=== added file '.bzrignore' --- .bzrignore 1970-01-01 00:00:00 +0000 +++ .bzrignore 2012-03-26 00:01:55 +0000 @@ -0,0 +1,5 @@ +targets +downloads +stages +build +Session.vim === added file 'atom_manip.pl' --- atom_manip.pl 1970-01-01 00:00:00 +0000 +++ atom_manip.pl 2012-05-17 22:58:49 +0000 @@ -0,0 +1,15 @@ +% vim: ft=prolog textwidth=80 tabstop=4 softtabstop=4 shiftwidth=4 expandtab + +:- module(atom_manip, [op(700, xfy, (=:)), (=:)/2]). + +=:(A, A) :- atom(A). + +=:(Variable, +(A, B)) :- + Aa =: A, + Ba =: B, + atomic_list_concat([Aa, Ba], '', Variable). + +=:(Variable, /(A, B)) :- + Aa =: A, + Ba =: B, + atomic_list_concat([Aa, Ba], '/', Variable). === added directory 'conf' === added file 'conf/chroot.sh-amd64' --- conf/chroot.sh-amd64 1970-01-01 00:00:00 +0000 +++ conf/chroot.sh-amd64 2012-03-20 13:21:43 +0000 @@ -0,0 +1,80 @@ +#!/bin/bash +SCRIPT=$(readlink -f $0) +DIR="`dirname "$SCRIPT"`" +EXE="${1:-$SHELL}" +PS4='+\t \s> ' + +cd "$DIR" + +declare -A NEW_ENV +NEW_ENV[HOST]="`basename $DIR`" +NEW_ENV[TERM]="${TERM%-256color}" +NEW_ENV[HOME]=/root/ +NEW_ENV[PATH]="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" + +do_chroot() { + local -a environ + for key in "${!NEW_ENV[@]}" + do + environ+=( "${key}=${NEW_ENV[$key]}" ) + done + env -i - "${environ[@]}" setarch x86_64 chroot . "$@" + RET=$? + echo "command $* returned $RET" +} + +UMOUNT="" + +trymount() { + for DST in "$@"; do true; done + if mount | grep -q "$DIR/$DST" + then + echo "$DST already mounted" + else + echo "mounting $DST" + mount "$@" + UMOUNT="$DST $UMOUNT" + fi +} + +#set -x + +trymount --bind {/,}dev +mkdir -v -p dev/{pts,shm} +trymount -t devpts devpts dev/pts +trymount -t tmpfs -o size=100M tmpfs dev/shm + +trymount -t proc none proc + +[[ -d usr/portage ]] && \ +trymount --bind {/,}usr/portage +[[ -d var/portage/distfiles ]] && \ +trymount --bind {/,}var/portage/distfiles +[[ -d var/portage/ccache ]] && \ +trymount --bind /var/prosys/ccache/amd64 var/portage/ccache + +[[ -f ./chroot_conf ]] && source ./chroot_conf + +#trymount -t tmpfs -o size=3G tmpfs var/tmp +#trymount -t tmpfs -o size=100M tmpfs tmp + +cp -v /etc/resolv.conf etc/ +cat proc/mounts >etc/mtab + + +#if [ -n "$DISPLAY" ] && [ -x ./usr/bin/xauth ] +#then +# echo "copying over X Authentication for $DISPLAY" +# xauth extract - $DISPLAY | do_chroot /bin/bash -x -c '/usr/bin/xauth merge -' +# NEW_ENV[DISPLAY]="127.0.0.1${DISPLAY}" +#fi + +do_chroot "$EXE" + +for M in $UMOUNT +do + echo "unmouting $M" + umount "$M" +done +set -x +exit $RET === added file 'conf/chroot.sh-x86' --- conf/chroot.sh-x86 1970-01-01 00:00:00 +0000 +++ conf/chroot.sh-x86 2012-03-20 13:21:43 +0000 @@ -0,0 +1,80 @@ +#!/bin/bash +SCRIPT=$(readlink -f $0) +DIR="`dirname "$SCRIPT"`" +EXE="${1:-$SHELL}" +PS4='+\t \s> ' + +cd "$DIR" + +declare -A NEW_ENV +NEW_ENV[HOST]="`basename $DIR`" +NEW_ENV[TERM]="${TERM%-256color}" +NEW_ENV[HOME]=/root/ +NEW_ENV[PATH]="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" + +do_chroot() { + local -a environ + for key in "${!NEW_ENV[@]}" + do + environ+=( "${key}=${NEW_ENV[$key]}" ) + done + env -i - "${environ[@]}" linux32 chroot . "$@" + RET=$? + echo "command $* returned $RET" +} + +UMOUNT="" + +trymount() { + for DST in "$@"; do true; done + if mount | grep -q "$DIR/$DST" + then + echo "$DST already mounted" + else + echo "mounting $DST" + mount "$@" + UMOUNT="$DST $UMOUNT" + fi +} + +#set -x + +trymount --bind {/,}dev +mkdir -v -p dev/{pts,shm} +trymount -t devpts devpts dev/pts +trymount -t tmpfs -o size=100M tmpfs dev/shm + +trymount -t proc none proc + +[[ -d usr/portage ]] && \ +trymount --bind {/,}usr/portage +[[ -d var/portage/distfiles ]] && \ +trymount --bind {/,}var/portage/distfiles +[[ -d var/portage/ccache ]] && \ +trymount --bind /var/prosys/ccache/amd64 var/portage/ccache + +[[ -f ./chroot_conf ]] && source ./chroot_conf + +#trymount -t tmpfs -o size=7G tmpfs var/tmp +#trymount -t tmpfs -o size=500M tmpfs tmp + +cp -v /etc/resolv.conf etc/ +cat proc/mounts >etc/mtab + + +#if [ -n "$DISPLAY" ] && [ -x ./usr/bin/xauth ] +#then +# echo "copying over X Authentication for $DISPLAY" +# xauth extract - $DISPLAY | do_chroot /bin/bash -x -c '/usr/bin/xauth merge -' +# NEW_ENV[DISPLAY]="127.0.0.1${DISPLAY}" +#fi + +do_chroot "$EXE" + +for M in $UMOUNT +do + echo "unmouting $M" + umount "$M" +done +set -x +exit $RET === added directory 'conf/gentoo_scripts' === added file 'conf/gentoo_scripts/build_stage4.sh' --- conf/gentoo_scripts/build_stage4.sh 1970-01-01 00:00:00 +0000 +++ conf/gentoo_scripts/build_stage4.sh 2011-11-25 17:27:50 +0000 @@ -0,0 +1,3 @@ +#!/bin/bash +PS4='+\t \s> ' +emerge -uDN --keep-going $( cat /root/prosys/world ) === added file 'conf/gentoo_scripts/build_stage5.sh' --- conf/gentoo_scripts/build_stage5.sh 1970-01-01 00:00:00 +0000 +++ conf/gentoo_scripts/build_stage5.sh 2012-03-01 22:00:47 +0000 @@ -0,0 +1,3 @@ +#!/bin/bash +PS4='+\t \s> ' +emerge ${KERNEL_SOURCES:-gentoo-sources} genkernel && genkernel all === added file 'conf/gentoo_scripts/rebuild_stage3.sh' --- conf/gentoo_scripts/rebuild_stage3.sh 1970-01-01 00:00:00 +0000 +++ conf/gentoo_scripts/rebuild_stage3.sh 2012-03-23 03:41:50 +0000 @@ -0,0 +1,36 @@ +#!/bin/bash +emerge() { + /usr/bin/emerge --quiet-build=y --verbose --keep-going $@ +} +CB=/etc/portage/package.use/circlebreak +CB_SRC=/root/prosys/circlebreak +finalize_circlebreak() { + if [[ -f "$CB" ]]; then + rm "$CB" && \ + emerge -uDN @world || \ + return 1 + fi + return 0 +} + +PS4='+\t \s> ' +set -x + +if [[ -f "$CB_SRC" ]]; then + cp "$CB_SRC" "$CB" +fi + +env-update && \ +source /etc/profile && \ +emerge portage ccache python:2.7 && \ +eselect python set python2.7 && \ +emerge -1 openrc udev && \ +emerge -u gcc && \ +gcc-config `gcc-config -l | awk '{p=$2} END{print p}'` && \ +source /etc/profile && \ +emerge -e @world && \ +finalize_circlebreak && \ +emerge -n gentoolkit && \ +/usr/bin/emerge --depclean && \ +emerge @preserved-rebuild && \ +revdep-rebuild -- -qv --keep-going === added file 'conf/gentoo_scripts/rebuild_stage3_uclibc.sh' --- conf/gentoo_scripts/rebuild_stage3_uclibc.sh 1970-01-01 00:00:00 +0000 +++ conf/gentoo_scripts/rebuild_stage3_uclibc.sh 2012-03-01 22:00:47 +0000 @@ -0,0 +1,17 @@ +#!/bin/bash +emerge() { + /usr/bin/emerge --quiet-build=y --verbose --keep-going $@ +} +PS4='+\t \s> ' +set -x +env-update && \ +source /etc/profile && \ +emerge portage uclibc && \ +/usr/portage/scripts/bootstrap.sh && \ +gcc-config `gcc-config -l | awk '{p=$2} END{print p}'` && \ +source /etc/profile && \ +emerge -e @world && \ +emerge -n gentoolkit && \ +/usr/bin/emerge --depclean && \ +emerge @preserved-rebuild && \ +revdep-rebuild -- -qv --keep-going === added file 'conf/gentoo_scripts/rm_py3k.sh' --- conf/gentoo_scripts/rm_py3k.sh 1970-01-01 00:00:00 +0000 +++ conf/gentoo_scripts/rm_py3k.sh 2012-03-01 22:00:47 +0000 @@ -0,0 +1,12 @@ +#!/bin/bash +PS4='+\t \s> ' +set -x +env-update && \ +source /etc/profile && \ +emerge portage ccache && \ +source /etc/profile && \ +emerge -1u '=python-2.7*' python-updater portage && \ +eselect python set python2.7 && \ +source /etc/profile && \ +emerge --unmerge '>=dev-lang/python-3' && \ +python-updater === added file 'conf/gentoo_scripts/update_stage3.sh' --- conf/gentoo_scripts/update_stage3.sh 1970-01-01 00:00:00 +0000 +++ conf/gentoo_scripts/update_stage3.sh 2012-03-01 22:00:47 +0000 @@ -0,0 +1,15 @@ +#!/bin/bash +emerge() { + /usr/bin/emerge --quiet-build=y --verbose --keep-going $@ +} +PS4='+\t \s> ' +set -x +env-update && \ +source /etc/profile && \ +emerge portage ccache && \ +source /etc/profile && \ +emerge -uDN @world && \ +emerge -n gentoolkit && \ +/usr/bin/emerge --depclean && \ +emerge @preserved-rebuild && \ +revdep-rebuild -- -qv --keep-going === added file 'conf/make.conf' --- conf/make.conf 1970-01-01 00:00:00 +0000 +++ conf/make.conf 2012-03-20 13:21:43 +0000 @@ -0,0 +1,22 @@ +EMERGE_DEFAULT_OPTS="--verbose --quiet --jobs 5" +MAKEOPTS="-j6 -l7" +LINGUAS="en cs" + +FEATURES="sandbox usersandbox userpriv userfetch -ccache config-protect-if-modified parallel-fetch parallel-install -preserve-libs unknown-features-warn -news buildpkg" + +GENTOO_MIRRORS=" + ftp://ftp.fi.muni.cz/pub/linux/gentoo/ + ftp://ftp.linux.cz/pub/linux/gentoo/ + http://ftp.sh.cvut.cz/gentoo +" + +PORT_LOGDIR="/var/log/portage" +PKGDIR="/var/portage/packages" +DISTDIR="/var/portage/distfiles" +CCACHE_DIR="/var/portage/ccache" +CCACHE_SIZE="10G" + +PORTAGE_ELOG_CLASSES="*" +PORTAGE_ELOG_SYSTEM="save_summary save echo" + +PORTDIR_OVERLAY="/var/portage/ccx-autobuild" === added directory 'conf/portage' === added file 'conf/portage/bashrc' --- conf/portage/bashrc 1970-01-01 00:00:00 +0000 +++ conf/portage/bashrc 2012-01-20 04:29:24 +0000 @@ -0,0 +1,1 @@ +export CCACHE_COMPILERCHECK=content === added file 'conf/portage/package.mask' --- conf/portage/package.mask 1970-01-01 00:00:00 +0000 +++ conf/portage/package.mask 2012-03-01 22:00:47 +0000 @@ -0,0 +1,2 @@ +#=sys-libs/zlib-1.2.6 +#>=sys-libs/zlib-1.2.5-r2 === added file 'dcg_stuff.pl' --- dcg_stuff.pl 1970-01-01 00:00:00 +0000 +++ dcg_stuff.pl 2012-06-03 13:59:12 +0000 @@ -0,0 +1,66 @@ +% vim: ft=prolog textwidth=80 tabstop=4 softtabstop=4 shiftwidth=4 expandtab + +:- module(dcg_stuff, [ + op(800,xfy,(#:)), (#:)/4, + op(800,xfy,(#+)), (#+)/4, + op(800,xfy,(#<<)), (#<<)/4, + op(800,xfy,(#=)), (#=)/4, + op(800,xfy,(#?)), (#?)/4, + phrase_assoc/2 + ]). + +:- use_module(library(assoc)). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Helpers for using assoc instead of list in DCG % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Call predicate with previous and new value of key as arguments +% key #: append([foo, bar]) +#:(Key,DCG_Goal,AssocIn,AssocOut) :- + get_assoc(Key,AssocIn,ValIn,AssocOut,ValOut), + phrase(DCG_Goal,ValIn,ValOut). + +% Appends to a d-list which is a value of a key +% key #+ [foo, bar] +#+(Key,List,AssocIn,AssocOut) :- + get_assoc(Key,AssocIn,ListIn-TailIn,AssocOut,ListOut-TailOut), + append(List, TailOut, TailIn), + ListIn = ListOut. + +#<<(Key,Item,AssocIn,AssocOut) :- + get_assoc(Key,AssocIn,ListIn-TailIn,AssocOut,ListOut-TailOut), + ListIn = ListOut, + TailIn = [Item|TailOut]. + +% Assign value to a key +% key #= Value +#=(Key,Value,AssocIn,AssocOut) :- + put_assoc(Key, AssocIn, Value, AssocOut). + +% Get a value of a key +% key #? Value +#?(Key,Value,Assoc,Assoc) :- + get_assoc(Key, Assoc, Value). + +% Alternative to phrase/2 using empty assoc instead of list +phrase_assoc(DCG_Goal, ValOut) :- + empty_assoc(Empty), + phrase(DCG_Goal, Empty, ValOut). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Maplist over DCG predicates % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +dcg_maplist(_Pred, [ ]) --> []. +dcg_maplist( Pred, [Arg|Rest]) --> + call(Pred, Arg), + dcg_maplist(Pred, Rest). + +% Like dcg_maplist but ignores unsatisfiable predicates +dcg_maplist_permissive(_Pred, [ ]) --> []. +dcg_maplist_permissive( Pred, [Arg|Rest]) --> + ( call(Pred, Arg) -> [] ; [] ), + dcg_maplist_permissive(Pred, Rest). + === added file 'escape.pl' --- escape.pl 1970-01-01 00:00:00 +0000 +++ escape.pl 2012-05-17 18:49:59 +0000 @@ -0,0 +1,107 @@ +% vim: ft=prolog textwidth=80 tabstop=4 softtabstop=4 shiftwidth=4 expandtab + +:- module(escape, [str/2, is_str/1, quoting/4, escape/3]). + +:- use_module(library(apply)). +:- use_module(library(lists)). + +:- use_module(generic). + + +% +% Strip characters from left or right side +% + +l_strip([ ], _ , [ ]). +l_strip([Head|Tail], Strip, Out) :- + ( member(Head, Strip) + -> l_strip(Tail, Strip, Out) + ; Out = [Head|Tail] + ). + +r_strip([ ], _ , []). +r_strip([Head|Tail], Strip, Out) :- + r_strip(Tail, Strip, Out0), + ( Out0 = [], + member(Head, Strip) + -> Out = [ ] + ; Out = [Head|Out0] + ). + + +% +% Merge tree into string list +% + +str_dlist(X, Joined, End) :- + ( is_list(X) -> ( maplist(integer, X) + -> append(X, End, Joined) + ; throw(not_a_proper_string(X)) + ) + ; atom(X) -> name(X, String), + append(String, End, Joined) + ; X = variable(Name) -> Joined = [variable(Name)|End] + ; X = A + B -> str_dlist(B, L, End), + str_dlist(A, Joined, L) + ; X = A +/+ B -> str(A, AString), + str(B, BString), + r_strip(AString, "/", AStripped), + l_strip(BString, "/", BStripped), + concat([AStripped, "/", BStripped, End], Joined) + ; throw(unable_to_convert_to_string(X)) + ). + +str(X, S) :- str_dlist(X, S, []). + +is_str(X) :- atom(X); X=variable(_); X=_+_; X=_+/+_; (is_list(X), maplist(integer, X)). + +%%%%%%%%%%%%%%%%%% +% Shell escaping % +%%%%%%%%%%%%%%%%%% + +% can escape anything but newline or variable +sh_escaped(Char, String) :- + integer(Char), + [Char] \= "\n", + ( member(Char, "\\ \t()[]{}&;$#!?*=<>'\"`") + -> ( [Bksl] = "\\", String = [Bksl, Char] ) + ; String = [Char] + ). + +% can escape anything single quote or variable +sh_single_quoted(Char, [Char]) :- + integer(Char), + [Char] \= "'". + +% can escape anything +sh_double_quoted(Char, String) :- + ( Char = variable(Name) + -> str(Name, NameStr), + concat(["${", NameStr, "}"], String) + ; member(Char, "$\\\"`") + -> ( [Bksl] = "\\", String = [Bksl, Char] ) + ; String = [Char] + ). + +quoting(sh, sh_escaped, "", ""). +quoting(sh, sh_single_quoted, "'", "'"). +quoting(sh, sh_double_quoted, "\"", "\""). + + +escape_whole(String, Name, Escaped) :- + maplist(Name, String, Parts), + concat(Parts, Joined), + quoting(_, Name, Pre, Post), + concat([Pre, Joined, Post], Escaped). + +escape_kv(String, Name, Length-Escaped) :- + escape_whole(String, Name, Escaped), + length(Escaped, Length). + +escape(Shell, In, Out) :- + str(In, String), + findall(Escaped, (quoting(Shell, Name, _, _), + escape_kv(String, Name, Escaped) + ), KV), + keysort(KV, Sorted), + Sorted = [_ - Out|_]. === added file 'generate_targets' --- generate_targets 1970-01-01 00:00:00 +0000 +++ generate_targets 2012-06-03 13:59:12 +0000 @@ -0,0 +1,8 @@ +#!/bin/zsh +set -x +mkdir -p ${0:h}/targets +for target in $( ${0:h}/stagebuilder.pl ) +do + ${0:h}/stagebuilder.pl $target >${0:h}/targets/${target} + chmod +x ${0:h}/targets/${target} +done === added file 'generic.pl' --- generic.pl 1970-01-01 00:00:00 +0000 +++ generic.pl 2011-11-26 16:18:19 +0000 @@ -0,0 +1,35 @@ +% vim: ft=prolog textwidth=80 tabstop=4 softtabstop=4 shiftwidth=4 expandtab + +:- module(generic, [op(400, yfx, +/+) ,join/3, prepend/3, str_join/3, concat/2]). + +% operator definition +%:- op(400, yfx, +/+). + +% +% String tree manipulation +% + +join(_ , [ ], [ ]). +join(_ , [X ], X ). +join(Sep, [A, B|Rest], A + Sep + Result) :- + join(Sep, [B|Rest], Result). +% +% list manipulation +% + +prepend(List, List0, List1) :- append(List, List1, List0). + +str_join(_ , [ ], [ ]). +str_join(_ , [X ], X ). +str_join(Sep, [A, B|Rest], Result) :- + concat([A, Sep, B], Start), + str_join(Sep, [Start|Rest], Result). + +concat([ ],[ ]). +concat([Head|Tail],List) :- concat_cons(Head,Tail,List). +concat_cons(Head ,[ ],Head). +concat_cons(Head0,[Head1|Tail],List) :- + append(Head0,Rest,List), + concat_cons(Head1,Tail,Rest). + + === renamed directory '' => 'overlay' === added directory 'scripts' === added file 'scripts/build_gentoo_stage4' --- scripts/build_gentoo_stage4 1970-01-01 00:00:00 +0000 +++ scripts/build_gentoo_stage4 2012-01-18 17:27:32 +0000 @@ -0,0 +1,18 @@ +#!/bin/zsh +source ${0:h}/functions + +[[ -d $1 ]] || die usage: ${0:t} '' +set -x + +summary=$1/var/log/portage/elog/summary.log +last=$( stat -c %Y $summary ) +until $1/chroot.sh /root/prosys/build_stage4.sh +do + new=$( stat -c %Y $summary ) + if [[ $last == $new ]] + then + die "emerge failed without errors, assuming unsatisfiable conditions" + fi + last=$new + ${0:h}/mask_failed_packages $1 +done === added file 'scripts/digest_download' --- scripts/digest_download 1970-01-01 00:00:00 +0000 +++ scripts/digest_download 2011-11-09 14:33:14 +0000 @@ -0,0 +1,27 @@ +#!/bin/zsh +# vim: noet ts=4 sts=4 +# TODO: write this script properly :] +# it should accept directory to download to / check for existing files + +die() { + echo DIE: $@ + exit 1 +} +CHECKSUM_URI=$1 + +wget -N $CHECKSUM_URI || die "downloading stage3 checksum failed" + +CHECK=`basename $CHECKSUM_URI` +gpg --verify $CHECK || die "Verifying the checksums PGP signature failed" +STAGE=${CHECK%.DIGESTS.asc} +# quick hack to check we don't have wrong .asc, might break in future +sums=(`egrep '^[a-fA-F0-9]{40} ' $CHECK`) +[[ $sums[2] == $STAGE ]] || die "something is wrong with checksum file" +if [ ! -f $STAGE ] +then + wget -nc `dirname $CHECKSUM_URI`/$STAGE'*' || die "download failed" +fi + +sha1sum -c $CHECK 1>&2 || die "sha1sum failed" +echo $STAGE + === added file 'scripts/digest_to_metalink.awk' --- scripts/digest_to_metalink.awk 1970-01-01 00:00:00 +0000 +++ scripts/digest_to_metalink.awk 2011-11-11 21:50:27 +0000 @@ -0,0 +1,47 @@ +#!/usr/bin/gawk -F ' ' -f + +BEGIN{ + split(urls, url_array, " "); + for(i in url_array){ + split(url_array[i], url_components, ":"); + url_type[i] = url_components[1]; + } + IFS=" "; +} + +/^[a-fA-F0-9]{32} \S+/{ + files[$2] = 1; + md5[$2] = $1; +} + +/^[a-fA-F0-9]{40} \S+/{ + files[$2] = 1; + sha1[$2] = $1; +} + +END{ + print ""; + print ""; + print ""; + for(file in files){ + print ""; + print " "; + if(file in md5){ + print " " md5[file] "" + } + if(file in sha1){ + print " " sha1[file] "" + } + print " "; + print " "; + for (i in url_array) { + url = url_array[i]; + type = url_type[i]; + print " " url "/" file "" + } + print " "; + print ""; + } + print ""; + print ""; +} === added file 'scripts/download_stage' --- scripts/download_stage 1970-01-01 00:00:00 +0000 +++ scripts/download_stage 2011-11-29 09:07:57 +0000 @@ -0,0 +1,28 @@ +#!/bin/zsh +# vim: noet ts=4 sts=4 +PS4='+%B%* %F{cyan}%N%f:%F{yellow}%i%f>%b ' +set -x + +destdir=${2:-.} + +digest_uri=${1}.DIGESTS.asc +#digest_uri=$( ${0:h}/resolve_txt_uri $1 ).DIGESTS.asc || exit $? + +digest=$( wget -q -O - $digest_uri ) || exit $? +gpg --verify --batch <<<$digest || exit $? +digest=$( sed -n '/^-----BEGIN PGP SIGNED MESSAGE-----$/,/^-----BEGIN PGP SIGNATURE-----$/p' <<<$digest ) || exit $? +files=( $( gawk <<<$digest -f ${0:h}/list_digest_files.awk | grep -Ee '\.tar(\.(gz|bz2|lzma|xz))?$' ) ) +if [[ $#files != 1 ]] +then + echo "got $#files tarballs, one expected" + exit 1 +fi +metalink=$( gawk -v urls=${digest_uri:h} -f ${0:h}/digest_to_metalink.awk <<<$digest ) || exit $? + +aria2c --check-integrity=true \ + --dir=$destdir \ + -l /dev/stderr \ + --quiet=true \ + --log-level=notice \ + -M - <<<$metalink || exit $? +echo ${destdir}/${files} === added file 'scripts/elog2html.py' --- scripts/elog2html.py 1970-01-01 00:00:00 +0000 +++ scripts/elog2html.py 2011-11-29 09:07:57 +0000 @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# vim: tw=75 sts=4 ts=4 noet fileencoding=utf-8 +import re +from collections import namedtuple +import warnings + +RE_PKG = r"^>>> Messages generated by process \d+ on (.*) for package (.*):" +RE_MSG = r"^(ERROR|WARN|LOG): ([a-z]*)$" + +Pkg = namedtuple('Pkg', 'time package messages') +Msg = namedtuple('Msg', 'level phase lines') + +def read_elog(f): + pkg = None + pkgs = [] + ignored = 0 + for line in f: + m = RE_PKG.match(line) + if m: + pkg = Pkg(m.groups() + [[]]) + pkgs.append(pkg) + continue + elif m is None: + ignored += 1 + m = RE_MSG.match(line) + if m: + pkg.messages.append(Msg(m.groups() + [[]])) + else: + pkg.messages[-1].lines(line) + if ignored: + warnings.warn( + 'ignored %d lines not belonging to any package'%ignored + ) + return pkgs === added file 'scripts/elogread.py' --- scripts/elogread.py 1970-01-01 00:00:00 +0000 +++ scripts/elogread.py 2012-03-20 13:21:43 +0000 @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# vim: tw=75 sts=4 ts=4 noet fileencoding=utf-8 +import re +import argparse +from collections import namedtuple, deque +from pprint import pprint + +RE_PACKAGE = re.compile( + r"^>>> Messages generated by process (\d+) on (.+) for package ([^:]+):" + ) +Package = namedtuple('Package', 'pid date package messages') + +RE_MESSAGE = re.compile(r"^(INFO|LOG|WARN|ERROR): ([a-z]+)$") +Message = namedtuple('Message', 'cls phase lines') + +class ElogSummaryParser(object): + def __init__(self, f=None): + self.packages = deque() + if f is not None: + self.parse_file(f) + + def parse_line(self, line): + m = RE_PACKAGE.match(line) + if m: + self.packages.append(Package(*( + m.groups() + (deque(),) + ))) + return + + m = RE_MESSAGE.match(line) + if m: + self.packages[-1].messages.append(Message(*( + m.groups() + (deque(),) + ))) + return + + if not self.packages[-1].messages and not line.strip(): + return + + self.packages[-1].messages[-1].lines.append(line) + + def parse_file(self, f): + if not hasattr(f, 'read'): + f = open(f) + for line in f: + self.parse_line(line.rstrip('\n')) + +parser = argparse.ArgumentParser() +parser.add_argument('--ignore-other', action='store_true', + help="Ignore errors in phase 'other' which seems to mean unmet" + " dependendencies") +parser.add_argument('action', choices=[ + 'dump', 'errors' + ]) +parser.add_argument('logfile', type=argparse.FileType('r'), + help='summary.log file') + +def main(): + args = parser.parse_args() + packages = ElogSummaryParser(args.logfile).packages + if args.action == 'errors': + for pkg in packages: + if any(( + True for msg in pkg.messages + if msg.cls == 'ERROR' and ( + not args.ignore_other or msg.phase != 'other' + ) + )): + print pkg.package + elif args.action == 'dump': + for pkg in packages: + pprint(pkg) + else: + print "unknown action %r"%args.action + +if __name__ == '__main__': + main() === added file 'scripts/functions' --- scripts/functions 1970-01-01 00:00:00 +0000 +++ scripts/functions 2012-05-17 22:58:49 +0000 @@ -0,0 +1,19 @@ +# vim: noet ts=4 sts=4 ft=zsh +PS4='+%B%* %F{cyan}%N%f:%F{yellow}%i%f>%b ' +die() { + echo DIE: "$@" + exit 1 +} + +die_usage() { + echo ERROR: "$@" + echo usage: ${0:t} $USAGE + exit 2 +} + +PROSYS_BASE=${PROSYS_BASE:-${${0:h}:h}} +PROSYS_CONF=${PROSYS_CONF:-${PROSYS_BASE}/conf} +PROSYS_BUILD=${PROSYS_BUILD:-${PROSYS_BASE}/build} +PROSYS_STAGES=${PROSYS_BUILD:-${PROSYS_STAGES}/stages} +PROSYS_TARGETS=${PROSYS_TARGETS:-${PROSYS_BASE}/targets} +PROSYS_DOWNLOADS=${PROSYS_DOWNLOADS:-${PROSYS_BASE}/downloads} === added file 'scripts/generate_metalink.py' --- scripts/generate_metalink.py 1970-01-01 00:00:00 +0000 +++ scripts/generate_metalink.py 2012-03-01 22:00:47 +0000 @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# vim: tw=75 sts=4 ts=4 noet fileencoding=utf-8 +import sys +import string +import os.path +import hashlib + +hashnames = ['md5', 'sha1', 'sha256'] +block = 1024 + +metalink_template = string.Template( +""" + + + + $SIZE + $HASHES + + $URI + + + +""") + +def main(filename, uri): + f = open(filename, 'rb') + hashes = [ hashlib.new(name) for name in hashnames ] + #size = 0 + + data = f.read(block) + while data: + #size += len(data) + for h in hashes: h.update(data) + data = f.read(block) + + size = f.tell() + f.close() + + print metalink_template.substitute( + URI = uri, + FILENAME = os.path.basename(filename), + SIZE = size, + HASHES = ''.join( + '%s'%(name, h.hexdigest()) + for name, h + in zip(hashnames, hashes) + ) + ) + + +if __name__ == '__main__': + if len(sys.argv) != 3: + print "usage: %s "%os.path.basename(sys.argv[0]) + sys.exit(1) + else: + main(*sys.argv[1:]) + === added file 'scripts/get_gentoo_stage' --- scripts/get_gentoo_stage 1970-01-01 00:00:00 +0000 +++ scripts/get_gentoo_stage 2012-05-17 22:58:49 +0000 @@ -0,0 +1,26 @@ +#!/bin/zsh +# vim: noet ts=4 sts=4 +source ${0:h}/functions +USAGE="target_basename download_dir txt_uri" +[[ ${#@} != 3 ]] && die_usage +set -x + +target_basename=$1 +download_dir=$2 +txt_uri=$3 + +mkdir -p $download_dir || die +digest_uri=$( ${0:h}/resolve_txt_uri $txt_uri ) || die +downloaded=$( ${0:h}/download_stage $digest_uri $download_dir ) || exit $? +builddate=$( sed 's/.*-\([0-9]*\)\.tar.*/\1' <<<$downloaded ) +dst_dir=${target_basename}-${builddate} +echo $dst_dir +if [[ -d $dst_dir ]]; then + # already unpacked & prepared + [[ -f $dst_dir/root/prosys/stages_completed ]] && exit 0 +fi +mkdir -p $dst_dir/{root/prosys,usr/portage,var/portage/packages} || die +tar -xpf $downloaded -C $dst_dir || die +rsync -a --delete $PROSYS_BASE/overlay/ $dst_dir/var/portage/ccx-autobuild/ || die +rsync -a --delete $PROSYS_CONF/gentoo_scripts/ $dst_dir/root/prosys/ || die +rsync -a --delete $PROSYS_CONF/portage/ $dst_dir/etc/portage/ || die === added file 'scripts/http_glob' --- scripts/http_glob 1970-01-01 00:00:00 +0000 +++ scripts/http_glob 2011-11-09 14:33:14 +0000 @@ -0,0 +1,8 @@ +#!/bin/zsh +# vim: noet ts=4 sts=4 +files=( $(wget -qO - ${1:h}/ | sed -n '/' +set -x +mask=$1/etc/portage/package.mask +[[ -d $mask ]] && mask=$mask/failed +pkg_list="$( ${0:h}/elogread.py --ignore-other errors $1/var/log/portage/elog/summary.log | sort -u )" +pkg_arr=( ${(f)pkg_list} ) +for pkg in $pkg_arr ; do + if ! [[ -d $1/var/db/pkg/$pkg ]] + then + atom="=$pkg" + grep -qFwe $atom $mask || echo $atom >> $mask + fi +done === added file 'scripts/portage_timestamp' --- scripts/portage_timestamp 1970-01-01 00:00:00 +0000 +++ scripts/portage_timestamp 2011-11-25 02:11:32 +0000 @@ -0,0 +1,3 @@ +#!/bin/zsh +timestamp_arr=( $(<$1/metadata/timestamp.x) ) || exit 1 +date -d @${timestamp_arr[1]} '+%Y%m%d' === added file 'scripts/resolve_txt_uri' --- scripts/resolve_txt_uri 1970-01-01 00:00:00 +0000 +++ scripts/resolve_txt_uri 2011-11-11 17:01:11 +0000 @@ -0,0 +1,6 @@ +#!/bin/zsh +# vim: noet ts=4 sts=4 +relative=$(wget -qO - $1 | grep -v '^#') +(( ${pipestatus[1]} )) && exit 1 +[[ -z "$relative" ]] && exit 1 +echo "${1:h}/$relative" === added file 'scripts/snapshot_stage' --- scripts/snapshot_stage 1970-01-01 00:00:00 +0000 +++ scripts/snapshot_stage 2012-05-17 22:58:49 +0000 @@ -0,0 +1,20 @@ +#!/bin/zsh +# vim: noet ts=4 sts=4 + +die() { + echo DIE: $@ + exit 1 +} + +SNAPSHOT_STYLE=${SNAPSHOT_STYLE:-btrfs} + +[[ -d $1 ]] || die "Source directory $1 does not exist" +[[ -e $2 ]] && { + dst=( $2(N/^F) ) + ((${#dst})) || die "Destination directory $2 exists and it is not empty" +} +[[ $SNAPSHOT_STYLE == 'btrfs' ]] || die 'only btrfs SNAPSHOT_STYLE supported currently' + +set -x +btrfs snapshot $1 $2 +exit $? === added file 'scripts/tar_checksum' --- scripts/tar_checksum 1970-01-01 00:00:00 +0000 +++ scripts/tar_checksum 2012-03-01 22:00:47 +0000 @@ -0,0 +1,35 @@ +#!/bin/zsh + +# usage: $0 filename other_tar_options + +FILE=$1 +shift +CHECK=${FILE}.DIGESTS +METALINK=${FILE}.metalink + +umask 022 + +die() { + echo ERROR: $* + exit 1 +} +run() { + "$@" <&- || die "$@" +} + +set -x + +tar -cf $FILE "$@" || die tar +${0:h}/generate_metalink.py $FILE http://webprojekty.cz/stages/${FILE:t} >$METALINK || die metalink generation failed +( + cd ${FILE:h} + md5sum ${FILE:t} + sha1sum ${FILE:t} + sha512sum ${FILE:t} +) >"${CHECK}" || die "failed to generate checksums" + +/usr/bin/gpg --batch --clearsign <"${CHECK}" >"${CHECK}.signed" || die "gpg clearsign of $CHECK failed" +run mv "${CHECK}.signed" "${CHECK}" +[[ -f ${METALINK}.sig ]] && rm ${METALINK}.sig +run /usr/bin/gpg --batch --detach-sign "${METALINK}" + === added file 'shell.pl' --- shell.pl 1970-01-01 00:00:00 +0000 +++ shell.pl 2012-05-21 07:02:28 +0000 @@ -0,0 +1,179 @@ +% vim: ft=prolog textwidth=80 tabstop=4 softtabstop=4 shiftwidth=4 expandtab + +%%%%%%%%%%%%%%%%%%%%%%%%% +% Shell code generation % +%%%%%%%%%%%%%%%%%%%%%%%%% + +:- module(shell, [ + op(600,xfy,($:-)), +% op(800,fx,(#)), + cmd_format/2, + cmd_print/1, + cmds_print/1, + cmd_repr/1, + cmds_repr/1 + ]). + +:- use_module(library(apply)). + +:- use_module(generic). +:- use_module(escape). + +% check for (incomplete) list containing character codes +assert_string(""). +assert_string(Var) :- var(Var). +assert_string([Code|Rest]) :- + integer(Code), + assert_string(Rest). + +assert_dcg_string(List, List) :- + assertion(assert_string(List)). + +escape(In, Out) :- escape(sh, In, Out). + +escape_dcg(In) --> + assert_dcg_string, + { escape(In, Out) }, + assert_dcg_string, + prepend(Out). + +escape_dcglist(List) --> + dcg_maplist(escape_dcg, List). + +str_dcg(In) --> + { str(In, Out) }, + prepend(Out). + +runnable([_|_]). +runnable(echo(_)). +runnable(chroot(_,_)). + +cmd_escape_runnable([Arg]) --> + assert_dcg_string, + escape_dcg(Arg). +cmd_escape_runnable([Arg1,Arg2|Rest]) --> + assert_dcg_string, + escape_dcg(Arg1), + prepend(" "), + cmd_escape_runnable([Arg2|Rest]). + +cmd_escape_runnable(echo(String)) --> + cmd_escape_runnable([echo, String]). + +cmd_escape_runnable(chroot(Dir, Args)) --> + cmd_escape_runnable([Dir +/+ 'chroot.sh'|Args]). + +cmd_escape_backticks(Runnable) --> + { runnable(Runnable) }, + prepend("$( "), + cmd_escape_runnable(Runnable), + prepend(" )"). + +check_returncode --> + assert_dcg_string, + prepend(" || exit $?\n"). + +cmd_tokens(verbatim(Verbatim)) --> + assert_dcg_string, + str_dcg(Verbatim). + +cmd_tokens(Runnable) --> + assert_dcg_string, + cmd_escape_runnable(Runnable), + check_returncode. + +cmd_tokens(Runnable >> File) --> + assert_dcg_string, + cmd_escape_runnable(Runnable), + prepend(" >>"), + escape_dcg(File), + check_returncode. + +cmd_tokens(Runnable > File) --> + assert_dcg_string, + cmd_escape_runnable(Runnable), + prepend(" >"), + escape_dcg(File), + check_returncode. + +cmd_tokens(Variable = Value) --> + assert_dcg_string, + str_dcg(Variable), + prepend("="), + ( { runnable(Value) } + -> prepend("\""), + cmd_escape_backticks(Value), + prepend("\"") + ; { is_str(Value) } + -> escape_dcg(Value) + ; { Value = Source $:- Default } + -> prepend("\"${"), + str_dcg(Source), + prepend(":-"), + ( { runnable(Default) } + -> cmd_escape_backticks(Default) + ; { is_str(Value) } + -> escape_dcg(Default) + ; throw(incomprehensible_default(Default)) + ), + prepend("}\"") + ; throw(incomprehensible_rhs(Value)) + ), + check_returncode. + +cmd_tokens(Variable = array(Runnable)) --> + assert_dcg_string, + str_dcg(Variable), + prepend("=( $("), + cmd_escape_runnable(Runnable), + prepend(") )"), + check_returncode. + +cmd_tokens(comment(Text)) --> + assert_dcg_string, + prepend("\n# "), + { str(Text, String) }, + make_comment(String), + prepend("\n"). + +cmd_tokens(run(List)) --> cmd_tokens(List). +cmd_tokens(run_append(List, File)) --> cmd_tokens(List >> File). +cmd_tokens(run_replace(List, File)) --> cmd_tokens(List > File). +cmd_tokens(run_outvar(List, Var)) --> cmd_tokens(Var = List). +cmd_tokens(run_outarray(List, Var)) --> cmd_tokens(Var = array(List)). +cmd_tokens(echo_append(String, File)) --> cmd_tokens(echo(String) >> File). +cmd_tokens(echo_replace(String, File)) --> cmd_tokens(echo(String) > File). +% cmd_tokens(comment(Text)) --> cmd_tokens(# Text). + +make_comment([ ]) --> []. +make_comment([Char|Rest]) :- + ( { [Char] = "\n" } + -> prepend("\n# ") + ; prepend(Char) + ), + make_comment(Rest). + +cmd_format(Cmd, String) :- phrase(cmd_tokens(Cmd), String, []). + +cmd_print(Cmd) :- + cmd_format(Cmd, String), !, + name(Name, String), + write(Name). + +cmds_print(Commands) :- + maplist(cmd_print, Commands). + +print_solution(String) :- + name(Text, String), + write(Text), + nl. + +cmd_repr(Command) :- + write('representation of: '), writeq(Command), write(' ::'), nl, + ( setof(String, cmd_format(Command, String), Solutions) + -> maplist(print_solution, Solutions) + ; write('FAILED!'), nl, trace, cmd_format(Command, _) + ). + +cmds_repr(Commands) :- + maplist(cmd_repr, Commands). === added file 'stagebuilder.pl' --- stagebuilder.pl 1970-01-01 00:00:00 +0000 +++ stagebuilder.pl 2013-05-15 07:01:22 +0000 @@ -0,0 +1,835 @@ +#!/usr/bin/swipl -q -g main -s +% vim: ft=prolog textwidth=80 tabstop=4 softtabstop=4 shiftwidth=4 expandtab + +:- use_module(library(lists)). +:- use_module(library(ordsets)). +:- use_module(library(assoc)). +:- use_module(library(apply)). +%:- use_module(library(pairs)). +%:- use_module(library(error)). + +:- use_module(generic). +:- use_module(escape). +:- use_module(shell). +:- use_module(dcg_stuff). +:- use_module(atom_manip). + + +%%%%%%%%%%%% +% Settings % +%%%%%%%%%%%% + +gentoo_mirror('ftp://ftp.linux.cz/pub/linux/gentoo/'). +stages_set_timezone('Europe/Prague'). +stages_set_locale('en_US.UTF-8'). + +work_dir('/var/prosys'). +site_conf_dir(Work +/+ conf ) :- work_dir(Work). +downloads_dir(Work +/+ downloads) :- work_dir(Work). + stages_dir(Work +/+ stages ) :- work_dir(Work). + script_dir(Work +/+ scripts ) :- work_dir(Work). + package_dir(Work +/+ packages ) :- work_dir(Work). + build_dir(Work +/+ build ) :- work_dir(Work). + targets_dir(Work +/+ targets ) :- work_dir(Work). + +%%%%%%%%%%%%%%%%%%%%%% +% Gentoo stuff below % +%%%%%%%%%%%%%%%%%%%%%% + +site_conf_file(Name, Dir +/+ Name) :- site_conf_dir(Dir). + +unpack_stage_tarball(Tarball) --> + builddir #? Dir, + commands #+ [ [tar, '-xpf', Tarball, '-C', Dir] ]. + +create_stage_tarball(Tarball, AddOpts) --> + builddir #? Dir, + { script_dir(ScriptDir), + append(AddOpts, ['-pC', Dir, '.'], Opts) + }, + commands #+ [ run([ScriptDir +/+ tar_checksum, Tarball | Opts]) ]. + +create_stage(Name) --> + { stages_dir(Stages) }, + create_tarball(Stages +/+ Name + '.tar.bz2', ['--use-compress-prog=pbzip2']). + +%http_glob(variable(uri), Uri) --> +% {script_dir(ScriptDir)}, +% [run_outvar([ScriptDir +/+ http_glob, Uri], uri)]. +% +%digest_download(variable(downloaded), Uri) --> +% {script_dir(ScriptDir)}, +% [run_outvar([ScriptDir +/+ digest_download, Uri], downloaded)]. + +%download_gentoo_stage(File, Mirror, Arch, Subarch, Subdir) --> +% http_glob(Uri +% ,Mirror + '/releases/' + Arch + '/current-stage3/' +% + Subdir +'stage3-' + Subarch + '-*.DIGESTS.asc' +% ), +% digest_download(File, Uri). + +gentoo_stage(i486, x86, 'latest-stage3-i486.txt'). +gentoo_stage(i686, x86, 'latest-stage3-i686.txt'). +gentoo_stage(i686_hardened, x86, 'latest-stage3-i686-hardened.txt'). +gentoo_stage(amd64, amd64, 'latest-stage3-amd64.txt'). +gentoo_stage(amd64_hardened, amd64, 'latest-stage3-amd64-hardened.txt'). +gentoo_stage(amd64_hardened_nomulti, amd64, 'latest-stage3-amd64-hardened+nomultilib.txt'). + +download_gentoo_stage(variable(downloaded), Name) --> + { gentoo_stage(Name, Arch, Txt), + gentoo_mirror(Mirror), + script_dir(ScriptDir), + downloads_dir(DownloadsDir) + }, + commands #+ [ + comment('download gentoo stage: ' + Name), + run([mkdir, '-p', DownloadsDir +/+ Name]), + run_outvar([ScriptDir +/+ resolve_txt_uri, + Mirror +/+ releases +/+ Arch +/+ autobuilds +/+ Txt + ], digest_uri), + run_outvar([ScriptDir +/+ download_stage, + variable(digest_uri), + DownloadsDir +/+ Name + ], downloaded) + ]. + +% +% Gentoo Packages +% + +gentoo_package(portage22, [ + package_keywords('=dev-lang/python-3') + %package_mask('net-zope/zope-fixers') + ]). +gentoo_package(mc, [ + package_use('app-misc/mc slang -ncurses'), + package_world('app-misc/mc') + ]). +gentoo_package(portage_utilities, [ + package_world('ccx-meta/portage-utilities') + ]). +gentoo_package(wifi, [ + package_world('net-wireless/wireless-tools'), + package_world('net-wireless/wpa_supplicant') + ]). +gentoo_package(vs_backup, [ + package_world('app-backup/rsnapshot'), + package_world('sys-fs/squashfs-tools') + ], [ + gzip, lzma, lzo, xattr + ]). + +gentoo_package(bindist, [], [bindist]). +gentoo_package(latex, [ + package_world('app-text/texlive'), + package_world('dev-tex/latex-beamer'), + package_world('dev-python/docutils'), + package_world('dev-tex/rubber'), + package_use('app-text/texlive X doc dvi2tty dvipdfm extra graphics png pstricks tex4ht truetype xml') + ], [ + kpathsea + ]). +gentoo_package(development_utilities, [ + package_world('ccx-meta/development-utilities') + ], [ + sqlite, sqlite3 + ]). +gentoo_package(vim, [ + package_world('app-editors/vim') + ], [ + 'vim', 'vim-pager', 'vim-syntax' + ]). +gentoo_package(zsh, [ + package_world('app-shells/zsh'), + package_world('app-shells/zsh-completion') + ], [ + 'zsh-completion' + ]). +gentoo_package(base_utilities, [ + package_use('app-editors/vim python vim-pager'), + package_world('ccx-meta/base-utilities') + ], [ + 'zsh-completion', unicode, vim, 'vim-syntax' + ]). +gentoo_package(base_system, [ + package_world('ccx-meta/base-system'), + package_use('dev-lang/tk threads') % needed for ruby stuff, whatever pulls it in + ], [ + caps, xattrs, acl, sqlite, sqlite3 + ]). +gentoo_package(base_network, [ + package_world('ccx-meta/base-network') + ], [ + ipv6 + ]). +gentoo_package(base_x11, [ + package_world('ccx-meta/base-x11'), + package_use('dev-libs/libxml2 python'), + package_use('x11-libs/libdrm libkms'), + circlebreak_use('net-print/cups -filters'), % break circular dependency with foomatic + circlebreak_use('dev-lang/python -tk') % break circular dependency with dev-tcltk/blt and xcb + ], [ + '256-color', 'X', apng, cairo, exif, gif, gstreamer, gtk, imlib, jpeg, fontconfig, + opengl, png, sdl, 'sdl-image', tcl, tk, tiff, truetype, webkit, xcb, xft, xpm, g3dvl + ]). +gentoo_package(filesystem_utilities, [ + package_world('ccx-meta/filesystem-utilities') + ], [ + 'device-mapper', xfs + ]). +gentoo_package(network_utilities, [ + package_world('ccx-meta/network-utilities'), + package_use('net-analyzer/tcpdump -samba') + ], [ + ssl,ipv6 + ]). +gentoo_package(picker_deps, [ + package_world('media-gfx/graphviz'), + package_world('dev-python/twisted'), + package_world('dev-python/twisted-web'), + package_world('dev-python/twisted-mail'), + package_world('dev-python/twisted-conch'), + package_world('dev-python/sqlalchemy'), + package_world('dev-python/docutils'), + package_world('dev-python/pyyaml') + ], [ + fontconfig, jpeg, png, postgres, serial, truetype, xml + ]). +gentoo_package(amd64_optimize, [], [ + mmx, sse, sse2, sse3, ssse3 + ]). +gentoo_package(net_clients, [ + package_world('ccx-meta/net-clients'), + package_use('net-libs/curl -threads -nss') + ], [ + ares, curl, gnutls, qt3support, minizip + ]). + +gentoo_package(Name, Echos, []) :- gentoo_package(Name, Echos). + +gentoo_package(geode_optimize, [], [ + mmx, mmxext + ], [ + sse, sse2, sse3, ssse3 + ]). +gentoo_package(nokit, [ + package_mask('sys-auth/polkit'), + package_mask('sys-auth/consolekit') + ], [], [ + policykit, consolekit, udisks, gdu + ]). +gentoo_package(base_media, [ + package_world('ccx-meta/base-media') + ], [ + aac, alsa, asf, audiofile, avcodec, dv, dvd, encode, ffmpeg, flac, + gstreamer, mng, modplug, mp3, mpeg, ogg, sid, sox, speex, theora, + transcode, vorbis, x264, xanim, xine, xvid, xvmc + ], [ + pulseaudio + ]). +gentoo_package(vserver, [ + package_world('sys-cluster/vserver-init'), + package_mask('sys-fs/udev') + ], [ + vserver + ], [ + udev + ]). + +gentoo_package(Name, Echos, UseEnabled, []) :- + gentoo_package(Name, Echos, UseEnabled). + +package_list(common, [ + portage22, bindist + ]). + +package_list(desktop, [ + vim, mc, nokit, + portage_utilities, + base_utilities, base_system, base_network, + network_utilities, filesystem_utilities, + base_x11, base_media, net_clients + ]). +package_list(laptop, [ + package_list(desktop), wifi + ]). + +% USE handling + +use_check_atom(Use) :- + ( atom(Use) + -> true + ; throw(use_is_not_simple_atom(Use)) + ). + +gentoo_package_use(Name, UseEnabledSet, UseDisabledSet) :- + gentoo_package(Name,_Echos, UseEnabledList, UseDisabledList), + maplist(use_check_atom, UseEnabledList), + maplist(use_check_atom, UseDisabledList), + list_to_ord_set(UseEnabledList, UseEnabledSet), + list_to_ord_set(UseDisabledList, UseDisabledSet). + +aggregate_package_use([ ], [ ], [ ]). +aggregate_package_use([PkgName|PkgNames], UseEnabled, UseDisabled) :- + gentoo_package_use(PkgName, PkgUseEnabled, PkgUseDisabled), + aggregate_package_use(PkgNames, AggUseEnabled, AggUseDisabled), + ord_union(PkgUseEnabled, AggUseEnabled, UseEnabled), + ord_union(PkgUseDisabled, AggUseDisabled, UseDisabled). +aggregate_package_use([package_list(PkgListName)|PkgNames], UseEnabled, UseDisabled) :- + package_list(PkgListName, Packages), + aggregate_package_use(Packages, PkgUseEnabled, PkgUseDisabled), + aggregate_package_use(PkgNames, AggUseEnabled, AggUseDisabled), + ord_union(PkgUseEnabled, AggUseEnabled, UseEnabled), + ord_union(PkgUseDisabled, AggUseDisabled, UseDisabled). + +disabled_use(Use, +('-', Use)). + +format_package_use(Packages, JoinedUse) :- + aggregate_package_use(Packages, UseEnabled, UseDisabled), + ord_intersection(UseEnabled, UseDisabled, Intersection), + ( ord_empty(Intersection) -> true + ; throw(conflicting_use(Intersection)) + ), + maplist(disabled_use, UseDisabled, UseDisabledMinus), + append(UseEnabled, UseDisabledMinus, MergedUse), + join(' ', MergedUse, JoinedUse). + +% package settings handling + +echo_package(package_mask(String), + echo_append(String, '/etc/portage/package.mask') + ). +echo_package(package_unmask(String), + echo_append(String, '/etc/portage/package.unmask') + ). +echo_package(package_use(String), + echo_append(String, '/etc/portage/package.use/prosys') + ). +echo_package(package_keywords(String), + echo_append(String, '/etc/portage/package.keywords') + ). +echo_package(package_world(String), + echo_append(String, '/root/prosys/world') + ). +echo_package(circlebreak_use(String), + echo_append(String, '/root/prosys/circlebreak') + ). + +extract_package_echo([ ], [ ]). +extract_package_echo([Pkg|Rest], List) :- + gentoo_package(Pkg, Echos, _, _), + append(Echos, Tail, List), + extract_package_echo(Rest, Tail). +extract_package_echo([package_list(Name)|Rest], List) :- + package_list(Name, Packages), + extract_package_echo(Packages, Echos), + append(Echos, Tail, List), + extract_package_echo(Rest, Tail). + +aggregate_package_echo(Packages, Assoc) :- + extract_package_echo(Packages, EchoPkgList), + maplist(echo_package, EchoPkgList, EchoAppendList), + empty_assoc(Empty), + aggregate_package_echo(EchoAppendList, Empty, Assoc). + +aggregate_package_echo([ ], Assoc, Assoc). +aggregate_package_echo([echo_append(String, File)|Rest], Assoc, Result) :- + ( get_assoc(File, Assoc, Prev) + -> put_assoc(File, Assoc, String + '\n' + Prev, NewAssoc) + ; put_assoc(File, Assoc, String, NewAssoc) + ), + aggregate_package_echo(Rest, NewAssoc, Result). + +package_echo_dir(Dir, File-String, echo_append(String, Dir +/+ File)). + +gentoo_package_echos(Packages, Dir, Commands) :- + aggregate_package_echo(Packages, Assoc), + assoc_to_list(Assoc, Pairs), + maplist(package_echo_dir(Dir), Pairs, Commands). + +extract_package_names([], []). +extract_package_names([Pkg|Rest], [Pkg|FlatRest]) :- + atom(Pkg), + extract_package_names(Rest, FlatRest). +extract_package_names([package_list(Name)|Rest], Joined) :- + package_list(Name, Packages), + extract_package_names(Packages, FlatPackages), + append(FlatPackages, FlatRest, Joined), + extract_package_names(Rest, FlatRest). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Command construction DCGs % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% +% altering make.conf +% + +dir_make_conf(Dir +/+ 'etc/make.conf') --> + build_dir #? Dir. + +configure_gentoo_packages(Packages) --> + { extract_package_names(Packages, PkgNames), + join(' ', PkgNames, PackagesJoined) + }, + commands #+ [ + comment('configure packages: ' + PackagesJoined), + echo_append('USE="' + JoinedUse + '"', Make_conf), + run([mkdir, '-p', Dir +/+ 'etc/portage/package.use']) + ], + { format_package_use(Packages, JoinedUse), + gentoo_package_echos(Packages, Dir, Commands), + dir_make_conf(Make_conf) + }, + commands #+ Commands. + +reset_make_conf(CFLAGS, CXXFLAGS, CHOST) --> + commands #+ [ comment('create new make.conf') ], + into_build_dir( + echo('#Autogenerated make.conf by ProSys\n' + + 'CFLGAGS="' + CFLAGS + '"\n' + + 'CXXFLAGS="' + CXXFLAGS + '"\n' + + 'CHOST="' + CHOST + '"\n' + ) >> 'etc/make.conf' + ). + +append_site_make_conf --> + { site_conf_file('make.conf', Src) }, + into_build_dir([cat, Src] >> 'etc/make.conf'). + +% +% other auxiliary predicates +% + +set_timezone(Zone) --> + build_dir #? Dir, + commands #+ [ + run([rm, Dir +/+ '/etc/localtime']), + run([ln, '-s', '../usr/share/zoneinfo' +/+ Zone, Dir +/+ 'etc/localtime']) + ]. + +set_locale(Locale) --> + into_build_dir(echo('LC_ALL="'+Locale+'"') > 'etc/env.d/02locale'). +% build_dir #? Dir, +% commands #+ [ +% echo_replace('LC_ALL="' + Locale + '"', Dir +/+ 'etc/env.d/02locale') +% ]. + +create_chroot_script(Arch) --> + build_dir #? Dir, + commands #+ [ + run([cp, '-Lp', '--', Conf + '/chroot.sh-' + Arch, Dir +/+ 'chroot.sh']) + ], + { site_conf_dir(Conf) }. + +into_build_dir(Runnable > File) --> + build_dir #? Dir, + commands #+ [ + Runnable > Dir+/+File + ]. + +into_build_dir(Runnable >> File) --> + build_dir #? Dir, + commands #+ [ + Runnable > Dir+/+File + ]. + +get_portage_timestamp(variable(portage_timestamp)) --> + { script_dir(Script) }, + commands #+ [ + run_outvar([Script +/+ portage_timestamp, '/usr/portage'], + portage_timestamp) + ]. +gentoo_create_pkgdir(Name, Dir) --> + {package_dir(PkgDir)}, + [comment('prepare binpkg directory'), + run(['mkdir', '-p', PkgDir +/+ Name]), + echo_append('trymount --bind ' + + PkgDir +/+ Name + + ' var/portage/packages', + Dir +/+ chroot_conf + ) + ]. + +gentoo_build_stage3(Name, Dir) --> + get_portage_timestamp(Dir, PortageVer), + [chroot(Dir, ['/root/prosys/rebuild_stage3.sh'])], + create_stage(Name + '_stage3-p' + PortageVer, Dir). +gentoo_build_stage4(Name, Dir) --> + [comment('build stages')], + get_portage_timestamp(Dir, PortageVer), + [chroot(Dir, ['/root/prosys/rebuild_stage3.sh'])], + create_stage(Name + '_stage3-p' + PortageVer, Dir), + {script_dir(Script)}, + [run([Script +/+ build_gentoo_stage4, Dir])], + create_stage(Name + '_stage4-p' + PortageVer, Dir). +gentoo_build_stage5(Name, Dir) --> + [comment('build stages')], + get_portage_timestamp(Dir, PortageVer), + [chroot(Dir, ['/root/prosys/update_stage3.sh'])], + create_stage(Name + '_stage3-p' + PortageVer, Dir), + {script_dir(Script)}, + [run([Script +/+ build_gentoo_stage4, Dir])], + create_stage(Name + '_stage4-p' + PortageVer, Dir), + [chroot(Dir, ['/root/prosys/build_stage5.sh'])], + create_stage(Name + '_stage5-p' + PortageVer, Dir). + +%%%%%%%%%%% +% targets % +%%%%%%%%%%% + +%% old old targets% {{{ +%target(i686_hardened_stage3, Dir) --> +% create_gentoo_builddir(i686_hardened, Dir), +% reset_make_conf(Dir, +% '-O2 -pipe -march=i686 -mtune=pentium4 -fomit-frame-pointer', +% '${CFLAGS}', +% 'i686-pc-linux-gnu'), +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir, [portage22, nopy3k, mc, vim]), +% [chroot(Dir, ['/root/prosys/rebuild_stage3.sh'])], +% gentoo_build_stage3(i686_hardened, Dir). +% +%target(i586_geodelx_testing, Dir) --> +% create_gentoo_builddir(i486, Dir), +% {dir_make_conf(Make_conf)}, +% reset_make_conf(Dir, +% '-march=i586 -mtune=geode -O1 -pipe -fomit-frame-pointer', +% '${CFLAGS}', +% 'i586-pc-linux-gnu'), +% [echo_append('ACCEPT_KEYWORDS="~x86"', Make_conf)], +% [echo_append('VIDEO_CARDS="dummy fbdev vesa geode"', Make_conf)], +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir, [portage22, nopy3k, mc, vim, nokit, geode_optimize]), +% gentoo_build_stage4(i586_geodelx_testing, Dir). +% +%target(i586_geodelx_uclibc, Dir) --> +% create_gentoo_builddir(i486, Dir), +% {dir_make_conf(Make_conf)}, +% reset_make_conf(Dir, +% '-march=i586 -mtune=geode -O1 -pipe -fomit-frame-pointer', +% '${CFLAGS}', +% 'i586-pc-linux-uclibc'), +% [echo_append('ACCEPT_KEYWORDS="~x86"', Make_conf)], +% [echo_append('UCLIBC_CPU="586"', Make_conf)], +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir, [portage22, nopy3k, mc, vim, nokit, geode_optimize]), +% [comment('convert to uclibc'), +% run([rm, Dir +/+ '/etc/make.profile']), +% run([ln, '-s', '../usr/portage/profiles/uclibc/x86', Dir +/+ '/etc/make.profile']), +% chroot(Dir, ['/root/prosys/rebuild_stage3_uclibc.sh']) +% ], +% gentoo_build_stage3(i586_geodelx_uclibc, Dir). +% +%target(amd64_stable, Dir) --> +% create_gentoo_builddir(amd64, Dir), +% %{dir_make_conf(Make_conf)}, +% reset_make_conf(Dir, '-O2 -pipe', '${CFLAGS}' +% ,'amd64-pc-linux-gnu'), +% %[echo_append('ACCEPT_KEYWORDS="~amd64"', Make_conf)], +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir ,[ +% portage22, nopy3k, vim, mc, nokit, +% portage_utilities, +% base_utilities, base_system, base_network, +% network_utilities, filesystem_utilities +% ]), +% gentoo_build_stage5(amd64_stable, Dir). +% +%target(amd64_mskp, Dir) --> +% create_gentoo_builddir(amd64, Dir), +% %{dir_make_conf(Make_conf)}, +% reset_make_conf(Dir, '-O2 -pipe', '${CFLAGS}' +% ,'amd64-pc-linux-gnu'), +% %[echo_append('ACCEPT_KEYWORDS="~amd64"', Make_conf)], +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir ,[ +% portage22, nopy3k, nokit, +% portage_utilities, +% base_utilities, base_system, base_network, +% network_utilities, filesystem_utilities, +% picker_deps +% ]), +% [comment('remove python3') +% ,chroot(Dir, ['/root/prosys/rm_py3k.sh']) +% ], +% gentoo_build_stage5(amd64_mskp, Dir). +% +%target(amd64_testing, Dir) --> +% create_gentoo_builddir(amd64, Dir), +% {dir_make_conf(Make_conf)}, +% reset_make_conf(Dir, '-O2 -pipe', '${CFLAGS}' +% ,'amd64-pc-linux-gnu'), +% [echo_append('ACCEPT_KEYWORDS="~amd64"', Make_conf)], +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir ,[ +% portage22, nopy3k, vim, mc, nokit, +% portage_utilities, +% base_utilities, base_system, base_network, +% network_utilities, filesystem_utilities +% ]), +% gentoo_build_stage4(amd64_testing, Dir). +% +% +%target(amd64_hardened_vshost, Dir) --> +% create_gentoo_builddir(amd64_hardened, Dir), +% {dir_make_conf(Make_conf)}, +% reset_make_conf(Dir, '-O2 -pipe', '${CFLAGS}' +% ,'amd64-pc-linux-gnu'), +% [echo_append('ACCEPT_KEYWORDS="~amd64"', Make_conf)], +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir +% ,[portage22, nopy3k, +% base_utilities, base_system, base_network, +% network_utilities, filesystem_utilities +% ]), +% gentoo_build_stage4(amd64_hardened_vshost, Dir). +% +%target(amd64_vserver_base, Dir) --> +% amd64_hardened_vserver(amd64_vserver_base, [], Dir). +% }}} + +target(Name, Dir) --> % stable + create_gentoo_builddir(StageName, Dir), + { dir_make_conf(Make_conf) + , site_conf_file('make.conf', Site_conf) + }, + target_gentoo(BaseName, StageName, StageMax, Dir, [ + run_append([cat, Site_conf], Make_conf) + ]), + {appendn(BaseName, '_stable', Name)}, + gentoo_create_pkgdir(Name, Dir), + gentoo_build_stages(Name, Dir, StageMax, 0, _). + +target(Name, Dir) --> % testing + create_gentoo_builddir(StageName, Dir), + { gentoo_stage(StageName, ArchName, _) + , dir_make_conf(Make_conf) + , site_conf_file('make.conf', Site_conf) + }, + target_gentoo(BaseName, StageName, StageMax, Dir, [ + echo_append('ACCEPT_KEYWORDS="~'+ArchName+'"', Make_conf), + echo_append('RUBY_TARGETS="ruby19"', Make_conf), + run_append([cat, Site_conf], Make_conf) + ]), + {appendn(BaseName, '_testing', Name)}, + gentoo_create_pkgdir(Name, Dir), + gentoo_build_stages(Name, Dir, StageMax, 1, _). + +gentoo_build_stages(Name, Dir, 3, 0, PortageVer) --> + [comment('build stages')], + get_portage_timestamp(Dir, PortageVer), + [chroot(Dir, ['/root/prosys/update_stage3.sh'])], + create_stage(Name + '_stage3-p' + PortageVer, Dir). + +gentoo_build_stages(Name, Dir, 3, 1, PortageVer) --> + [comment('build stages')], + get_portage_timestamp(Dir, PortageVer), + [chroot(Dir, ['/root/prosys/rebuild_stage3.sh'])], + create_stage(Name + '_stage3-p' + PortageVer, Dir). + +gentoo_build_stages(Name, Dir, 4, Rebuild, PortageVer) --> + gentoo_build_stages(Name, Dir, 3, Rebuild, PortageVer), + {script_dir(Script)}, + [run([Script +/+ build_gentoo_stage4, Dir])], + create_stage(Name + '_stage4-p' + PortageVer, Dir). + +gentoo_build_stages(Name, Dir, 5, Rebuild, PortageVer) --> + gentoo_build_stages(Name, Dir, 4, Rebuild, PortageVer), + [chroot(Dir, ['/root/prosys/build_stage5.sh'])], + create_stage(Name + '_stage5-p' + PortageVer, Dir). + +appendn(Start, End, Whole) :- + name(Start, StartS), + name(End, EndS), + append(StartS, EndS, WholeS), + name(Whole, WholeS). + +target_gentoo(k8_x11, i686, 5, Dir, AddCommands) --> + reset_make_conf(Dir, '-O2 -march=i686 -mcpu=k8 -pipe -fomit-frame-pointer' + , '${CFLAGS}', 'i686-pc-linux-gnu'), + prepend(AddCommands), + configure_gentoo_packages(Dir ,[ + portage22, nopy3k, vim, mc, nokit, + portage_utilities, + base_utilities, base_system, base_network, + network_utilities, filesystem_utilities, + base_x11, base_media, net_clients, + development_utilities, latex + ]). + +target_gentoo(amd64_x11, amd64, 5, Dir, AddCommands) --> + reset_make_conf(Dir, '-O2 -pipe', '${CFLAGS}' + ,'amd64-pc-linux-gnu'), + prepend(AddCommands), + configure_gentoo_packages(Dir ,[ + portage22, nopy3k, vim, mc, nokit, + portage_utilities, + base_utilities, base_system, base_network, + network_utilities, filesystem_utilities, + base_x11, base_media, net_clients, + development_utilities, latex + ]). + +target_gentoo(atom_eeepc, i686, 5, Dir, AddCommands) --> + reset_make_conf(Dir, '-Os -march=prescott -pipe -fomit-frame-pointer' + , '${CFLAGS}', 'i686-pc-linux-gnu'), + prepend(AddCommands), + {dir_make_conf(Make_conf)}, + [echo_append('VIDEO_CARDS="dummy fbdev vesa intel"', Make_conf)], + configure_gentoo_packages(Dir ,[ + package_list(common), package_list(laptop), + development_utilities, latex + ]). + +target_gentoo(Name, amd64_hardened, 4, Dir, AddCommands) --> + { gentoo_vserver(VSName, AddPackages) + , appendn('vserver_', VSName, Name)}, + reset_make_conf(Dir, '-O2 -pipe', '${CFLAGS}' ,'amd64-pc-linux-gnu'), + prepend(AddCommands), + configure_gentoo_packages(Dir ,[ + portage22, vim, nokit, + portage_utilities, + base_utilities, base_system, base_network, + vserver | AddPackages + ]). + +gentoo_vserver(vanilla, []). +gentoo_vserver(backups, [vs_backup]). + +%amd64_hardened_vserver(Name, Packages, Dir) --> +% create_gentoo_builddir(amd64_hardened_nomulti, Dir), +% {dir_make_conf(Make_conf)}, +% reset_make_conf(Dir, '-O2 -pipe', '${CFLAGS}' +% ,'amd64-pc-linux-gnu'), +% [echo_append('ACCEPT_KEYWORDS="~amd64"', Make_conf)], +% append_site_make_conf(Dir), +% configure_gentoo_packages(Dir +% ,[portage22, nopy3k, +% base_utilities, base_system, +% vserver_init +% | Packages +% ]), +% gentoo_build_stage4(Name, Dir). + +% TODO make gentoo stage target from this +%create_gentoo_builddir(Name, Dir) --> +% {gentoo_stage(Name, ArchName, _)}, +% download_gentoo_stage(Tarball, Name), +% prepend([comment('prepare build directory') +% ,run([mkdir, '-p' +% ,Dir +/+ 'usr/portage' +% ,Dir +/+ 'var/portage/ccache' +% ,Dir +/+ 'var/portage/packages' +% ]) +% ]), +% unpack_tarball(Tarball, Dir), +% create_chroot_script(Dir, ArchName), +% {work_dir(Work), site_conf_dir(Conf)}, +% [run([rsync, '-a', Work +/+ 'overlay/' +% , Dir +/+ 'var/portage/ccx-autobuild' +% ]), +% run([rsync, '-a', Conf +/+ 'gentoo_scripts/' +% , Dir +/+ 'root/prosys/' +% ]), +% run([rsync, '-a', Conf +/+ 'portage/' +% , Dir +/+ 'etc/portage/' +% ]), +% comment('configure local settings') +% ], +% set_timezone(Dir, 'Europe/Prague'), +% set_locale(Dir, 'en_US.UTF-8'). + + +% gentoo stage tarballs +target(TargetName) --> + { gentoo_stage(StageName, Arch, Txt), + TargetName =: gentoo_stage3_ + StageName, + gentoo_mirror(Mirror), + script_dir(Scripts), work_dir(Work), downloads_dir(DownloadsDir) + }, + build_dir #= variable(build_dir), + commands #+ [ + build_dir = [Scripts+/+get_gentoo_stage, + Work+/+build+/+TargetName, + DownloadsDir+/+StageName, + Mirror +/+ releases +/+ Arch +/+ autobuilds +/+ Txt + ] + ], + create_chroot_script(Arch), + ( { stages_set_timezone(TimeZone) } + -> set_timezone(TimeZone) + ; { true } + ), + ( { stages_set_locale(Locale) } + -> set_locale(Locale) + ; { true } + ). + +% build ~arch variant from gentoo stage +target(TargetName) --> + { gentoo_stage(StageName, Arch, _Txt), + PrevTargetName =: gentoo_stage3_ + StageName, + TargetName =: PrevTargetName + '_testing', + % script_dir(Scripts), + targets_dir(TargetsDir), + build_dir(BuildDir), + B = variable(build_dir) + }, + get_portage_timestamp(PortageTS), + build_dir #= B, + commands #+ [ + build_dir = BuildDir+/+TargetName+'-p'+PortageTS, + [TargetsDir+/+PrevTargetName, variable(build_dir)], + echo('ACCEPT_KEYWORDS="~'+Arch+'"') >> (B+/+'etc/make.conf'), + chroot(B, ['/root/prosys/rebuild_stage3.sh']) + ]. + +clone_stage --> + { script_dir(Scripts) }, + build_dir #? Src, + commands #+ [ + verbatim('if [[ -n "$1" ]]; then\n\t'), + [Scripts+/+snapshot_stage, Src, variable('1')], + verbatim('fi\n') + ]. + +% automatically add some stuff to stage commands +target_wrapper(Name) --> + target(Name), + into_build_dir(echo(Name) >> 'root/prosys/stages_completed'), + clone_stage. + +% non-dcg variant of target, sets up parameters and calls dcg variant +target(Name, Commands) :- + list_to_assoc([ commands-(Commands-Commands) ], AssocIn), + phrase(target_wrapper(Name), AssocIn, AssocOut), + get_assoc(commands, AssocOut, Commands-[]). + +debug_target(Name) :- + target(Name, C), + !, + write('Commands: '), + nl, + write(C), + nl, + cmds_repr(C). + +printnl(Text) :- + print(Text), + nl. + +main([ ]) :- + findall(Name , target(Name, _), Names), + maplist(printnl, Names). + +main([Name]) :- + target(Name, Commands), + print('#!/bin/zsh -x\n\n# Generated by ProSys stagebuilder\n# Stage name: '), + print(Name), nl, + cmds_print(Commands). + +%main([Name]) :- main([Name, variable('1')]).