diff --git a/.gitignore b/.gitignore index 21808c7..f3ed09f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ config.status configure stamp-vti stow.info -t/target/ version.texi lib/Stow.pm doc/stow.8 @@ -20,3 +19,4 @@ doc/stow.html stamp-vti MYMETA.json MYMETA.yml +tmp-testing-trees/ diff --git a/Makefile.am b/Makefile.am index 916c82f..7419305 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,37 +11,74 @@ dist_pmstow_DATA = lib/Stow/Util.pm TEXINFO_TEX = doc/texinfo.tex export TEXI2DVI_BUILD_MODE = clean +AM_MAKEINFOFLAGS = -I $(srcdir) -DEFAULT_IGNORE_LIST = default-ignore-list +# We require this -I parameter to ensure that the include of the +# default ignore list in the manual works. Unfortunately this is +# the only way to do it: +# +# http://article.gmane.org/gmane.comp.sysutils.automake.bugs/4334/match=passing+parameters +# +# even though it annoyingly produces a warning with the -Wall option +# to AM_INIT_AUTOMAKE which has to be silenced via -Wno-override. +TEXI2DVI = texi2dvi $(AM_MAKEINFOFLAGS) -TESTS_ENVIRONMENT=$(PERL) -I $(top_srcdir) -TESTS = \ - t/cleanup_invalid_links.t \ - t/defer.t \ - t/examples.t \ - t/find_stowed_path.t \ - t/foldable.t \ - t/ignore.t \ - t/parent.t \ - t/stow_contents.t \ - t/stow.t \ - t/unstow_contents_orig.t \ - t/unstow_contents.t \ - t/chkstow.t +DEFAULT_IGNORE_LIST = $(srcdir)/default-ignore-list + +TESTS_DIR = $(srcdir)/t +TESTS_OUT = tmp-testing-trees +TESTS_ENVIRONMENT = $(PERL) -I$(srcdir)/bin -I$(srcdir)/lib -I$(TESTS_DIR) + +# This is a kind of hack; TESTS needs to be set to ensure that the +# `check-am' target makes check-TESTS, but we override check-TESTS +# so it doesn't really matter what it's set to, as long as it already +# exists (otherwise automake will try to build it). +TESTS = t AUTOMAKE_OPTIONS = dist-shar + +# GNU autotools standardised on the 'check' target, but CPAN (and the +# rest of the world) standardised on the 'test' target. +test: check + +# required in vpath mode to ensure $build/t/ exists +check_DATA = $(TESTS_OUT) + +# Test::Harness produces cleaner output than automake's default test +# harness, albeit without the pretty colours provided by the +# `color-tests' AM_INIT_AUTOMAKE option. This also dodges having to +# set TESTS to the full list of tests, which is good because automake +# doesn't support wildcards, and so it would be too easy to forget to +# add a new one to the list. +# +# Note that automake's `check' rule cannot be overridden +# for some weird reason: +# +# http://thread.gmane.org/gmane.comp.sysutils.automake.general/13040/focus=13041 +# +# so we override check-TESTS instead which is where the real work is +# done anyway. Unfortunately this produces a warning with the -Wall +# option to AM_INIT_AUTOMAKE which has to be silenced via +# -Wno-override. +check-TESTS: + dir=$(TESTS_DIR); \ + $(TESTS_ENVIRONMENT) -MTest::Harness -e 'runtests(@ARGV)' "$${dir#./}"/*.t + +$(TESTS_OUT): + mkdir -p $@ + CPAN_FILES = MANIFEST MANIFEST.SKIP Build.PL META.yml META.json EXTRA_DIST = \ bin/stow.in bin/chkstow.in lib/Stow.pm.in \ $(TESTS) t/testutil.pm \ $(TEXINFO_TEX) \ - default-ignore-list \ + $(DEFAULT_IGNORE_LIST) \ $(CPAN_FILES) CLEANFILES = $(bin_SCRIPTS) $(dist_pm_DATA) # clean up files left behind by test suite clean-local: - -rm -rf t/target t/stow \ + -rm -rf $(TESTS_OUT) \ bin/stow bin/chkstow doc/stow.8 ChangeLog \ doc/manual.* @@ -50,14 +87,17 @@ edit = sed -e 's|[@]PERL[@]|$(PERL)|g' \ -e 's|[@]VERSION[@]|$(VERSION)|g' bin/stow: bin/stow.in Makefile + [ -d bin ] || mkdir bin # required in vpath mode $(edit) < $< > $@ chmod +x $@ bin/chkstow: bin/chkstow.in Makefile + [ -d bin ] || mkdir bin # required in vpath mode $(edit) < $< > $@ chmod +x $@ lib/Stow.pm: lib/Stow.pm.in Makefile $(DEFAULT_IGNORE_LIST) + [ -d lib ] || mkdir lib # required in vpath mode ( $(edit) < $<; cat $(DEFAULT_IGNORE_LIST) ) > $@ ############################################################################## @@ -86,8 +126,6 @@ doc/manual.html: doc/manual.texi cd doc && texi2html -I $$srcdir -expandinfo -menu -monolithic -verbose manual.texi doc/stow.8: bin/stow Makefile + [ -d doc ] || mkdir doc # required in vpath mode pod2man $< > $@ -MODULES = lib/Stow.pm lib/Stow/Util.pm -test: bin/stow bin/chkstow $(MODULES) - perl -MTest::Harness -Ilib -It -Ibin -e 'runtests(@ARGV)' t/*.t diff --git a/configure.ac b/configure.ac index a9b6fa7..65b5f32 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,10 @@ dnl Process this file with Autoconf to produce configure dnl AC_INIT([stow], [2.0.2], [bug-stow@gnu.org]) AC_PREREQ([2.61]) AC_CONFIG_AUX_DIR([automake]) -AM_INIT_AUTOMAKE([-Wall -Werror]) +# Unfortunately we have to disable warnings for overrides, because we +# need to override the built-in `check' rule and also the TEXI2DVI +# variable. +AM_INIT_AUTOMAKE([-Wall -Werror -Wno-override]) AC_PROG_INSTALL AM_MAINTAINER_MODE([enable]) diff --git a/t/chkstow.t b/t/chkstow.t index 4affd7f..bb611d8 100755 --- a/t/chkstow.t +++ b/t/chkstow.t @@ -15,7 +15,7 @@ use Test::Output; use English qw(-no_match_vars); init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); # setup stow directory make_dir('stow'); diff --git a/t/cleanup_invalid_links.t b/t/cleanup_invalid_links.t index 99bfdf3..e6edd9d 100755 --- a/t/cleanup_invalid_links.t +++ b/t/cleanup_invalid_links.t @@ -13,7 +13,7 @@ use English qw(-no_match_vars); use testutil; init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); my $stow; diff --git a/t/defer.t b/t/defer.t index 24d4d5f..ca47fb3 100755 --- a/t/defer.t +++ b/t/defer.t @@ -11,6 +11,9 @@ use testutil; use Test::More tests => 4; +init_test_dirs(); +cd("$OUT_DIR/target"); + my $stow; $stow = new_Stow(defer => [ 'man' ]); diff --git a/t/examples.t b/t/examples.t index 67d72aa..42894ef 100755 --- a/t/examples.t +++ b/t/examples.t @@ -13,7 +13,7 @@ use Test::More tests => 10; use English qw(-no_match_vars); init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); my $stow; diff --git a/t/find_stowed_path.t b/t/find_stowed_path.t index c632d5d..2d5425d 100755 --- a/t/find_stowed_path.t +++ b/t/find_stowed_path.t @@ -13,15 +13,15 @@ use Test::More tests => 6; init_test_dirs(); -my $stow = new_Stow(dir => 't/stow'); +my $stow = new_Stow(dir => "$OUT_DIR/stow"); is_deeply( - [ $stow->find_stowed_path('t/target/a/b/c', '../../../stow/a/b/c') ], - [ 't/stow/a/b/c', 't/stow', 'a' ] + [ $stow->find_stowed_path("$OUT_DIR/target/a/b/c", '../../../stow/a/b/c') ], + [ "$OUT_DIR/stow/a/b/c", "$OUT_DIR/stow", 'a' ] => 'from root' ); -cd('t/target'); +cd("$OUT_DIR/target"); $stow->set_stow_dir('../stow'); is_deeply( [ $stow->find_stowed_path('a/b/c','../../../stow/a/b/c') ], @@ -31,33 +31,33 @@ is_deeply( make_dir('stow'); cd('../..'); -$stow->set_stow_dir('t/target/stow'); +$stow->set_stow_dir("$OUT_DIR/target/stow"); is_deeply( - [ $stow->find_stowed_path('t/target/a/b/c', '../../stow/a/b/c') ], - [ 't/target/stow/a/b/c', 't/target/stow', 'a' ] + [ $stow->find_stowed_path("$OUT_DIR/target/a/b/c", '../../stow/a/b/c') ], + [ "$OUT_DIR/target/stow/a/b/c", "$OUT_DIR/target/stow", 'a' ] => 'stow is subdir of target directory' ); is_deeply( - [ $stow->find_stowed_path('t/target/a/b/c','../../empty') ], + [ $stow->find_stowed_path("$OUT_DIR/target/a/b/c",'../../empty') ], [ '', '', '' ] => 'target is not stowed' ); -make_dir('t/target/stow2'); -make_file('t/target/stow2/.stow'); +make_dir("$OUT_DIR/target/stow2"); +make_file("$OUT_DIR/target/stow2/.stow"); is_deeply( - [ $stow->find_stowed_path('t/target/a/b/c','../../stow2/a/b/c') ], - [ 't/target/stow2/a/b/c', 't/target/stow2', 'a' ] + [ $stow->find_stowed_path("$OUT_DIR/target/a/b/c",'../../stow2/a/b/c') ], + [ "$OUT_DIR/target/stow2/a/b/c", "$OUT_DIR/target/stow2", 'a' ] => q(detect alternate stow directory) ); # Possible corner case with rogue symlink pointing to ancestor of # stow dir. is_deeply( - [ $stow->find_stowed_path('t/target/a/b/c','../../..') ], + [ $stow->find_stowed_path("$OUT_DIR/target/a/b/c",'../../..') ], [ '', '', '' ] => q(corner case - link points to ancestor of stow dir) ); diff --git a/t/foldable.t b/t/foldable.t index 1d0446f..ebb3b82 100755 --- a/t/foldable.t +++ b/t/foldable.t @@ -13,7 +13,7 @@ use Test::More tests => 4; use English qw(-no_match_vars); init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); my $stow = new_Stow(dir => '../stow'); diff --git a/t/ignore.t b/t/ignore.t index 5d23bba..83966fc 100755 --- a/t/ignore.t +++ b/t/ignore.t @@ -14,7 +14,7 @@ use testutil; use Stow::Util qw(join_paths); init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); my $stow = new_Stow(); diff --git a/t/stow.t b/t/stow.t index 7057378..c9a021d 100755 --- a/t/stow.t +++ b/t/stow.t @@ -17,15 +17,15 @@ init_test_dirs(); local @ARGV = ( '-v', - '-d t/stow', - '-t t/target', + "-d $OUT_DIR/stow", + "-t $OUT_DIR/target", 'dummy' ); my ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options(); is($options->{verbose}, 1, 'verbose option'); -is($options->{dir}, 't/stow', 'stow dir option'); +is($options->{dir}, "$OUT_DIR/stow", 'stow dir option'); my $stow = new_Stow(%$options); diff --git a/t/stow_contents.t b/t/stow_contents.t index 30cfa64..db0e9fc 100755 --- a/t/stow_contents.t +++ b/t/stow_contents.t @@ -15,7 +15,7 @@ use Stow::Util qw(canon_path); use testutil; init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); my $stow; my @conflicts; @@ -293,16 +293,16 @@ ok( # stow a simple tree minimally when cwd isn't target # cd('../..'); -$stow = new_Stow(dir => 't/stow', target => 't/target'); +$stow = new_Stow(dir => "$OUT_DIR/stow", target => "$OUT_DIR/target"); -make_dir('t/stow/pkg16/bin16'); -make_file('t/stow/pkg16/bin16/file16'); +make_dir("$OUT_DIR/stow/pkg16/bin16"); +make_file("$OUT_DIR/stow/pkg16/bin16/file16"); $stow->plan_stow('pkg16'); $stow->process_tasks(); is($stow->get_conflicts(), 0, 'no conflicts with minimal stow'); is( - readlink('t/target/bin16'), + readlink("$OUT_DIR/target/bin16"), '../stow/pkg16/bin16', => "minimal stow of a simple tree when cwd isn't target" ); @@ -311,17 +311,17 @@ is( # stow a simple tree minimally to absolute stow dir when cwd isn't # target # -$stow = new_Stow(dir => canon_path('t/stow'), - target => 't/target'); +$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), + target => "$OUT_DIR/target"); -make_dir('t/stow/pkg17/bin17'); -make_file('t/stow/pkg17/bin17/file17'); +make_dir("$OUT_DIR/stow/pkg17/bin17"); +make_file("$OUT_DIR/stow/pkg17/bin17/file17"); $stow->plan_stow('pkg17'); $stow->process_tasks(); is($stow->get_conflicts(), 0, 'no conflicts with minimal stow'); is( - readlink('t/target/bin17'), + readlink("$OUT_DIR/target/bin17"), '../stow/pkg17/bin17', => "minimal stow of a simple tree with absolute stow dir" ); @@ -330,17 +330,17 @@ is( # stow a simple tree minimally with absolute stow AND target dirs when # cwd isn't target # -$stow = new_Stow(dir => canon_path('t/stow'), - target => canon_path('t/target')); +$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), + target => canon_path("$OUT_DIR/target")); -make_dir('t/stow/pkg18/bin18'); -make_file('t/stow/pkg18/bin18/file18'); +make_dir("$OUT_DIR/stow/pkg18/bin18"); +make_file("$OUT_DIR/stow/pkg18/bin18/file18"); $stow->plan_stow('pkg18'); $stow->process_tasks(); is($stow->get_conflicts(), 0, 'no conflicts with minimal stow'); is( - readlink('t/target/bin18'), + readlink("$OUT_DIR/target/bin18"), '../stow/pkg18/bin18', => "minimal stow of a simple tree with absolute stow and target dirs" ); diff --git a/t/testutil.pm b/t/testutil.pm index 2efe72e..67d4f45 100755 --- a/t/testutil.pm +++ b/t/testutil.pm @@ -4,17 +4,28 @@ # Utilities shared by test scripts # +package testutil; + use strict; use warnings; use Stow; -use Stow::Util qw(parent); +use Stow::Util qw(parent canon_path); + +use base qw(Exporter); +our @EXPORT = qw( + $OUT_DIR + init_test_dirs + cd + new_Stow new_compat_Stow + make_dir make_link make_file + remove_dir remove_link +); + +our $OUT_DIR = 'tmp-testing-trees'; sub init_test_dirs { - die "t/ didn't exist; are you running the tests from the root of the tree?\n" - unless -d 't'; - - for my $dir ('t/target', 't/stow') { + for my $dir ("$OUT_DIR/target", "$OUT_DIR/stow") { -d $dir and remove_dir($dir); make_dir($dir); } diff --git a/t/unstow_contents.t b/t/unstow_contents.t index 45ad7d6..6929a03 100755 --- a/t/unstow_contents.t +++ b/t/unstow_contents.t @@ -15,7 +15,7 @@ use testutil; use Stow::Util qw(canon_path); init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); # Note that each of the following tests use a distinct set of files @@ -273,8 +273,8 @@ ok( # Unstow a never stowed package # -eval { remove_dir('t/target'); }; -mkdir('t/target'); +eval { remove_dir("$OUT_DIR/target"); }; +mkdir("$OUT_DIR/target"); $stow = new_Stow(); $stow->plan_unstow('pkg12'); @@ -311,17 +311,17 @@ ok( # unstow a simple tree minimally when cwd isn't target # cd('../..'); -$stow = new_Stow(dir => 't/stow', target => 't/target'); +$stow = new_Stow(dir => "$OUT_DIR/stow", target => "$OUT_DIR/target"); -make_dir('t/stow/pkg13/bin13'); -make_file('t/stow/pkg13/bin13/file13'); -make_link('t/target/bin13', '../stow/pkg13/bin13'); +make_dir("$OUT_DIR/stow/pkg13/bin13"); +make_file("$OUT_DIR/stow/pkg13/bin13/file13"); +make_link("$OUT_DIR/target/bin13", '../stow/pkg13/bin13'); $stow->plan_unstow('pkg13'); $stow->process_tasks(); ok( scalar($stow->get_conflicts) == 0 && - -f 't/stow/pkg13/bin13/file13' && ! -e 't/target/bin13' + -f "$OUT_DIR/stow/pkg13/bin13/file13" && ! -e "$OUT_DIR/target/bin13" => 'unstow a simple tree' ); @@ -329,18 +329,18 @@ ok( # unstow a simple tree minimally with absolute stow dir when cwd isn't # target # -$stow = new_Stow(dir => canon_path('t/stow'), - target => 't/target'); +$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), + target => "$OUT_DIR/target"); -make_dir('t/stow/pkg14/bin14'); -make_file('t/stow/pkg14/bin14/file14'); -make_link('t/target/bin14', '../stow/pkg14/bin14'); +make_dir("$OUT_DIR/stow/pkg14/bin14"); +make_file("$OUT_DIR/stow/pkg14/bin14/file14"); +make_link("$OUT_DIR/target/bin14", '../stow/pkg14/bin14'); $stow->plan_unstow('pkg14'); $stow->process_tasks(); ok( scalar($stow->get_conflicts) == 0 && - -f 't/stow/pkg14/bin14/file14' && ! -e 't/target/bin14' + -f "$OUT_DIR/stow/pkg14/bin14/file14" && ! -e "$OUT_DIR/target/bin14" => 'unstow a simple tree with absolute stow dir' ); @@ -348,18 +348,18 @@ ok( # unstow a simple tree minimally with absolute stow AND target dirs # when cwd isn't target # -$stow = new_Stow(dir => canon_path('t/stow'), - target => canon_path('t/target')); +$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), + target => canon_path("$OUT_DIR/target")); -make_dir('t/stow/pkg15/bin15'); -make_file('t/stow/pkg15/bin15/file15'); -make_link('t/target/bin15', '../stow/pkg15/bin15'); +make_dir("$OUT_DIR/stow/pkg15/bin15"); +make_file("$OUT_DIR/stow/pkg15/bin15/file15"); +make_link("$OUT_DIR/target/bin15", '../stow/pkg15/bin15'); $stow->plan_unstow('pkg15'); $stow->process_tasks(); ok( scalar($stow->get_conflicts) == 0 && - -f 't/stow/pkg15/bin15/file15' && ! -e 't/target/bin15' + -f "$OUT_DIR/stow/pkg15/bin15/file15" && ! -e "$OUT_DIR/target/bin15" => 'unstow a simple tree with absolute stow and target dirs' ); diff --git a/t/unstow_contents_orig.t b/t/unstow_contents_orig.t index 61b1a45..ec86dac 100755 --- a/t/unstow_contents_orig.t +++ b/t/unstow_contents_orig.t @@ -15,7 +15,7 @@ use testutil; use Stow::Util qw(canon_path); init_test_dirs(); -cd('t/target'); +cd("$OUT_DIR/target"); # Note that each of the following tests use a distinct set of files @@ -280,8 +280,8 @@ ok( # Unstow a never stowed package # -eval { remove_dir('t/target'); }; -mkdir('t/target'); +eval { remove_dir("$OUT_DIR/target"); }; +mkdir("$OUT_DIR/target"); $stow = new_compat_Stow(); $stow->plan_unstow('pkg12'); @@ -318,17 +318,17 @@ ok( # unstow a simple tree minimally when cwd isn't target # cd('../..'); -$stow = new_Stow(dir => 't/stow', target => 't/target'); +$stow = new_Stow(dir => "$OUT_DIR/stow", target => "$OUT_DIR/target"); -make_dir('t/stow/pkg13/bin13'); -make_file('t/stow/pkg13/bin13/file13'); -make_link('t/target/bin13', '../stow/pkg13/bin13'); +make_dir("$OUT_DIR/stow/pkg13/bin13"); +make_file("$OUT_DIR/stow/pkg13/bin13/file13"); +make_link("$OUT_DIR/target/bin13", '../stow/pkg13/bin13'); $stow->plan_unstow('pkg13'); $stow->process_tasks(); ok( scalar($stow->get_conflicts) == 0 && - -f 't/stow/pkg13/bin13/file13' && ! -e 't/target/bin13' + -f "$OUT_DIR/stow/pkg13/bin13/file13" && ! -e "$OUT_DIR/target/bin13" => 'unstow a simple tree' ); @@ -336,18 +336,18 @@ ok( # unstow a simple tree minimally with absolute stow dir when cwd isn't # target # -$stow = new_Stow(dir => canon_path('t/stow'), - target => 't/target'); +$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), + target => "$OUT_DIR/target"); -make_dir('t/stow/pkg14/bin14'); -make_file('t/stow/pkg14/bin14/file14'); -make_link('t/target/bin14', '../stow/pkg14/bin14'); +make_dir("$OUT_DIR/stow/pkg14/bin14"); +make_file("$OUT_DIR/stow/pkg14/bin14/file14"); +make_link("$OUT_DIR/target/bin14", '../stow/pkg14/bin14'); $stow->plan_unstow('pkg14'); $stow->process_tasks(); ok( scalar($stow->get_conflicts) == 0 && - -f 't/stow/pkg14/bin14/file14' && ! -e 't/target/bin14' + -f "$OUT_DIR/stow/pkg14/bin14/file14" && ! -e "$OUT_DIR/target/bin14" => 'unstow a simple tree with absolute stow dir' ); @@ -355,18 +355,18 @@ ok( # unstow a simple tree minimally with absolute stow AND target dirs # when cwd isn't target # -$stow = new_Stow(dir => canon_path('t/stow'), - target => canon_path('t/target')); +$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), + target => canon_path("$OUT_DIR/target")); -make_dir('t/stow/pkg15/bin15'); -make_file('t/stow/pkg15/bin15/file15'); -make_link('t/target/bin15', '../stow/pkg15/bin15'); +make_dir("$OUT_DIR/stow/pkg15/bin15"); +make_file("$OUT_DIR/stow/pkg15/bin15/file15"); +make_link("$OUT_DIR/target/bin15", '../stow/pkg15/bin15'); $stow->plan_unstow('pkg15'); $stow->process_tasks(); ok( scalar($stow->get_conflicts) == 0 && - -f 't/stow/pkg15/bin15/file15' && ! -e 't/target/bin15' + -f "$OUT_DIR/stow/pkg15/bin15/file15" && ! -e "$OUT_DIR/target/bin15" => 'unstow a simple tree with absolute stow and target dirs' );