aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-05-14 21:03:01 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-05-15 18:12:12 +0300
commit1ffe9fa27ee9829c16446a09aa5bd94bcc60ab68 (patch)
treefef5df69e64ab0c64dc299e864e04185b7d022e0
parent602b71ed970b8ca9fea19c0103be7a977179d50d (diff)
Add update, clean, and test commands tests
-rw-r--r--tests/common.test34
-rw-r--r--tests/fetch.test11
-rw-r--r--tests/init.test148
-rw-r--r--tests/new.test83
-rw-r--r--tests/status.test58
-rw-r--r--tests/sync.test81
-rw-r--r--tests/test.test29
-rw-r--r--tests/update.test38
8 files changed, 388 insertions, 94 deletions
diff --git a/tests/common.test b/tests/common.test
index f66d9eb..8578f5c 100644
--- a/tests/common.test
+++ b/tests/common.test
@@ -5,14 +5,25 @@
# Commonly-used variables setup and driver command line.
#
+# Variables for supporting Windows/POSIX testscript variants.
+#
+win32 = ($cxx.target.class == 'windows')
+exe = ($win32 ? '.exe' : '')
+
# Use the same build system driver as the one running the tests (as opposed
-# to one that may or may not be found via PATH). A common approach will be to
-# run build2 as a sanity check in a directory produced/updated by the bdep
-# command being tested.
+# to one that may or may not be found via PATH). This implies that we don't
+# support cross-testing.
+#
+# A common approach will be to run build2 as a sanity check in a directory
+# produced/updated by a command being tested.
#
build = $recall($build.path)
test.options += --build $build
+# @@ It would be nice to query bdep for the bpkg path it uses.
+#
+bpkg = ("$config.bdep.test.bpkg" != '' ? "$config.bdep.test.bpkg" : "bpkg$exe")
+
# Helper commands that can be used by tests to prepare the testing environment
# or validate an outcome of the command being tested. They are likely to get
# additional options and redirects appended prior to use. A common approach
@@ -21,24 +32,17 @@ test.options += --build $build
# (for example, to make sure that configuration post-test state is valid and is
# as expected).
#
+clean = $* clean
+deinit = $* deinit
+init = $* init
+fetch = $* fetch
new = $* new
status = $* status
-init = $* init
sync = $* sync
-fetch = $* fetch
-deinit = $* deinit
+update = $* update
# All testscripts are named after bdep commands, for example sync.test. So the
# testscript scope id is a name of the command being tested.
#
cmd = [string] $@
test.arguments = $cmd
-
-# Convenience variables for supporting Windows/POSIX testscript variants.
-#
-win32 = ($cxx.target.class == 'windows')
-exe = ($win32 ? '.exe' : '')
-
-# @@ It would be nice to query bdep for the bpkg path it uses.
-#
-bpkg = ("$config.bdep.test.bpkg" != '' ? "$config.bdep.test.bpkg" : "bpkg$exe")
diff --git a/tests/fetch.test b/tests/fetch.test
index ad0640e..7fec857 100644
--- a/tests/fetch.test
+++ b/tests/fetch.test
@@ -7,12 +7,13 @@
new += 2>!
init += cc "config.cxx=$config.cxx" -d prj 2>!
status += --all
+deinit += -d prj
: add-dependency
:
{
$clone_prj;
- $init -C prj-cfg @cfg &prj/build/bootstrap/*** &prj-cfg/***;
+ $init -C prj-cfg @cfg &prj-cfg/***;
$new -t lib --vcs none libfoo &libfoo/*** 2>!;
$new -t lib --vcs none libbar &libbar/*** 2>!;
@@ -35,9 +36,15 @@ status += --all
$status -d prj >'prj configured 0.1.0-a.0.19700101000000';
- $bpkg list --complements --prerequisites -d prj-cfg >>/"EOO"
+ $bpkg list --complements --prerequisites -d prj-cfg >>/"EOO";
dir:$~/prj $~/prj
complement dir:$~/libbar $~/libbar
prerequisite dir:$~/libfoo $~/libfoo
EOO
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ synchronizing:
+ drop prj
+ EOE
}
diff --git a/tests/init.test b/tests/init.test
index 43ce441..3fc05c6 100644
--- a/tests/init.test
+++ b/tests/init.test
@@ -7,13 +7,13 @@
.include common.test project.test
-new += 2>!
-status += --all
+new += -d prj
+status += -d prj
deinit += -d prj
cxx = cc "config.cxx=$config.cxx"
-: cfg-create
+: create-cfg
:
: We will also test that the configuration variables are properly persisted and
: the project is properly built in the source tree.
@@ -25,23 +25,31 @@ cxx = cc "config.cxx=$config.cxx"
initializing in project $~/prj/
created configuration @cfg $~/prj-cfg/ \(1, default, forwarded, auto-synchronized\)
synchronizing:
- % new prj.0\.1\.0-a\.0\.19700101000000%
+ % new prj.+19700101000000%
EOE
sed -n -e 's/^config.cc.poptions = (.+)$/\1/p' prj-cfg/build/config.build \
>'-DTEST';
- $status --directory prj >'prj configured 0.1.0-a.0.19700101000000';
+ $status >'prj configured 0.1.0-a.0.19700101000000';
- $build prj/ 2>>/EOE &prj/prj/prj$exe;
+ $build prj/ 2>>/EOE;
mkdir prj-cfg/prj/fsdir{prj/}
c++ prj/prj/cxx{prj}@prj-cfg/prj/prj/
ld prj-cfg/prj/prj/exe{prj}
ln prj-cfg/prj/prj/exe{prj} -> prj/prj/
EOE
- $build prj-cfg/ 2>>/EOE;
- info: dir{prj-cfg/} is up to date
+ prj/prj/prj 'testscript' >'Hello, testscript!';
+
+ $build prj-cfg/prj/ 2>>/EOE;
+ info: prj-cfg/dir{prj/} is up to date
+ EOE
+
+ $build 'clean:' prj/ 2>>/EOE;
+ rm prj-cfg/prj/prj/exe{prj}
+ rm prj-cfg/prj/prj/obje{prj}
+ rm prj-cfg/prj/fsdir{prj/}
EOE
$deinit 2>>/"EOE"
@@ -51,31 +59,29 @@ cxx = cc "config.cxx=$config.cxx"
EOE
}
-: cfg-add
+: add-cfg
:
{
- create_cfg = $bpkg create $cxx -d 2>!
-
$clone_prj;
- $create_cfg prj-cfg1/ &prj-cfg1/***;
- $create_cfg prj-cfg2/ &prj-cfg2/***;
+ $bpkg create $cxx -d prj-cfg1/ 2>! &prj-cfg1/***;
+ $bpkg create $cxx -d prj-cfg2/ 2>! &prj-cfg2/***;
- $* -A @cfg1 2>>/~"%EOE%";
+ $* -A @cfg1 2>>/~"%EOE%"; # Shortcut.
initializing in project $~/prj/
added configuration @cfg1 $~/prj-cfg1/ \(1, default, forwarded, auto-synchronized\)
synchronizing:
- % new prj.0\.1\.0-a\.0\.19700101000000%
+ % new prj.+19700101000000%
EOE
$* -A prj-cfg2 @cfg2 2>>/~"%EOE%";
initializing in project $~/prj/
added configuration @cfg2 $~/prj-cfg2/ \(2, auto-synchronized\)
synchronizing:
- % new prj.0\.1\.0-a\.0\.19700101000000%
+ % new prj.+19700101000000%
EOE
- $status --directory prj >>EOO;
+ $status --all >>EOO;
in configuration @cfg1:
prj configured 0.1.0-a.0.19700101000000
@@ -107,5 +113,109 @@ cxx = cc "config.cxx=$config.cxx"
EOE
}
-# @@ Test initializing a package rather than project.
-#
+: pkg
+:
+: Test initializing a package while creating it inside an already existing
+: project.
+:
+{
+ # Create (and build) the executable single-package project.
+ #
+ cp --no-cleanup -p -r ../prj ./ &prj/***;
+
+ $* -C @cfg $cxx 2>>/~"%EOE%" &prj-cfg/***;
+ initializing in project $~/prj/
+ created configuration @cfg $~/prj-cfg/ \(1, default, forwarded, auto-synchronized\)
+ synchronizing:
+ % new prj.+19700101000000%
+ EOE
+
+ $status >'prj configured 0.1.0-a.0.19700101000000';
+
+ $build prj/ 2>>/EOE;
+ mkdir prj-cfg/prj/fsdir{prj/}
+ c++ prj/prj/cxx{prj}@prj-cfg/prj/prj/
+ ld prj-cfg/prj/prj/exe{prj}
+ ln prj-cfg/prj/prj/exe{prj} -> prj/prj/
+ EOE
+
+ $build prj-cfg/ 2>>/EOE;
+ info: dir{prj-cfg/} is up to date
+ EOE
+
+ # Move the executable package into a separate directory.
+ #
+ mkdir --no-cleanup prj/prj.pkg;
+
+ # @@ Shouldn't we add mv builtin?
+ #
+ fs = prj/prj/ prj/build/ prj/buildfile prj/manifest prj/.gitignore;
+ cp --no-cleanup -p -r $fs prj/prj.pkg/;
+ rm -r $fs;
+
+ cp --no-cleanup -p -r prj/prj.pkg/ prj/prj;
+ rm -r prj/prj.pkg/;
+
+ cat <<EOI >=prj/packages.manifest;
+ : 1
+ location: prj/
+ EOI
+
+ # Add the library package.
+ #
+ $new --package -t lib libprj 2>>/"EOE";
+ created new library package libprj in $~/prj/libprj/
+ EOE
+
+ $init -a -d prj/libprj 2>>/~"%EOE%";
+ initializing in project $~/prj/
+ synchronizing:
+ % upgrade prj.+19700101000000#1%
+ % new libprj.+19700101000000%
+ EOE
+
+ # Factor out some of the executable package functionality into the library.
+ #
+ cat <<EOI >+prj/prj/manifest;
+ depends: libprj
+ EOI
+
+ sed -i -e 's/^(#import .+)$/import libs += libprj%lib{prj}/' \
+ prj/prj/prj/buildfile;
+
+ cat <<EOI >=prj/prj/prj/prj.cxx;
+ #include <iostream>
+
+ #include <libprj/prj.hxx>
+
+ using namespace std;
+
+ int main (int argc, char* argv[])
+ {
+ if (argc < 2)
+ {
+ cerr << "error: missing name" << endl;
+ return 1;
+ }
+
+ prj::say_hello (cout, argv[1]);
+ }
+ EOI
+
+ $build prj-cfg/prj/ 2>>/~"%EOE%";
+ synchronizing $~/prj-cfg/:
+ % upgrade prj.+19700101000000#2%
+ %mkdir prj-cfg/.+%{2}
+ %.{3}
+ %ld prj-cfg/.+%{2}
+ EOE
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ deinitializing package prj
+ deinitializing package libprj
+ synchronizing:
+ drop prj
+ drop libprj
+ EOE
+}
diff --git a/tests/new.test b/tests/new.test
index 96cb4c5..cdb1537 100644
--- a/tests/new.test
+++ b/tests/new.test
@@ -4,42 +4,77 @@
.include common.test
+status += -d prj
+
+cxx = cc "config.cxx=$config.cxx"
+
: exe
{
- $* -t exe hello 2>>/"EOE" &hello/***;
- created new executable project hello in $~/hello/
+ $* -t exe -l c++ prj 2>>/"EOE" &prj/***;
+ created new executable project prj in $~/prj/
EOE
- $build hello/ 2>>/EOE
- c++ hello/hello/cxx{hello}
- ld hello/hello/exe{hello}
+ $build prj/ 2>>/EOE
+ c++ prj/prj/cxx{prj}
+ ld prj/prj/exe{prj}
EOE
}
: lib
{
- $* -t lib libhello 2>>/"EOE" &libhello/***;
- created new library project libhello in $~/libhello/
+ $* -t lib -l c++ libprj 2>>/"EOE" &libprj/***;
+ created new library project libprj in $~/libprj/
EOE
- # We build the project by chunks to make sure the output is reproducible (no,
- # -s doesn't really help).
- #
- echo "#include <libhello/version.hxx>" >+libhello/libhello/hello.hxx;
-
- $build libhello/libhello/libs{hello} 2>>/EOE;
- ver libhello/libhello/version.hxx.in
- c++ libhello/libhello/cxx{hello}
- ld libhello/libhello/libs{hello}
+ $build libprj/ 2>>/~%EOE%
+ %.{4}
+ %ld libprj/.+%{3}
EOE
+}
- $build libhello/libhello/ 2>>/EOE;
- c++ libhello/libhello/cxx{hello}
- ld libhello/libhello/liba{hello}
- EOE
+: cfg
+{
+ : dir-and-name
+ :
+ {
+ $* -C prj-config @cfg prj $cxx 2>>/~"%EOE%" &prj/*** &prj-config/***;
+ created new executable project prj in $~/prj/
+ created configuration @cfg $~/prj-config/ \(1, default, forwarded, auto-synchronized\)
+ synchronizing:
+ % new prj.+19700101000000%
+ EOE
- $build libhello/ 2>>/EOE
- c++ libhello/tests/basics/cxx{driver}
- ld libhello/tests/basics/exe{driver}
- EOE
+ $status >'prj configured 0.1.0-a.0.19700101000000';
+
+ $build prj/ 2>>/EOE
+ mkdir prj-config/prj/fsdir{prj/}
+ c++ prj/prj/cxx{prj}@prj-config/prj/prj/
+ ld prj-config/prj/prj/exe{prj}
+ ln prj-config/prj/prj/exe{prj} -> prj/prj/
+ EOE
+ }
+
+ : name
+ :
+ : Test deducing the configuration directory path from project source
+ : directory path and configuration name. Here we also use the dash-prefixed
+ : name (as in Windows PowerShell where the leading '@' character is special).
+ :
+ {
+ $* -C -@cfg prj $cxx 2>>/~"%EOE%" &prj/*** &prj-cfg/***;
+ created new executable project prj in $~/prj/
+ created configuration @cfg $~/prj-cfg/ \(1, default, forwarded, auto-synchronized\)
+ synchronizing:
+ % new prj.+19700101000000%
+ EOE
+
+ $status >'prj configured 0.1.0-a.0.19700101000000';
+
+ $build prj/ 2>>/EOE
+ mkdir prj-cfg/prj/fsdir{prj/}
+ c++ prj/prj/cxx{prj}@prj-cfg/prj/prj/
+ ld prj-cfg/prj/prj/exe{prj}
+ ln prj-cfg/prj/prj/exe{prj} -> prj/prj/
+ EOE
+ }
}
diff --git a/tests/status.test b/tests/status.test
index bdf3434..99fe360 100644
--- a/tests/status.test
+++ b/tests/status.test
@@ -4,27 +4,34 @@
.include common.test project.test
-new += 2>!
-init += cc "config.cxx=$config.cxx" -d prj 2>!
-sync += -d prj 2>!
+new += 2>!
+init += cc "config.cxx=$config.cxx" -d prj 2>!
+sync += -d prj 2>!
+deinit += -d prj
-: basic
+: no-config
:
{
$clone_prj;
- $init -C prj-cfg @cfg &prj/build/bootstrap/*** &prj-cfg/***;
- $* >'prj configured 0.1.0-a.0.19700101000000'
+ $* 2>>/"EOE" != 0
+ error: no default configuration in project $~/prj/
+ info: use \(@<cfg-name> | --config|-c <cfg-dir> | --all|-a\) to specify configuration explicitly
+ EOE
}
-: no-config
+: one-config
:
{
$clone_prj;
+ $init -C prj-cfg @cfg &prj-cfg/***;
- $* 2>>/"EOE" != 0
- error: no default configuration in project $~/prj/
- info: use \(@<cfg-name> | --config|-c <cfg-dir> | --all|-a\) to specify configuration explicitly
+ $* >'prj configured 0.1.0-a.0.19700101000000';
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ synchronizing:
+ drop prj
EOE
}
@@ -32,49 +39,62 @@ sync += -d prj 2>!
:
{
$clone_prj;
- $init -C prj-cfg1 @cfg1 &prj-cfg1/*** &prj/build/bootstrap/***;
+ $init -C prj-cfg1 @cfg1 &prj-cfg1/***;
$init -C prj-cfg2 @cfg2 &prj-cfg2/***;
$* @cfg2 >'prj configured 0.1.0-a.0.19700101000000';
- $* --all >>EOO
+ $* --all >>EOO;
in configuration @cfg1:
prj configured 0.1.0-a.0.19700101000000
in configuration @cfg2:
prj configured 0.1.0-a.0.19700101000000
EOO
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ synchronizing:
+ drop prj
+ EOE
}
: dependency
:
{
$clone_prj;
- $init -C prj-cfg @cfg &prj/build/bootstrap/*** &prj-cfg/***;
+ $init -C prj-cfg @cfg &prj-cfg/***;
- $new -t lib --vcs none libhello &libhello/***;
+ $new -t lib --vcs none libprj &libprj/***;
cat <<EOI >+prj/repositories.manifest;
:
role: prerequisite
- location: ../libhello
+ location: ../libprj
type: dir
EOI
cat <<EOI >+prj/manifest;
- depends: libhello
+ depends: libprj
EOI
$* --recursive >>EOO 2>>/"EOE";
prj configured 0.1.0-a.0.19700101000000 available 0.1.0-a.0.19700101000000#1
EOO
- fetching dir:$~/libhello \(prerequisite of dir:$~/prj\)
+ fetching dir:$~/libprj \(prerequisite of dir:$~/prj\)
EOE
$sync;
- $* --recursive >>~%EOO%
+ $* --recursive >>~%EOO%;
prj configured 0.1.0-a.0.19700101000000#1
- % libhello configured 0\.1\.0-a\.0\..+%
+ % libprj configured 0\.1\.0-a\.0\..+%
EOO
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ synchronizing:
+ drop prj
+ drop libprj
+ EOE
}
diff --git a/tests/sync.test b/tests/sync.test
index 1e044b2..74d9a6d 100644
--- a/tests/sync.test
+++ b/tests/sync.test
@@ -6,34 +6,37 @@
new += 2>!
init += cc "config.cxx=$config.cxx" -d prj 2>!
-status += --all --recursive
+status += --all --recursive -d prj
+deinit += -d prj
: dependency
:
{
$clone_prj;
- $init -C prj-cfg @cfg &prj/build/bootstrap/*** &prj-cfg/***;
- $new -t lib --vcs none libhello &libhello/***;
+ $init -C @cfg1 &prj-cfg1/***;
+ $init -C @cfg2 &prj-cfg2/***;
+
+ $new -t lib --vcs none libprj &libprj/***;
cat <<EOI >+prj/repositories.manifest;
:
role: prerequisite
- location: ../libhello
+ location: ../libprj
type: dir
EOI
cat <<EOI >+prj/manifest;
- depends: libhello
+ depends: libprj
EOI
- sed -i -e 's/^(#import .+)$/import libs += libhello%lib{hello}/' \
+ sed -i -e 's/^(#import .+)$/import libs += libprj%lib{prj}/' \
prj/prj/buildfile;
cat <<EOI >=prj/prj/prj.cxx;
#include <iostream>
- #include <libhello/hello.hxx>
+ #include <libprj/prj.hxx>
using namespace std;
@@ -45,22 +48,70 @@ status += --all --recursive
return 1;
}
- hello::say_hello (cout, argv[1]);
+ prj::say_hello (cout, argv[1]);
}
EOI
+ # Sync the default (cfg1) configuration.
+ #
$* 2>>/~"%EOE%";
- fetching dir:$~/libhello \(prerequisite of dir:$~/prj\)
+ fetching dir:$~/libprj \(prerequisite of dir:$~/prj\)
synchronizing:
- % new libhello.0\.1\.0-a\.0\..+ \\\(required by prj\\\)%
- % upgrade prj.0\.1\.0-a\.0\.19700101000000#1%
+ % new libprj.+ \\\(required by prj\\\)%
+ % upgrade prj.+19700101000000#1%
EOE
- $status -d prj >>~%EOO%;
+ $status >>~%EOO% 2>>/~"%EOE%";
+ in configuration @cfg1:
prj configured 0.1.0-a.0.19700101000000#1
- % libhello configured 0\.1\.0-a\.0\..+%
+ % libprj configured 0.+%
+
+ in configuration @cfg2:
+ prj configured 0.1.0-a.0.19700101000000 available 0.1.0-a.0.19700101000000#1
EOO
+ fetching dir:$~/libprj \(prerequisite of dir:$~/prj\)
+ EOE
+
+ # Sync all configuration.
+ #
+ $* --all 2>>~%EOE%;
+ in configuration @cfg1:
+
+ in configuration @cfg2:
+ synchronizing:
+ % new libprj.+ \(required by prj\)%
+ upgrade prj/0.1.0-a.0.19700101000000#1
+ EOE
+
+ $status >>~%EOE%;
+ in configuration @cfg1:
+ prj configured 0.1.0-a.0.19700101000000#1
+ % libprj configured 0.+%
- $build prj/ 2>! &prj/prj/prj$exe &?prj/prj/prj.exe.dlls/***;
- prj/prj/prj 'testscript' >'Hello, testscript!'
+ in configuration @cfg2:
+ prj configured 0.1.0-a.0.19700101000000#1
+ % libprj configured 0.+%
+ EOE
+
+ # @@ Add synchronizing a single package when 'new -t empty' is supported.
+ #
+ $build prj/ 2>>/~"%EOE%";
+ %mkdir prj-cfg1/.+%{2}
+ %.{3}
+ %ld prj-cfg1/.+%{2}
+ ln prj-cfg1/prj/prj/exe{prj} -> prj/prj/
+ EOE
+
+ $build 'clean:' prj/ 2>>/EOE;
+ rm prj-cfg1/prj/prj/exe{prj}
+ rm prj-cfg1/prj/prj/obje{prj}
+ rm prj-cfg1/prj/fsdir{prj/}
+ EOE
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ synchronizing:
+ drop prj
+ drop libprj
+ EOE
}
diff --git a/tests/test.test b/tests/test.test
new file mode 100644
index 0000000..673927b
--- /dev/null
+++ b/tests/test.test
@@ -0,0 +1,29 @@
+# file : tests/test.test
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+.include common.test project.test
+
+init += cc "config.cxx=$config.cxx" -d prj 2>!
+deinit += -d prj
+
+: project
+:
+{
+ $clone_prj;
+
+ $init -C @cfg &prj-cfg/***;
+
+ $* 2>>/EOE;
+ mkdir prj-cfg/prj/fsdir{prj/}
+ c++ prj/prj/cxx{prj}@prj-cfg/prj/prj/
+ ld prj-cfg/prj/prj/exe{prj}
+ test prj/prj/test{testscript}@prj-cfg/prj/prj/ prj-cfg/prj/prj/exe{prj}
+ EOE
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ synchronizing:
+ drop prj
+ EOE
+}
diff --git a/tests/update.test b/tests/update.test
new file mode 100644
index 0000000..23055c6
--- /dev/null
+++ b/tests/update.test
@@ -0,0 +1,38 @@
+# file : tests/update.test
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+# Here we test both update and clean commands.
+#
+
+.include common.test project.test
+
+init += cc "config.cxx=$config.cxx" -d prj 2>!
+deinit += -d prj
+clean += -d prj
+
+: project
+:
+{
+ $clone_prj;
+
+ $init -C @cfg &prj-cfg/***;
+
+ $* 2>>/EOE;
+ mkdir prj-cfg/prj/fsdir{prj/}
+ c++ prj/prj/cxx{prj}@prj-cfg/prj/prj/
+ ld prj-cfg/prj/prj/exe{prj}
+ EOE
+
+ $clean 2>>/EOE;
+ rm prj-cfg/prj/prj/exe{prj}
+ rm prj-cfg/prj/prj/obje{prj}
+ rm prj-cfg/prj/fsdir{prj/}
+ EOE
+
+ $deinit 2>>/"EOE"
+ deinitializing in project $~/prj/
+ synchronizing:
+ drop prj
+ EOE
+}