Merge lp:~aaron-whitehouse/duplicity/filelist_combine into lp:~duplicity-team/duplicity/0.7-series

Proposed by Aaron Whitehouse
Status: Merged
Merged at revision: 1081
Proposed branch: lp:~aaron-whitehouse/duplicity/filelist_combine
Merge into: lp:~duplicity-team/duplicity/0.7-series
Diff against target: 2740 lines (+683/-919)
7 files modified
bin/duplicity.1 (+20/-82)
duplicity/commandline.py (+27/-4)
duplicity/selection.py (+27/-128)
po/duplicity.pot (+99/-106)
testing/functional/test_selection.py (+203/-193)
testing/stdin_test.sh (+203/-0)
testing/unit/test_selection.py (+104/-406)
To merge this branch: bzr merge lp:~aaron-whitehouse/duplicity/filelist_combine
Reviewer Review Type Date Requested Status
duplicity-team Pending
Review via email: mp+252814@code.launchpad.net

Description of the change

Merged globbing and non-globbing filelists to use the same code path and all accept globbing characters. Added deprecation warning to the --exclude-globbing-filelist and include-globbing-filelist options in commandline.py and hid them from help output. Updated the manual (and unit tests) accordingly.

Note that this does trigger a change in behaviour for duplicity. Previously, include patterns in include-filelist did not match files in a directory that was included, so /usr/local in an include file would not have matched /usr/local/doc. Now, this folder would be included, as would occur if --include or the old --include-globbing-filelist was used. Additional lines will therefore need to be added to filelists to unambiguously exclude unwanted subfolders, if this is intended.

Mark --include-filelist-stdin and --exclude-fielist-stdin for deprecation and hide from --help output.

To post a comment you must log in.
Revision history for this message
edso (ed.so) wrote :

three point

1. wouldn't it make sense to either depreciate in-/exclude or in/exclude-globbing as they afre functional identical

2. not sure if we should want to have keep the old non-globbing selection for simple setups. easier to understand and done.

3. your branch clashes with the current dev branch. you probably need to rebase your changes.

..ede/duply.net

Revision history for this message
Kenneth Loafman (kenneth-loafman) wrote :

1. He deprecated the in/exclude-globbing-filelist and folded that
functionality into in/exclude-filelist.

2. We talked about this on the mailing list. This simplifies the number of
options we deal with and in general should make life easier. If you don't
use globbing, the selection should be simple still.

3. Yes, should have started with the current code for the merge.

On Thu, Mar 12, 2015 at 2:44 PM, edso <email address hidden> wrote:

> three point
>
> 1. wouldn't it make sense to either depreciate in-/exclude or
> in/exclude-globbing as they afre functional identical
>
> 2. not sure if we should want to have keep the old non-globbing selection
> for simple setups. easier to understand and done.
>
> 3. your branch clashes with the current dev branch. you probably need to
> rebase your changes.
>
> ..ede/duply.net
>
>
> --
>
> https://code.launchpad.net/~aaron-whitehouse/duplicity/filelist_combine/+merge/252814
> You are subscribed to branch lp:duplicity.
>

Revision history for this message
edso (ed.so) wrote :

1. so in/exclude-globbing* is retired now?

2. right, but '/folder' is different from '/folder/**' now, although they might be perceived identical by a user. why not fold the whole way and only have one globbing filelist '--filelist' parameter which uses '+/-' to identify the rows as we had them already.

the reasons are
- simplification
- with the meaning change old filelists won't work the same way as before anymore, so a complete new parameter would force users to chack what has changed

of course the change needs to be documented properly in the manpage too.

3. jepp

..ede/duply.net

1076. By Aaron Whitehouse <email address hidden>

Merge in changes to rebase against dev.

1077. By Aaron Whitehouse <email address hidden>

Updated duplicity.pot

Revision history for this message
Aaron Whitehouse (aaron-whitehouse) wrote :

Sorry about the conflict. I thought I had, but was updating against a branch instead of the dev branch - I'm still getting the hang of bzr. Next time I'll know to check the information on the merge page. Hopefully I've rebased it in the correct way, but please let me know if not.

Kenneth is right, I folded the functionality of globbing filelists into non-globbing filelists. What is called --include-filelist is what used to be --include-globbing-filelist, but I went for the shorter name. So it is the old --in/exclude-filelist functionality that has been removed.

I'm not sure that I follow your point that /folder is different from /folder/** now - do you mean that they are prior to the merge, or will be after the merge? Would you mind explaining a little further, please?

I was basing my view that there would be a functionality change on the manual, but in testing the current version (prior to this merge), I'm not sure that it works as I thought it did. The code below works on the current dev version, suggesting to me that at least in the case I've tested they are including the same things (which is all files and subfolders).

class TestOldInclude
    def test_old_style_include(self):
        """This compares a backup using --include-filelist with one using --include-globbing-filelist."""
        with open("testfiles/filelist.txt", 'w') as f:
            f.write("+ testfiles/select2\n"
                    "- testfiles/select")
        self.backup("full", "testfiles/", options=["--include-filelist=testfiles/filelist.txt"])
        self.restore()
        restore_dir = 'testfiles/restore_out'
        restored = self.directory_tree_to_list_of_lists(restore_dir + "/select2")
        self.backup("full", "testfiles/", options=["--include-globbing-filelist=testfiles/filelist.txt"])
        self.restore()
        restore_dir = 'testfiles/restore_out'
        restored2 = self.directory_tree_to_list_of_lists(restore_dir + "/select2")
        self.assertEqual(restored, restored2)
        print(restored)

I also just had a play around on my system version (0.6.21) to investigate the point from the manual:
"2. Include patterns do not match files in a directory that is included. So /usr/local in an include file will not match /usr/local/doc"

I created a test tree of:
===
usr:
clown local

usr/clown:

usr/local:
doc test1 test.txt

usr/local/doc:

usr/local/test1:
===

and a filelist of:
usr/local
- usr/clown

and ran:
duplicity --include-filelist=filelist.txt usr file://des/

On restoring it, my restore filetree is:
===
restore/:
local

restore/local:
doc test1 test.txt

restore/local/doc:

restore/local/test1:
===

So usr/local in my include file _does_ in fact include the file usr/local/doc in my backup.

Maybe I'm missing the point of what it was supposed to do differently, but obviously if it wasn't actually doing it, we don't need to worry about a functionality change. I would appreciate any thoughts that you have from your much greater knowledge of the code/project!

Revision history for this message
Kenneth Loafman (kenneth-loafman) wrote :

One of the reasons for --include / --exclude is the default handling for
non-specific names, ones without + or -, say the output of find or similar,
so I'm happy with that scenario. A lot of tools I use have similar
semantics.

One set of semantics I would like to explore is to do away with
--in/exclude-filename and go with just --in/exclude <spec> where <spec> is:
1) simple filename or directory name
2) @filename to in/exclude by filename
3) - (dash) to in/exclude by stdin

To answer edso's next proposal we could make it --filename if we went with
--filename <spec> where <spec> is like above but preceded by '+' for
inclusion and '-' for exclusion. To avoid confusion we could always drop
#3 above. I know of no use for that option in real life.

On Fri, Mar 13, 2015 at 7:22 AM, <email address hidden> wrote:

> The proposal to merge lp:~aaron-whitehouse/duplicity/filelist_combine into
> lp:duplicity has been updated.
>
> Status: Needs review => Merged
>
> For more details, see:
>
> https://code.launchpad.net/~aaron-whitehouse/duplicity/filelist_combine/+merge/252814
> --
> Your team duplicity-team is requested to review the proposed merge of
> lp:~aaron-whitehouse/duplicity/filelist_combine into lp:duplicity.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~duplicity-team
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~duplicity-team
> More help : https://help.launchpad.net/ListHelp
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bin/duplicity.1'
--- bin/duplicity.1 2015-02-08 16:43:23 +0000
+++ bin/duplicity.1 2015-03-12 21:50:57 +0000
@@ -481,28 +481,15 @@
481.TP481.TP
482.BI "--exclude-filelist " filename482.BI "--exclude-filelist " filename
483Excludes the files listed in483Excludes the files listed in
484.IR filename .484.IR filename,
485See the485with each line of the filelist interpreted according to the
486.B FILE SELECTION
487section for more information.
488
489.TP
490.BI --exclude-filelist-stdin
491Like
492.BI --exclude-filelist,
493but the list of files will be read from standard input. See the
494.B FILE SELECTION
495section for more information.
496
497.TP
498.BR "--exclude-globbing-filelist " filename
499Like
500.BI --exclude-filelist
501but each line of the filelist will be interpreted according to the
502same rules as486same rules as
503.BI --include487.BI --include
504and488and
505.BI --exclude.489.BI --exclude.
490See the
491.B FILE SELECTION
492section for more information.
506493
507.TP494.TP
508.BR "--exclude-if-present " filename495.BR "--exclude-if-present " filename
@@ -663,22 +650,6 @@
663section for more information.650section for more information.
664651
665.TP652.TP
666.BI --include-filelist-stdin
667Like
668.BR --include-filelist ,
669but read the list of included files from standard input.
670
671.TP
672.BI "--include-globbing-filelist " filename
673Like
674.BI --include-filelist
675but each line of the filelist will be interpreted according to the
676same rules as
677.BI --include
678and
679.BI --exclude.
680
681.TP
682.BI "--include-regexp " regexp653.BI "--include-regexp " regexp
683Include files matching the regular expression654Include files matching the regular expression
684.IR regexp .655.IR regexp .
@@ -746,7 +717,7 @@
746Use nulls (\\0) instead of newlines (\\n) as line separators, which717Use nulls (\\0) instead of newlines (\\n) as line separators, which
747may help when dealing with filenames containing newlines. This718may help when dealing with filenames containing newlines. This
748affects the expected format of the files specified by the719affects the expected format of the files specified by the
749--{include|exclude}-filelist[-stdin] switches as well as the format of720--{include|exclude}-filelist switches as well as the format of
750the directory statistics file.721the directory statistics file.
751722
752.TP723.TP
@@ -1337,10 +1308,6 @@
1337"03-05-2002", and "2002-3-05" all mean March 5th, 2002.1308"03-05-2002", and "2002-3-05" all mean March 5th, 2002.
13381309
1339.SH FILE SELECTION1310.SH FILE SELECTION
1340duplicity accepts the same file selection options
1341.B rdiff-backup
1342does, including --exclude, --exclude-filelist-stdin, etc.
1343
1344When duplicity is run, it searches through the given source1311When duplicity is run, it searches through the given source
1345directory and backs up all the files specified by the file selection1312directory and backs up all the files specified by the file selection
1346system. The file selection system comprises a number of file1313system. The file selection system comprises a number of file
@@ -1353,20 +1320,12 @@
1353.br1320.br
1354--exclude-filelist1321--exclude-filelist
1355.br1322.br
1356--exclude-filelist-stdin
1357.br
1358--exclude-globbing-filelist
1359.br
1360--exclude-regexp1323--exclude-regexp
1361.br1324.br
1362--include1325--include
1363.br1326.br
1364--include-filelist1327--include-filelist
1365.br1328.br
1366--include-filelist-stdin
1367.br
1368--include-globbing-filelist
1369.br
1370--include-regexp1329--include-regexp
1371.RE1330.RE
1372Each file selection condition either matches or doesn't match a given1331Each file selection condition either matches or doesn't match a given
@@ -1402,9 +1361,9 @@
1402The1361The
1403.BR include ,1362.BR include ,
1404.BR exclude ,1363.BR exclude ,
1405.BR include-globbing-filelist ,1364.BR include-filelist ,
1406and1365and
1407.B exclude-globbing-filelist1366.B exclude-filelist
1408options accept some1367options accept some
1409.IR "extended shell globbing patterns" .1368.IR "extended shell globbing patterns" .
1410These patterns can contain1369These patterns can contain
@@ -1493,34 +1452,18 @@
14931452
1494The1453The
1495.BR --include-filelist ,1454.BR --include-filelist ,
1496.BR --exclude-filelist ,
1497.BR --include-filelist-stdin ,
1498and1455and
1499.BI --exclude-filelist-stdin1456.BI --exclude-filelist ,
1500options also introduce file selection conditions. They direct1457options also introduce file selection conditions. They direct
1501duplicity to read in a file, each line of which is a file1458duplicity to read in a file, each line of which is a file
1502specification, and to include or exclude the matching files. Lines1459specification, and to include or exclude the matching files. Lines
1503are separated by newlines or nulls, depending on whether the1460are separated by newlines or nulls, depending on whether the
1504--null-separator switch was given. Each line in a filelist is1461--null-separator switch was given. Each line in the filelist will be
1505interpreted similarly to the way1462interpreted as a globbing pattern the way
1506.I extended shell patterns1463.BI --include
1507are, with a few exceptions:
1508.PP
1509.B 1.
1510Globbing patterns like
1511.BR * ,
1512.BR ** ,
1513.BR ? ,
1514and1464and
1515.B [...]1465.BI --exclude
1516are not expanded.1466options are interpreted, except that lines starting with "+ " are interpreted as include directives, even
1517.br
1518.B 2.
1519Include patterns do not match files in a directory that is included.
1520So /usr/local in an include file will not match /usr/local/doc.
1521.br
1522.B 3.
1523Lines starting with "+ " are interpreted as include directives, even
1524if found in a filelist referenced by1467if found in a filelist referenced by
1525.BR --exclude-filelist .1468.BR --exclude-filelist .
1526Similarly, lines starting with "- " exclude files even if they are1469Similarly, lines starting with "- " exclude files even if they are
@@ -1544,23 +1487,18 @@
1544.B "--include-filelist list.txt"1487.B "--include-filelist list.txt"
1545would include /usr, /usr/local, and1488would include /usr, /usr/local, and
1546/usr/local/bin. It would exclude /usr/local/doc,1489/usr/local/bin. It would exclude /usr/local/doc,
1547/usr/local/doc/python, etc. It neither excludes nor includes1490/usr/local/doc/python, etc. It would also include
1548/usr/local/man, leaving the fate of this directory to the next1491/usr/local/man, as this is included within /user/local. Finally, it is undefined what happens with
1549specification condition. Finally, it is undefined what happens with
1550/var. A single file list should not contain conflicting file1492/var. A single file list should not contain conflicting file
1551specifications.1493specifications.
15521494
1553The1495Each line in the filelist will also be
1554.BI --include-globbing-filelist
1555and
1556.BI --exclude-globbing-filelist
1557options also specify filelists, but each line in the filelist will be
1558interpreted as a globbing pattern the way1496interpreted as a globbing pattern the way
1559.BI --include1497.BI --include
1560and1498and
1561.BI --exclude1499.BI --exclude
1562options are interpreted (although "+ " and "- " prefixing is still1500options are interpreted.
1563allowed). For instance, if the file "globbing-list.txt" contains the1501For instance, if the file "list.txt" contains the
1564lines:1502lines:
15651503
1566.RS1504.RS
@@ -1572,7 +1510,7 @@
1572.RE1510.RE
15731511
1574Then1512Then
1575.B "--include-globbing-filelist globbing-list.txt"1513.B "--include-filelist list.txt"
1576would be exactly the same as specifying1514would be exactly the same as specifying
1577.B "--include dir/foo --include dir/bar --exclude **"1515.B "--include dir/foo --include dir/bar --exclude **"
1578on the command line.1516on the command line.
15791517
=== modified file 'duplicity/commandline.py'
--- duplicity/commandline.py 2015-01-31 23:30:49 +0000
+++ duplicity/commandline.py 2015-03-12 21:50:57 +0000
@@ -73,6 +73,21 @@
73 "Use of default filenames is strongly suggested.") % opt,73 "Use of default filenames is strongly suggested.") % opt,
74 log.ERROR, force_print=True)74 log.ERROR, force_print=True)
7575
76def old_globbing_filelist_deprecation(opt):
77 log.Log(_("Warning: Option %s is pending deprecation and will be removed in a future release.\n"
78 "--include-filelist and --exclude-filelist now accept globbing characters and should "
79 "be used instead.") % opt,
80 log.ERROR, force_print=True)
81
82def stdin_deprecation(opt):
83 # See https://bugs.launchpad.net/duplicity/+bug/1423367
84 # In almost all Linux distros stdin is a file represented by /dev/stdin,
85 # so --exclude-file=/dev/stdin will work as a substitute.
86 log.Log(_("Warning: Option %s is pending deprecation and will be removed in a future release.\n"
87 "On many GNU/Linux systems, stdin is represented by /dev/stdin and\n"
88 "--include-filelist=/dev/stdin or --exclude-filelist=/dev/stdin could\n"
89 "be used as a substitute.") % opt,
90 log.ERROR, force_print=True)
7691
77def expand_fn(filename):92def expand_fn(filename):
78 return os.path.expanduser(os.path.expandvars(filename))93 return os.path.expanduser(os.path.expandvars(filename))
@@ -307,10 +322,14 @@
307322
308 parser.add_option("--exclude-filelist-stdin", action="callback", dest="",323 parser.add_option("--exclude-filelist-stdin", action="callback", dest="",
309 callback=lambda o, s, v, p: (select_opts.append(("--exclude-filelist", "standard input")),324 callback=lambda o, s, v, p: (select_opts.append(("--exclude-filelist", "standard input")),
310 select_files.append(sys.stdin)))325 select_files.append(sys.stdin),
326 stdin_deprecation(o)),
327 help=optparse.SUPPRESS_HELP)
311328
312 parser.add_option("--exclude-globbing-filelist", type="file", metavar=_("filename"),329 parser.add_option("--exclude-globbing-filelist", type="file", metavar=_("filename"),
313 dest="", action="callback", callback=add_filelist)330 dest="", action="callback", callback=lambda o, s, v, p: (add_filelist(o, s, v, p),
331 old_globbing_filelist_deprecation(s)),
332 help=optparse.SUPPRESS_HELP)
314333
315 # TRANSL: Used in usage help to represent the name of a file. Example:334 # TRANSL: Used in usage help to represent the name of a file. Example:
316 # --log-file <filename>335 # --log-file <filename>
@@ -409,9 +428,13 @@
409 dest="", action="callback", callback=add_filelist)428 dest="", action="callback", callback=add_filelist)
410 parser.add_option("--include-filelist-stdin", action="callback", dest="",429 parser.add_option("--include-filelist-stdin", action="callback", dest="",
411 callback=lambda o, s, v, p: (select_opts.append(("--include-filelist", "standard input")),430 callback=lambda o, s, v, p: (select_opts.append(("--include-filelist", "standard input")),
412 select_files.append(sys.stdin)))431 select_files.append(sys.stdin),
432 stdin_deprecation(o)),
433 help=optparse.SUPPRESS_HELP)
413 parser.add_option("--include-globbing-filelist", type="file", metavar=_("filename"),434 parser.add_option("--include-globbing-filelist", type="file", metavar=_("filename"),
414 dest="", action="callback", callback=add_filelist)435 dest="", action="callback", callback=lambda o, s, v, p: (add_filelist(o, s, v, p),
436 old_globbing_filelist_deprecation(s)),
437 help=optparse.SUPPRESS_HELP)
415 parser.add_option("--include-regexp", metavar=_("regular_expression"), dest="",438 parser.add_option("--include-regexp", metavar=_("regular_expression"), dest="",
416 type="string", action="callback", callback=add_selection)439 type="string", action="callback", callback=add_selection)
417440
418441
=== modified file 'duplicity/selection.py'
--- duplicity/selection.py 2015-01-31 23:30:49 +0000
+++ duplicity/selection.py 2015-03-12 21:50:57 +0000
@@ -102,6 +102,7 @@
102102
103 def set_iter(self):103 def set_iter(self):
104 """Initialize generator, prepare to iterate."""104 """Initialize generator, prepare to iterate."""
105 # Externally-accessed method
105 self.rootpath.setdata() # this may have changed since Select init106 self.rootpath.setdata() # this may have changed since Select init
106 self.iter = self.Iterate(self.rootpath)107 self.iter = self.Iterate(self.rootpath)
107 self.next = self.iter.next108 self.next = self.iter.next
@@ -117,6 +118,7 @@
117 scanning" bit.118 scanning" bit.
118119
119 """120 """
121 # Only called by set_iter. Internal.
120 def error_handler(exc, path, filename):122 def error_handler(exc, path, filename):
121 fullpath = os.path.join(path.name, filename)123 fullpath = os.path.join(path.name, filename)
122 try:124 try:
@@ -143,6 +145,7 @@
143 and should be included iff something inside is included.145 and should be included iff something inside is included.
144146
145 """147 """
148 # Only called by Iterate. Internal.
146 # todo: get around circular dependency issue by importing here149 # todo: get around circular dependency issue by importing here
147 from duplicity import robust # @Reimport150 from duplicity import robust # @Reimport
148 for filename in robust.listpath(path):151 for filename in robust.listpath(path):
@@ -200,6 +203,7 @@
200203
201 def Select(self, path):204 def Select(self, path):
202 """Run through the selection functions and return dominant val 0/1/2"""205 """Run through the selection functions and return dominant val 0/1/2"""
206 # Only used by diryield and tests. Internal.
203 if not self.selection_functions:207 if not self.selection_functions:
204 return 1208 return 1
205 scan_pending = False209 scan_pending = False
@@ -227,6 +231,7 @@
227 (option-string, (additional argument, filelist_fp)).231 (option-string, (additional argument, filelist_fp)).
228232
229 """233 """
234 # Called by commandline.py set_selection. External.
230 filelists_index = 0235 filelists_index = 0
231 try:236 try:
232 for opt, arg in argtuples:237 for opt, arg in argtuples:
@@ -236,11 +241,9 @@
236 self.add_selection_func(self.present_get_sf(arg, 0))241 self.add_selection_func(self.present_get_sf(arg, 0))
237 elif opt == "--exclude-device-files":242 elif opt == "--exclude-device-files":
238 self.add_selection_func(self.devfiles_get_sf())243 self.add_selection_func(self.devfiles_get_sf())
239 elif opt == "--exclude-filelist":244 elif (opt == "--exclude-filelist") or (opt == "--exclude-globbing-filelist"):
240 self.add_selection_func(self.filelist_get_sf(245 # --exclude-globbing-filelist is now deprecated, as all filelists are globbing
241 filelists[filelists_index], 0, arg))246 # but keep this here for the short term for backwards-compatibility
242 filelists_index += 1
243 elif opt == "--exclude-globbing-filelist":
244 for sf in self.filelist_globbing_get_sfs(filelists[filelists_index], 0, arg):247 for sf in self.filelist_globbing_get_sfs(filelists[filelists_index], 0, arg):
245 self.add_selection_func(sf)248 self.add_selection_func(sf)
246 filelists_index += 1249 filelists_index += 1
@@ -252,11 +255,9 @@
252 self.add_selection_func(self.exclude_older_get_sf(arg))255 self.add_selection_func(self.exclude_older_get_sf(arg))
253 elif opt == "--include":256 elif opt == "--include":
254 self.add_selection_func(self.glob_get_sf(arg, 1))257 self.add_selection_func(self.glob_get_sf(arg, 1))
255 elif opt == "--include-filelist":258 elif (opt == "--include-filelist") or (opt == "--include-globbing-filelist"):
256 self.add_selection_func(self.filelist_get_sf(259 # --include-globbing-filelist is now deprecated, as all filelists are globbing
257 filelists[filelists_index], 1, arg))260 # but keep this here for the short term for backwards-compatibility
258 filelists_index += 1
259 elif opt == "--include-globbing-filelist":
260 for sf in self.filelist_globbing_get_sfs(filelists[filelists_index], 1, arg):261 for sf in self.filelist_globbing_get_sfs(filelists[filelists_index], 1, arg):
261 self.add_selection_func(sf)262 self.add_selection_func(sf)
262 filelists_index += 1263 filelists_index += 1
@@ -271,6 +272,7 @@
271272
272 def parse_catch_error(self, exc):273 def parse_catch_error(self, exc):
273 """Deal with selection error exc"""274 """Deal with selection error exc"""
275 # Internal, used by ParseArgs.
274 if isinstance(exc, FilePrefixError):276 if isinstance(exc, FilePrefixError):
275 log.FatalError(_("""\277 log.FatalError(_("""\
276Fatal Error: The file specification278Fatal Error: The file specification
@@ -288,6 +290,7 @@
288290
289 def parse_last_excludes(self):291 def parse_last_excludes(self):
290 """Exit with error if last selection function isn't an exclude"""292 """Exit with error if last selection function isn't an exclude"""
293 # Internal. Used by ParseArgs.
291 if (self.selection_functions and294 if (self.selection_functions and
292 not self.selection_functions[-1].exclude):295 not self.selection_functions[-1].exclude):
293 log.FatalError(_("""\296 log.FatalError(_("""\
@@ -301,76 +304,12 @@
301304
302 def add_selection_func(self, sel_func, add_to_start=None):305 def add_selection_func(self, sel_func, add_to_start=None):
303 """Add another selection function at the end or beginning"""306 """Add another selection function at the end or beginning"""
307 # Internal. Used by ParseArgs.
304 if add_to_start:308 if add_to_start:
305 self.selection_functions.insert(0, sel_func)309 self.selection_functions.insert(0, sel_func)
306 else:310 else:
307 self.selection_functions.append(sel_func)311 self.selection_functions.append(sel_func)
308312
309 def filelist_get_sf(self, filelist_fp, inc_default, filelist_name):
310 """Return selection function by reading list of files
311
312 The format of the filelist is documented in the man page.
313 filelist_fp should be an (open) file object.
314 inc_default should be true if this is an include list,
315 false for an exclude list.
316 filelist_name is just a string used for logging.
317
318 """
319 log.Notice(_("Reading filelist %s") % filelist_name)
320 tuple_list, something_excluded = \
321 self.filelist_read(filelist_fp, inc_default, filelist_name)
322 log.Notice(_("Sorting filelist %s") % filelist_name)
323 tuple_list.sort()
324 i = [0] # We have to put index in list because of stupid scoping rules
325
326 def selection_function(path):
327 while 1:
328 if i[0] >= len(tuple_list):
329 return None
330 include, move_on = \
331 self.filelist_pair_match(path, tuple_list[i[0]])
332 if move_on:
333 i[0] += 1
334 if include is None:
335 continue # later line may match
336 return include
337
338 selection_function.exclude = something_excluded or inc_default == 0
339 selection_function.name = "Filelist: " + filelist_name
340 return selection_function
341
342 def filelist_read(self, filelist_fp, include, filelist_name):
343 """Read filelist from fp, return (tuplelist, something_excluded)"""
344 prefix_warnings = [0]
345
346 def incr_warnings(exc):
347 """Warn if prefix is incorrect"""
348 prefix_warnings[0] += 1
349 if prefix_warnings[0] < 6:
350 log.Warn(_("Warning: file specification '%s' in filelist %s\n"
351 "doesn't start with correct prefix %s. Ignoring.") %
352 (exc, filelist_name, util.ufn(self.prefix)))
353 if prefix_warnings[0] == 5:
354 log.Warn(_("Future prefix errors will not be logged."))
355
356 something_excluded, tuple_list = None, []
357 separator = globals.null_separator and "\0" or "\n"
358 for line in filelist_fp.read().split(separator):
359 try:
360 tuple = self.filelist_parse_line(line, include)
361 except FilePrefixError as exc:
362 incr_warnings(exc)
363 continue
364 if not tuple:
365 # Skip blanks/full-line comments
366 continue
367 else:
368 tuple_list.append(tuple)
369 if not tuple[1]:
370 something_excluded = 1
371 if filelist_fp not in (sys.stdin,) and filelist_fp.close():
372 log.Warn(_("Error closing filelist %s") % filelist_name)
373 return (tuple_list, something_excluded)
374313
375 def filelist_sanitise_line(self, line, include_default):314 def filelist_sanitise_line(self, line, include_default):
376 """315 """
@@ -379,6 +318,7 @@
379 The aim is to parse filelists in a consistent way, prior to the interpretation of globbing statements.318 The aim is to parse filelists in a consistent way, prior to the interpretation of globbing statements.
380 The function removes whitespace, comment lines and processes modifiers (leading +/-) and quotes.319 The function removes whitespace, comment lines and processes modifiers (leading +/-) and quotes.
381 """320 """
321 # Internal. Used by filelist_globbing_get_sfs
382322
383 line = line.strip()323 line = line.strip()
384 if not line: # skip blanks324 if not line: # skip blanks
@@ -400,59 +340,6 @@
400340
401 return line, include341 return line, include
402342
403 def filelist_parse_line(self, line, include):
404 """Parse a single line of a filelist, returning a pair or None if the line is blank/a comment
405
406 Pair will be of form (index, include), where index is another
407 tuple, and include is 1 if the line specifies that we are
408 including a file. The default is given as an argument.
409 prefix is the string that the index is relative to.
410
411 """
412
413 line, include = self.filelist_sanitise_line(line, include)
414
415 if not line:
416 # Skip blanks and comments
417 return None
418
419 if not line.startswith(self.prefix):
420 raise FilePrefixError(line)
421 line = line[len(self.prefix):] # Discard prefix
422 index = tuple(filter(lambda x: x, line.split("/"))) # remove empties
423 return (index, include)
424
425 def filelist_pair_match(self, path, pair):
426 """Matches a filelist tuple against a path
427
428 Returns a pair (include, move_on). include is None if the
429 tuple doesn't match either way, and 0/1 if the tuple excludes
430 or includes the path.
431
432 move_on is true if the tuple cannot match a later index, and
433 so we should move on to the next tuple in the index.
434
435 """
436 index, include = pair
437 if include == 1:
438 if index < path.index:
439 return (None, True)
440 if index == path.index:
441 return (1, True)
442 elif index[:len(path.index)] == path.index:
443 return (1, False) # /foo/bar implicitly includes /foo
444 else:
445 return (None, False) # path greater, not initial sequence
446 elif include == 0:
447 if path.index[:len(index)] == index:
448 return (0, False) # /foo implicitly excludes /foo/bar
449 elif index < path.index:
450 return (None, True)
451 else:
452 return (None, False) # path greater, not initial sequence
453 else:
454 assert 0, "Include is %s, should be 0 or 1" % (include,)
455
456 def filelist_globbing_get_sfs(self, filelist_fp, inc_default, list_name):343 def filelist_globbing_get_sfs(self, filelist_fp, inc_default, list_name):
457 """Return list of selection functions by reading fileobj344 """Return list of selection functions by reading fileobj
458345
@@ -462,6 +349,7 @@
462 See the man page on --[include/exclude]-globbing-filelist349 See the man page on --[include/exclude]-globbing-filelist
463350
464 """351 """
352 # Internal. Used by ParseArgs.
465 log.Notice(_("Reading globbing filelist %s") % list_name)353 log.Notice(_("Reading globbing filelist %s") % list_name)
466 separator = globals.null_separator and "\0" or "\n"354 separator = globals.null_separator and "\0" or "\n"
467 for line in filelist_fp.read().split(separator):355 for line in filelist_fp.read().split(separator):
@@ -473,6 +361,7 @@
473361
474 def other_filesystems_get_sf(self, include):362 def other_filesystems_get_sf(self, include):
475 """Return selection function matching files on other filesystems"""363 """Return selection function matching files on other filesystems"""
364 # Internal. Used by ParseArgs and unit tests.
476 assert include == 0 or include == 1365 assert include == 0 or include == 1
477 root_devloc = self.rootpath.getdevloc()366 root_devloc = self.rootpath.getdevloc()
478367
@@ -488,6 +377,7 @@
488377
489 def regexp_get_sf(self, regexp_string, include):378 def regexp_get_sf(self, regexp_string, include):
490 """Return selection function given by regexp_string"""379 """Return selection function given by regexp_string"""
380 # Internal. Used by ParseArgs and unit tests.
491 assert include == 0 or include == 1381 assert include == 0 or include == 1
492 try:382 try:
493 regexp = re.compile(regexp_string)383 regexp = re.compile(regexp_string)
@@ -507,6 +397,7 @@
507397
508 def devfiles_get_sf(self):398 def devfiles_get_sf(self):
509 """Return a selection function to exclude all dev files"""399 """Return a selection function to exclude all dev files"""
400 # Internal. Used by ParseArgs.
510 if self.selection_functions:401 if self.selection_functions:
511 log.Warn(_("Warning: exclude-device-files is not the first "402 log.Warn(_("Warning: exclude-device-files is not the first "
512 "selector.\nThis may not be what you intended"))403 "selector.\nThis may not be what you intended"))
@@ -523,6 +414,7 @@
523414
524 def glob_get_sf(self, glob_str, include):415 def glob_get_sf(self, glob_str, include):
525 """Return selection function given by glob string"""416 """Return selection function given by glob string"""
417 # Internal. Used by ParseArgs, filelist_globbing_get_sfs and unit tests.
526 assert include == 0 or include == 1418 assert include == 0 or include == 1
527 if glob_str == "**":419 if glob_str == "**":
528 sel_func = lambda path: include420 sel_func = lambda path: include
@@ -539,6 +431,7 @@
539431
540 def present_get_sf(self, filename, include):432 def present_get_sf(self, filename, include):
541 """Return selection function given by existence of a file in a directory"""433 """Return selection function given by existence of a file in a directory"""
434 # Internal. Used by ParseArgs.
542 assert include == 0 or include == 1435 assert include == 0 or include == 1
543436
544 def exclude_sel_func(path):437 def exclude_sel_func(path):
@@ -572,6 +465,7 @@
572 globbing characters are used.465 globbing characters are used.
573466
574 """467 """
468 # Internal. Used by glob_get_sf and unit tests.
575 if not filename.startswith(self.prefix):469 if not filename.startswith(self.prefix):
576 raise FilePrefixError(filename)470 raise FilePrefixError(filename)
577 index = tuple(filter(lambda x: x,471 index = tuple(filter(lambda x: x,
@@ -580,6 +474,7 @@
580474
581 def glob_get_tuple_sf(self, tuple, include):475 def glob_get_tuple_sf(self, tuple, include):
582 """Return selection function based on tuple"""476 """Return selection function based on tuple"""
477 # Internal. Used by glob_get_filename_sf.
583 def include_sel_func(path):478 def include_sel_func(path):
584 if (path.index == tuple[:len(path.index)] or479 if (path.index == tuple[:len(path.index)] or
585 path.index[:len(tuple)] == tuple):480 path.index[:len(tuple)] == tuple):
@@ -616,6 +511,7 @@
616 things similar to this.511 things similar to this.
617512
618 """513 """
514 # Internal. Used by glob_get_sf and unit tests.
619 if glob_str.lower().startswith("ignorecase:"):515 if glob_str.lower().startswith("ignorecase:"):
620 re_comp = lambda r: re.compile(r, re.I | re.S)516 re_comp = lambda r: re.compile(r, re.I | re.S)
621 glob_str = glob_str[len("ignorecase:"):]517 glob_str = glob_str[len("ignorecase:"):]
@@ -656,6 +552,7 @@
656552
657 def exclude_older_get_sf(self, date):553 def exclude_older_get_sf(self, date):
658 """Return selection function based on files older than modification date """554 """Return selection function based on files older than modification date """
555 # Internal. Used by ParseArgs.
659556
660 def sel_func(path):557 def sel_func(path):
661 if not path.isreg():558 if not path.isreg():
@@ -673,6 +570,7 @@
673570
674 def glob_get_prefix_res(self, glob_str):571 def glob_get_prefix_res(self, glob_str):
675 """Return list of regexps equivalent to prefixes of glob_str"""572 """Return list of regexps equivalent to prefixes of glob_str"""
573 # Internal. Used by glob_get_normal_sf.
676 glob_parts = glob_str.split("/")574 glob_parts = glob_str.split("/")
677 if "" in glob_parts[1:-1]:575 if "" in glob_parts[1:-1]:
678 # "" OK if comes first or last, as in /foo/576 # "" OK if comes first or last, as in /foo/
@@ -696,6 +594,7 @@
696 by Donovan Baarda.594 by Donovan Baarda.
697595
698 """596 """
597 # Internal. Used by glob_get_normal_sf, glob_get_prefix_res and unit tests.
699 i, n, res = 0, len(pat), ''598 i, n, res = 0, len(pat), ''
700 while i < n:599 while i < n:
701 c, s = pat[i], pat[i:i + 2]600 c, s = pat[i], pat[i:i + 2]
702601
=== modified file 'po/duplicity.pot'
--- po/duplicity.pot 2015-03-11 12:27:42 +0000
+++ po/duplicity.pot 2015-03-12 21:50:57 +0000
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: PACKAGE VERSION\n"9"Project-Id-Version: PACKAGE VERSION\n"
10"Report-Msgid-Bugs-To: Kenneth Loafman <kenneth@loafman.com>\n"10"Report-Msgid-Bugs-To: Kenneth Loafman <kenneth@loafman.com>\n"
11"POT-Creation-Date: 2015-03-11 07:21-0500\n"11"POT-Creation-Date: 2015-03-12 21:43+0000\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -371,7 +371,7 @@
371msgid "Backend error detail: %s"371msgid "Backend error detail: %s"
372msgstr ""372msgstr ""
373373
374#: ../bin/rdiffdir:61 ../duplicity/commandline.py:241374#: ../bin/rdiffdir:61 ../duplicity/commandline.py:256
375#, python-format375#, python-format
376msgid "Error opening file %s"376msgid "Error opening file %s"
377msgstr ""377msgstr ""
@@ -693,11 +693,30 @@
693"Use of default filenames is strongly suggested."693"Use of default filenames is strongly suggested."
694msgstr ""694msgstr ""
695695
696#: ../duplicity/commandline.py:77
697#, python-format
698msgid ""
699"Warning: Option %s is pending deprecation and will be removed in a future "
700"release.\n"
701"--include-filelist and --exclude-filelist now accept globbing characters and "
702"should be used instead."
703msgstr ""
704
705#: ../duplicity/commandline.py:86
706#, python-format
707msgid ""
708"Warning: Option %s is pending deprecation and will be removed in a future "
709"release.\n"
710"On many GNU/Linux systems, stdin is represented by /dev/stdin and\n"
711"--include-filelist=/dev/stdin or --exclude-filelist=/dev/stdin could\n"
712"be used as a substitute."
713msgstr ""
714
696#. Used in usage help to represent a Unix-style path name. Example:715#. Used in usage help to represent a Unix-style path name. Example:
697#. --archive-dir <path>716#. --archive-dir <path>
698#: ../duplicity/commandline.py:262 ../duplicity/commandline.py:272717#: ../duplicity/commandline.py:277 ../duplicity/commandline.py:287
699#: ../duplicity/commandline.py:289 ../duplicity/commandline.py:359718#: ../duplicity/commandline.py:304 ../duplicity/commandline.py:378
700#: ../duplicity/commandline.py:560 ../duplicity/commandline.py:774719#: ../duplicity/commandline.py:583 ../duplicity/commandline.py:797
701msgid "path"720msgid "path"
702msgstr ""721msgstr ""
703722
@@ -707,9 +726,9 @@
707#. --hidden-encrypt-key <gpg_key_id>726#. --hidden-encrypt-key <gpg_key_id>
708#. Used in usage help to represent an ID for a GnuPG key. Example:727#. Used in usage help to represent an ID for a GnuPG key. Example:
709#. --encrypt-key <gpg_key_id>728#. --encrypt-key <gpg_key_id>
710#: ../duplicity/commandline.py:284 ../duplicity/commandline.py:291729#: ../duplicity/commandline.py:299 ../duplicity/commandline.py:306
711#: ../duplicity/commandline.py:381 ../duplicity/commandline.py:544730#: ../duplicity/commandline.py:400 ../duplicity/commandline.py:567
712#: ../duplicity/commandline.py:747731#: ../duplicity/commandline.py:770
713msgid "gpg-key-id"732msgid "gpg-key-id"
714msgstr ""733msgstr ""
715734
@@ -717,43 +736,43 @@
717#. matching one or more files, as described in the documentation.736#. matching one or more files, as described in the documentation.
718#. Example:737#. Example:
719#. --exclude <shell_pattern>738#. --exclude <shell_pattern>
720#: ../duplicity/commandline.py:299 ../duplicity/commandline.py:406739#: ../duplicity/commandline.py:314 ../duplicity/commandline.py:425
721#: ../duplicity/commandline.py:797740#: ../duplicity/commandline.py:820
722msgid "shell_pattern"741msgid "shell_pattern"
723msgstr ""742msgstr ""
724743
725#. Used in usage help to represent the name of a file. Example:744#. Used in usage help to represent the name of a file. Example:
726#. --log-file <filename>745#. --log-file <filename>
727#: ../duplicity/commandline.py:305 ../duplicity/commandline.py:312746#: ../duplicity/commandline.py:320 ../duplicity/commandline.py:329
728#: ../duplicity/commandline.py:317 ../duplicity/commandline.py:408747#: ../duplicity/commandline.py:336 ../duplicity/commandline.py:427
729#: ../duplicity/commandline.py:413 ../duplicity/commandline.py:424748#: ../duplicity/commandline.py:434 ../duplicity/commandline.py:447
730#: ../duplicity/commandline.py:743749#: ../duplicity/commandline.py:766
731msgid "filename"750msgid "filename"
732msgstr ""751msgstr ""
733752
734#. Used in usage help to represent a regular expression (regexp).753#. Used in usage help to represent a regular expression (regexp).
735#: ../duplicity/commandline.py:324 ../duplicity/commandline.py:415754#: ../duplicity/commandline.py:343 ../duplicity/commandline.py:438
736msgid "regular_expression"755msgid "regular_expression"
737msgstr ""756msgstr ""
738757
739#. Used in usage help to represent a time spec for a previous758#. Used in usage help to represent a time spec for a previous
740#. point in time, as described in the documentation. Example:759#. point in time, as described in the documentation. Example:
741#. duplicity remove-older-than time [options] target_url760#. duplicity remove-older-than time [options] target_url
742#: ../duplicity/commandline.py:328 ../duplicity/commandline.py:371761#: ../duplicity/commandline.py:347 ../duplicity/commandline.py:390
743#: ../duplicity/commandline.py:486 ../duplicity/commandline.py:829762#: ../duplicity/commandline.py:509 ../duplicity/commandline.py:852
744msgid "time"763msgid "time"
745msgstr ""764msgstr ""
746765
747#. Used in usage help. (Should be consistent with the "Options:"766#. Used in usage help. (Should be consistent with the "Options:"
748#. header.) Example:767#. header.) Example:
749#. duplicity [full|incremental] [options] source_dir target_url768#. duplicity [full|incremental] [options] source_dir target_url
750#: ../duplicity/commandline.py:377 ../duplicity/commandline.py:466769#: ../duplicity/commandline.py:396 ../duplicity/commandline.py:489
751#: ../duplicity/commandline.py:489 ../duplicity/commandline.py:552770#: ../duplicity/commandline.py:512 ../duplicity/commandline.py:575
752#: ../duplicity/commandline.py:762771#: ../duplicity/commandline.py:785
753msgid "options"772msgid "options"
754msgstr ""773msgstr ""
755774
756#: ../duplicity/commandline.py:392775#: ../duplicity/commandline.py:411
757#, python-format776#, python-format
758msgid ""777msgid ""
759"Running in 'ignore errors' mode due to %s; please re-consider if this was "778"Running in 'ignore errors' mode due to %s; please re-consider if this was "
@@ -761,152 +780,152 @@
761msgstr ""780msgstr ""
762781
763#. Used in usage help to represent an imap mailbox782#. Used in usage help to represent an imap mailbox
764#: ../duplicity/commandline.py:404783#: ../duplicity/commandline.py:423
765msgid "imap_mailbox"784msgid "imap_mailbox"
766msgstr ""785msgstr ""
767786
768#: ../duplicity/commandline.py:418787#: ../duplicity/commandline.py:441
769msgid "file_descriptor"788msgid "file_descriptor"
770msgstr ""789msgstr ""
771790
772#. Used in usage help to represent a desired number of791#. Used in usage help to represent a desired number of
773#. something. Example:792#. something. Example:
774#. --num-retries <number>793#. --num-retries <number>
775#: ../duplicity/commandline.py:429 ../duplicity/commandline.py:451794#: ../duplicity/commandline.py:452 ../duplicity/commandline.py:474
776#: ../duplicity/commandline.py:463 ../duplicity/commandline.py:472795#: ../duplicity/commandline.py:486 ../duplicity/commandline.py:495
777#: ../duplicity/commandline.py:510 ../duplicity/commandline.py:515796#: ../duplicity/commandline.py:533 ../duplicity/commandline.py:538
778#: ../duplicity/commandline.py:519 ../duplicity/commandline.py:588797#: ../duplicity/commandline.py:542 ../duplicity/commandline.py:611
779#: ../duplicity/commandline.py:757798#: ../duplicity/commandline.py:780
780msgid "number"799msgid "number"
781msgstr ""800msgstr ""
782801
783#. Used in usage help (noun)802#. Used in usage help (noun)
784#: ../duplicity/commandline.py:432803#: ../duplicity/commandline.py:455
785msgid "backup name"804msgid "backup name"
786msgstr ""805msgstr ""
787806
788#. noun807#. noun
789#: ../duplicity/commandline.py:528 ../duplicity/commandline.py:531808#: ../duplicity/commandline.py:551 ../duplicity/commandline.py:554
790#: ../duplicity/commandline.py:728809#: ../duplicity/commandline.py:751
791msgid "command"810msgid "command"
792msgstr ""811msgstr ""
793812
794#: ../duplicity/commandline.py:534813#: ../duplicity/commandline.py:557
795msgid "pyrax|cloudfiles"814msgid "pyrax|cloudfiles"
796msgstr ""815msgstr ""
797816
798#: ../duplicity/commandline.py:555817#: ../duplicity/commandline.py:578
799msgid "pem formatted bundle of certificate authorities"818msgid "pem formatted bundle of certificate authorities"
800msgstr ""819msgstr ""
801820
802#. Used in usage help. Example:821#. Used in usage help. Example:
803#. --timeout <seconds>822#. --timeout <seconds>
804#: ../duplicity/commandline.py:565 ../duplicity/commandline.py:791823#: ../duplicity/commandline.py:588 ../duplicity/commandline.py:814
805msgid "seconds"824msgid "seconds"
806msgstr ""825msgstr ""
807826
808#. abbreviation for "character" (noun)827#. abbreviation for "character" (noun)
809#: ../duplicity/commandline.py:571 ../duplicity/commandline.py:725828#: ../duplicity/commandline.py:594 ../duplicity/commandline.py:748
810msgid "char"829msgid "char"
811msgstr ""830msgstr ""
812831
813#: ../duplicity/commandline.py:691832#: ../duplicity/commandline.py:714
814#, python-format833#, python-format
815msgid "Using archive dir: %s"834msgid "Using archive dir: %s"
816msgstr ""835msgstr ""
817836
818#: ../duplicity/commandline.py:692837#: ../duplicity/commandline.py:715
819#, python-format838#, python-format
820msgid "Using backup name: %s"839msgid "Using backup name: %s"
821msgstr ""840msgstr ""
822841
823#: ../duplicity/commandline.py:699842#: ../duplicity/commandline.py:722
824#, python-format843#, python-format
825msgid "Command line error: %s"844msgid "Command line error: %s"
826msgstr ""845msgstr ""
827846
828#: ../duplicity/commandline.py:700847#: ../duplicity/commandline.py:723
829msgid "Enter 'duplicity --help' for help screen."848msgid "Enter 'duplicity --help' for help screen."
830msgstr ""849msgstr ""
831850
832#. Used in usage help to represent a Unix-style path name. Example:851#. Used in usage help to represent a Unix-style path name. Example:
833#. rsync://user[:password]@other_host[:port]//absolute_path852#. rsync://user[:password]@other_host[:port]//absolute_path
834#: ../duplicity/commandline.py:713853#: ../duplicity/commandline.py:736
835msgid "absolute_path"854msgid "absolute_path"
836msgstr ""855msgstr ""
837856
838#. Used in usage help. Example:857#. Used in usage help. Example:
839#. tahoe://alias/some_dir858#. tahoe://alias/some_dir
840#: ../duplicity/commandline.py:717859#: ../duplicity/commandline.py:740
841msgid "alias"860msgid "alias"
842msgstr ""861msgstr ""
843862
844#. Used in help to represent a "bucket name" for Amazon Web863#. Used in help to represent a "bucket name" for Amazon Web
845#. Services' Simple Storage Service (S3). Example:864#. Services' Simple Storage Service (S3). Example:
846#. s3://other.host/bucket_name[/prefix]865#. s3://other.host/bucket_name[/prefix]
847#: ../duplicity/commandline.py:722866#: ../duplicity/commandline.py:745
848msgid "bucket_name"867msgid "bucket_name"
849msgstr ""868msgstr ""
850869
851#. Used in usage help to represent the name of a container in870#. Used in usage help to represent the name of a container in
852#. Amazon Web Services' Cloudfront. Example:871#. Amazon Web Services' Cloudfront. Example:
853#. cf+http://container_name872#. cf+http://container_name
854#: ../duplicity/commandline.py:733873#: ../duplicity/commandline.py:756
855msgid "container_name"874msgid "container_name"
856msgstr ""875msgstr ""
857876
858#. noun877#. noun
859#: ../duplicity/commandline.py:736878#: ../duplicity/commandline.py:759
860msgid "count"879msgid "count"
861msgstr ""880msgstr ""
862881
863#. Used in usage help to represent the name of a file directory882#. Used in usage help to represent the name of a file directory
864#: ../duplicity/commandline.py:739883#: ../duplicity/commandline.py:762
865msgid "directory"884msgid "directory"
866msgstr ""885msgstr ""
867886
868#. Used in usage help, e.g. to represent the name of a code887#. Used in usage help, e.g. to represent the name of a code
869#. module. Example:888#. module. Example:
870#. rsync://user[:password]@other.host[:port]::/module/some_dir889#. rsync://user[:password]@other.host[:port]::/module/some_dir
871#: ../duplicity/commandline.py:752890#: ../duplicity/commandline.py:775
872msgid "module"891msgid "module"
873msgstr ""892msgstr ""
874893
875#. Used in usage help to represent an internet hostname. Example:894#. Used in usage help to represent an internet hostname. Example:
876#. ftp://user[:password]@other.host[:port]/some_dir895#. ftp://user[:password]@other.host[:port]/some_dir
877#: ../duplicity/commandline.py:766896#: ../duplicity/commandline.py:789
878msgid "other.host"897msgid "other.host"
879msgstr ""898msgstr ""
880899
881#. Used in usage help. Example:900#. Used in usage help. Example:
882#. ftp://user[:password]@other.host[:port]/some_dir901#. ftp://user[:password]@other.host[:port]/some_dir
883#: ../duplicity/commandline.py:770902#: ../duplicity/commandline.py:793
884msgid "password"903msgid "password"
885msgstr ""904msgstr ""
886905
887#. Used in usage help to represent a TCP port number. Example:906#. Used in usage help to represent a TCP port number. Example:
888#. ftp://user[:password]@other.host[:port]/some_dir907#. ftp://user[:password]@other.host[:port]/some_dir
889#: ../duplicity/commandline.py:778908#: ../duplicity/commandline.py:801
890msgid "port"909msgid "port"
891msgstr ""910msgstr ""
892911
893#. Used in usage help. This represents a string to be used as a912#. Used in usage help. This represents a string to be used as a
894#. prefix to names for backup files created by Duplicity. Example:913#. prefix to names for backup files created by Duplicity. Example:
895#. s3://other.host/bucket_name[/prefix]914#. s3://other.host/bucket_name[/prefix]
896#: ../duplicity/commandline.py:783915#: ../duplicity/commandline.py:806
897msgid "prefix"916msgid "prefix"
898msgstr ""917msgstr ""
899918
900#. Used in usage help to represent a Unix-style path name. Example:919#. Used in usage help to represent a Unix-style path name. Example:
901#. rsync://user[:password]@other.host[:port]/relative_path920#. rsync://user[:password]@other.host[:port]/relative_path
902#: ../duplicity/commandline.py:787921#: ../duplicity/commandline.py:810
903msgid "relative_path"922msgid "relative_path"
904msgstr ""923msgstr ""
905924
906#. Used in usage help to represent the name of a single file925#. Used in usage help to represent the name of a single file
907#. directory or a Unix-style path to a directory. Example:926#. directory or a Unix-style path to a directory. Example:
908#. file:///some_dir927#. file:///some_dir
909#: ../duplicity/commandline.py:802928#: ../duplicity/commandline.py:825
910msgid "some_dir"929msgid "some_dir"
911msgstr ""930msgstr ""
912931
@@ -914,14 +933,14 @@
914#. directory or a Unix-style path to a directory where files will be933#. directory or a Unix-style path to a directory where files will be
915#. coming FROM. Example:934#. coming FROM. Example:
916#. duplicity [full|incremental] [options] source_dir target_url935#. duplicity [full|incremental] [options] source_dir target_url
917#: ../duplicity/commandline.py:808936#: ../duplicity/commandline.py:831
918msgid "source_dir"937msgid "source_dir"
919msgstr ""938msgstr ""
920939
921#. Used in usage help to represent a URL files will be coming940#. Used in usage help to represent a URL files will be coming
922#. FROM. Example:941#. FROM. Example:
923#. duplicity [restore] [options] source_url target_dir942#. duplicity [restore] [options] source_url target_dir
924#: ../duplicity/commandline.py:813943#: ../duplicity/commandline.py:836
925msgid "source_url"944msgid "source_url"
926msgstr ""945msgstr ""
927946
@@ -929,75 +948,75 @@
929#. directory or a Unix-style path to a directory. where files will be948#. directory or a Unix-style path to a directory. where files will be
930#. going TO. Example:949#. going TO. Example:
931#. duplicity [restore] [options] source_url target_dir950#. duplicity [restore] [options] source_url target_dir
932#: ../duplicity/commandline.py:819951#: ../duplicity/commandline.py:842
933msgid "target_dir"952msgid "target_dir"
934msgstr ""953msgstr ""
935954
936#. Used in usage help to represent a URL files will be going TO.955#. Used in usage help to represent a URL files will be going TO.
937#. Example:956#. Example:
938#. duplicity [full|incremental] [options] source_dir target_url957#. duplicity [full|incremental] [options] source_dir target_url
939#: ../duplicity/commandline.py:824958#: ../duplicity/commandline.py:847
940msgid "target_url"959msgid "target_url"
941msgstr ""960msgstr ""
942961
943#. Used in usage help to represent a user name (i.e. login).962#. Used in usage help to represent a user name (i.e. login).
944#. Example:963#. Example:
945#. ftp://user[:password]@other.host[:port]/some_dir964#. ftp://user[:password]@other.host[:port]/some_dir
946#: ../duplicity/commandline.py:834965#: ../duplicity/commandline.py:857
947msgid "user"966msgid "user"
948msgstr ""967msgstr ""
949968
950#. Header in usage help969#. Header in usage help
951#: ../duplicity/commandline.py:852970#: ../duplicity/commandline.py:875
952msgid "Backends and their URL formats:"971msgid "Backends and their URL formats:"
953msgstr ""972msgstr ""
954973
955#. Header in usage help974#. Header in usage help
956#: ../duplicity/commandline.py:881975#: ../duplicity/commandline.py:904
957msgid "Commands:"976msgid "Commands:"
958msgstr ""977msgstr ""
959978
960#: ../duplicity/commandline.py:905979#: ../duplicity/commandline.py:928
961#, python-format980#, python-format
962msgid "Specified archive directory '%s' does not exist, or is not a directory"981msgid "Specified archive directory '%s' does not exist, or is not a directory"
963msgstr ""982msgstr ""
964983
965#: ../duplicity/commandline.py:914984#: ../duplicity/commandline.py:937
966#, python-format985#, python-format
967msgid ""986msgid ""
968"Sign key should be an 8, 16 alt. 40 character hex string, like 'AA0E73D2'.\n"987"Sign key should be an 8, 16 alt. 40 character hex string, like 'AA0E73D2'.\n"
969"Received '%s' instead."988"Received '%s' instead."
970msgstr ""989msgstr ""
971990
972#: ../duplicity/commandline.py:974991#: ../duplicity/commandline.py:997
973#, python-format992#, python-format
974msgid ""993msgid ""
975"Restore destination directory %s already exists.\n"994"Restore destination directory %s already exists.\n"
976"Will not overwrite."995"Will not overwrite."
977msgstr ""996msgstr ""
978997
979#: ../duplicity/commandline.py:979998#: ../duplicity/commandline.py:1002
980#, python-format999#, python-format
981msgid "Verify directory %s does not exist"1000msgid "Verify directory %s does not exist"
982msgstr ""1001msgstr ""
9831002
984#: ../duplicity/commandline.py:9851003#: ../duplicity/commandline.py:1008
985#, python-format1004#, python-format
986msgid "Backup source directory %s does not exist."1005msgid "Backup source directory %s does not exist."
987msgstr ""1006msgstr ""
9881007
989#: ../duplicity/commandline.py:10161008#: ../duplicity/commandline.py:1039
990#, python-format1009#, python-format
991msgid "Command line warning: %s"1010msgid "Command line warning: %s"
992msgstr ""1011msgstr ""
9931012
994#: ../duplicity/commandline.py:10161013#: ../duplicity/commandline.py:1039
995msgid ""1014msgid ""
996"Selection options --exclude/--include\n"1015"Selection options --exclude/--include\n"
997"currently work only when backing up,not restoring."1016"currently work only when backing up,not restoring."
998msgstr ""1017msgstr ""
9991018
1000#: ../duplicity/commandline.py:10641019#: ../duplicity/commandline.py:1087
1001#, python-format1020#, python-format
1002msgid ""1021msgid ""
1003"Bad URL '%s'.\n"1022"Bad URL '%s'.\n"
@@ -1005,7 +1024,7 @@
1005"\"file:///usr/local\". See the man page for more information."1024"\"file:///usr/local\". See the man page for more information."
1006msgstr ""1025msgstr ""
10071026
1008#: ../duplicity/commandline.py:10891027#: ../duplicity/commandline.py:1112
1009msgid "Main action: "1028msgid "Main action: "
1010msgstr ""1029msgstr ""
10111030
@@ -1240,33 +1259,33 @@
1240msgid "Error listing directory %s"1259msgid "Error listing directory %s"
1241msgstr ""1260msgstr ""
12421261
1243#: ../duplicity/selection.py:1251262#: ../duplicity/selection.py:127
1244#, python-format1263#, python-format
1245msgid "Skipping socket %s"1264msgid "Skipping socket %s"
1246msgstr ""1265msgstr ""
12471266
1248#: ../duplicity/selection.py:1291267#: ../duplicity/selection.py:131
1249#, python-format1268#, python-format
1250msgid "Error initializing file %s"1269msgid "Error initializing file %s"
1251msgstr ""1270msgstr ""
12521271
1253#: ../duplicity/selection.py:133 ../duplicity/selection.py:1541272#: ../duplicity/selection.py:135 ../duplicity/selection.py:157
1254#, python-format1273#, python-format
1255msgid "Error accessing possibly locked file %s"1274msgid "Error accessing possibly locked file %s"
1256msgstr ""1275msgstr ""
12571276
1258#: ../duplicity/selection.py:1691277#: ../duplicity/selection.py:172
1259#, python-format1278#, python-format
1260msgid "Warning: base %s doesn't exist, continuing"1279msgid "Warning: base %s doesn't exist, continuing"
1261msgstr ""1280msgstr ""
12621281
1263#: ../duplicity/selection.py:172 ../duplicity/selection.py:1901282#: ../duplicity/selection.py:175 ../duplicity/selection.py:193
1264#: ../duplicity/selection.py:1931283#: ../duplicity/selection.py:196
1265#, python-format1284#, python-format
1266msgid "Selecting %s"1285msgid "Selecting %s"
1267msgstr ""1286msgstr ""
12681287
1269#: ../duplicity/selection.py:2751288#: ../duplicity/selection.py:277
1270#, python-format1289#, python-format
1271msgid ""1290msgid ""
1272"Fatal Error: The file specification\n"1291"Fatal Error: The file specification\n"
@@ -1277,14 +1296,14 @@
1277"pattern (such as '**') which matches the base directory."1296"pattern (such as '**') which matches the base directory."
1278msgstr ""1297msgstr ""
12791298
1280#: ../duplicity/selection.py:2841299#: ../duplicity/selection.py:286
1281#, python-format1300#, python-format
1282msgid ""1301msgid ""
1283"Fatal Error while processing expression\n"1302"Fatal Error while processing expression\n"
1284"%s"1303"%s"
1285msgstr ""1304msgstr ""
12861305
1287#: ../duplicity/selection.py:2931306#: ../duplicity/selection.py:296
1288#, python-format1307#, python-format
1289msgid ""1308msgid ""
1290"Last selection expression:\n"1309"Last selection expression:\n"
@@ -1294,43 +1313,17 @@
1294"probably isn't what you meant."1313"probably isn't what you meant."
1295msgstr ""1314msgstr ""
12961315
1297#: ../duplicity/selection.py:3191316#: ../duplicity/selection.py:353
1298#, python-format
1299msgid "Reading filelist %s"
1300msgstr ""
1301
1302#: ../duplicity/selection.py:322
1303#, python-format
1304msgid "Sorting filelist %s"
1305msgstr ""
1306
1307#: ../duplicity/selection.py:350
1308#, python-format
1309msgid ""
1310"Warning: file specification '%s' in filelist %s\n"
1311"doesn't start with correct prefix %s. Ignoring."
1312msgstr ""
1313
1314#: ../duplicity/selection.py:354
1315msgid "Future prefix errors will not be logged."
1316msgstr ""
1317
1318#: ../duplicity/selection.py:372
1319#, python-format
1320msgid "Error closing filelist %s"
1321msgstr ""
1322
1323#: ../duplicity/selection.py:465
1324#, python-format1317#, python-format
1325msgid "Reading globbing filelist %s"1318msgid "Reading globbing filelist %s"
1326msgstr ""1319msgstr ""
13271320
1328#: ../duplicity/selection.py:4951321#: ../duplicity/selection.py:385
1329#, python-format1322#, python-format
1330msgid "Error compiling regular expression %s"1323msgid "Error compiling regular expression %s"
1331msgstr ""1324msgstr ""
13321325
1333#: ../duplicity/selection.py:5111326#: ../duplicity/selection.py:402
1334msgid ""1327msgid ""
1335"Warning: exclude-device-files is not the first selector.\n"1328"Warning: exclude-device-files is not the first selector.\n"
1336"This may not be what you intended"1329"This may not be what you intended"
13371330
=== modified file 'testing/functional/test_selection.py'
--- testing/functional/test_selection.py 2015-01-31 16:19:46 +0000
+++ testing/functional/test_selection.py 2015-03-12 21:50:57 +0000
@@ -24,7 +24,6 @@
2424
25from . import FunctionalTestCase25from . import FunctionalTestCase
2626
27
28class IncludeExcludeFunctionalTest(FunctionalTestCase):27class IncludeExcludeFunctionalTest(FunctionalTestCase):
29 """28 """
30 This contains methods used in the tests below for testing the include, exclude and various filelist features.29 This contains methods used in the tests below for testing the include, exclude and various filelist features.
@@ -235,13 +234,13 @@
235 self.assertEqual(restored, self.expected_restored_tree_with_trailing_space)234 self.assertEqual(restored, self.expected_restored_tree_with_trailing_space)
236235
237236
238class TestExcludeGlobbingFilelistTest(IncludeExcludeFunctionalTest):237class TestExcludeFilelistTest(IncludeExcludeFunctionalTest):
239 """238 """
240 Test --exclude-globbing-filelist using duplicity binary.239 Test --exclude-filelist using duplicity binary.
241 """240 """
242241
243 def test_exclude_globbing_filelist(self):242 def test_exclude_filelist(self):
244 """Test that exclude globbing filelist works in the basic case """243 """Test that exclude filelist works in the basic case """
245 # As this is an exclude filelist any lines with no +/- modifier should be treated as if they have a -.244 # As this is an exclude filelist any lines with no +/- modifier should be treated as if they have a -.
246 # Create a filelist245 # Create a filelist
247 with open('testfiles/exclude.txt', 'w') as f:246 with open('testfiles/exclude.txt', 'w') as f:
@@ -264,7 +263,50 @@
264 '+ testfiles/select2/3\n'263 '+ testfiles/select2/3\n'
265 '+ testfiles/select2/1\n'264 '+ testfiles/select2/1\n'
266 'testfiles/select2/**')265 'testfiles/select2/**')
267 self.backup("full", "testfiles/select2", options=["--exclude-globbing-filelist=testfiles/exclude.txt"])266 self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt"])
267 self.restore()
268 restore_dir = 'testfiles/restore_out'
269 restored = self.directory_tree_to_list_of_lists(restore_dir)
270 self.assertEqual(restored, self.expected_restored_tree)
271
272 def test_exclude_filelist_combined_imperfections(self):
273 """Test that exclude filelist works with imperfections in the input file"""
274 # This is a combined test for speed reasons. The individual imperfections are tested as unittests in
275 # unit/test_selection.
276 # Imperfections tested are;
277 # * Leading space/spaces before the modifier
278 # * Trailing space/spaces after the filename (but before the newline)
279 # * Blank lines (newline character only)
280 # * Line only containing spaces
281 # * Full-line comments with # as the first character and with leading/trailing spaces
282 # * Unnecessarily quoted filenames with/without modifier (both " and ')
283
284 # Create a filelist
285 with open('testfiles/exclude.txt', 'w') as f:
286 f.write('+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
287 'testfiles/select2/3/3sub3/3sub3sub2\n'
288 '+ testfiles/select2/3/3sub2/3sub2sub2\n'
289 ' + testfiles/select2/3/3sub3\n' # Note leading space added here
290 '- testfiles/select2/3/3sub1\n'
291 ' testfiles/select2/2/2sub1/2sub1sub3\n' # Note leading spaces added here
292 '\n'
293 'testfiles/select2/2/2sub1/2sub1sub2\n'
294 ' + testfiles/select2/2/2sub1 \n' # Note added trailing/leading space here
295 '- "testfiles/select2/1/1sub3/1sub3sub2"\n' # Unnecessary quotes
296 '# Testing a full-line comment\n'
297 "'testfiles/select2/1/1sub3/1sub3sub1' \n" # Note added spaces and quotes here
298 'testfiles/select2/1/1sub2/1sub2sub3\n'
299 ' \n'
300 '+ testfiles/select2/1/1sub2/1sub2sub1\n'
301 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
302 'testfiles/select2/1/1sub1/1sub1sub2\n'
303 ' # Testing a full-line comment with leading and trailing spaces \n'
304 'testfiles/select2/1/1sub2 \n' # Note added spaces here
305 '+ testfiles/select2/1.py\n'
306 '+ testfiles/select2/3 \n' # Note added space here
307 '+ testfiles/select2/1\n'
308 '- testfiles/select2/**')
309 self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt"])
268 self.restore()310 self.restore()
269 restore_dir = 'testfiles/restore_out'311 restore_dir = 'testfiles/restore_out'
270 restored = self.directory_tree_to_list_of_lists(restore_dir)312 restored = self.directory_tree_to_list_of_lists(restore_dir)
@@ -272,6 +314,8 @@
272314
273 def test_exclude_globbing_filelist_combined_imperfections(self):315 def test_exclude_globbing_filelist_combined_imperfections(self):
274 """Test that exclude globbing filelist works with imperfections in the input file"""316 """Test that exclude globbing filelist works with imperfections in the input file"""
317 # Identical to test_exclude_filelist_combined_imperfections and included to ensure that
318 # the deprecated --exclude-globbing-filelist function works as expected until it is deliberately removed.
275 # This is a combined test for speed reasons. The individual imperfections are tested as unittests in319 # This is a combined test for speed reasons. The individual imperfections are tested as unittests in
276 # unit/test_selection.320 # unit/test_selection.
277 # Imperfections tested are;321 # Imperfections tested are;
@@ -313,7 +357,7 @@
313 restored = self.directory_tree_to_list_of_lists(restore_dir)357 restored = self.directory_tree_to_list_of_lists(restore_dir)
314 self.assertEqual(restored, self.expected_restored_tree)358 self.assertEqual(restored, self.expected_restored_tree)
315359
316 def test_exclude_globbing_filelist_trailing_whitespace_folders_work_with_quotes(self):360 def test_exclude_filelist_trailing_whitespace_folders_work_with_quotes(self):
317 """Test that folders with trailing whitespace in the names work correctly if they are enclosed in quotes"""361 """Test that folders with trailing whitespace in the names work correctly if they are enclosed in quotes"""
318 # Create a filelist362 # Create a filelist
319 with open('testfiles/exclude.txt', 'w') as f:363 with open('testfiles/exclude.txt', 'w') as f:
@@ -339,17 +383,17 @@
339 '+ testfiles/select2/3\n'383 '+ testfiles/select2/3\n'
340 '+ testfiles/select2/1\n'384 '+ testfiles/select2/1\n'
341 'testfiles/select2/**')385 'testfiles/select2/**')
342 self.backup("full", "testfiles/select2", options=["--exclude-globbing-filelist=testfiles/exclude.txt"])386 self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt"])
343 self.restore()387 self.restore()
344 restore_dir = 'testfiles/restore_out'388 restore_dir = 'testfiles/restore_out'
345 restored = self.directory_tree_to_list_of_lists(restore_dir)389 restored = self.directory_tree_to_list_of_lists(restore_dir)
346 self.assertEqual(restored, self.expected_restored_tree_with_trailing_space)390 self.assertEqual(restored, self.expected_restored_tree_with_trailing_space)
347391
348 @unittest.expectedFailure392 @unittest.expectedFailure
349 def test_exclude_globbing_filelist_progress_option(self):393 def test_exclude_filelist_progress_option(self):
350 """Test that exclude globbing filelist is unaffected by the --progress option"""394 """Test that exclude filelist is unaffected by the --progress option"""
351 # ToDo - currently fails. Bug #1264744 (https://bugs.launchpad.net/duplicity/+bug/1264744)395 # ToDo - currently fails. Bug #1264744 (https://bugs.launchpad.net/duplicity/+bug/1264744)
352 # Create a filelist identical to that used in test_exclude_globbing_filelist396 # Create a filelist identical to that used in test_exclude_filelist
353 with open('testfiles/exclude.txt', 'w') as f:397 with open('testfiles/exclude.txt', 'w') as f:
354 f.write('+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'398 f.write('+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
355 'testfiles/select2/3/3sub3/3sub3sub2\n'399 'testfiles/select2/3/3sub3/3sub3sub2\n'
@@ -371,170 +415,94 @@
371 '+ testfiles/select2/1\n'415 '+ testfiles/select2/1\n'
372 'testfiles/select2/**')416 'testfiles/select2/**')
373417
374 # Backup the files exactly as in test_exclude_globbing_filelist, but with the --progress option418 # Backup the files exactly as in test_exclude_filelist, but with the --progress option
375 self.backup("full", "testfiles/select2", options=["--exclude-globbing-filelist=testfiles/exclude.txt",419 self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt",
376 "--progress"])420 "--progress"])
377 self.restore()421 self.restore()
378 restore_dir = 'testfiles/restore_out'422 restore_dir = 'testfiles/restore_out'
379 restored = self.directory_tree_to_list_of_lists(restore_dir)423 restored = self.directory_tree_to_list_of_lists(restore_dir)
380 # The restored files should match those restored in test_exclude_globbing_filelist424 # The restored files should match those restored in test_exclude_filelist
381 self.assertEqual(restored, self.expected_restored_tree)425 self.assertEqual(restored, self.expected_restored_tree)
382
383class TestIncludeGlobbingFilelistTest(IncludeExcludeFunctionalTest):
384 """
385 Test --include-globbing-filelist using duplicity binary.
386 """
387
388 def test_include_globbing_filelist(self):
389 """Test that include globbing filelist works in the basic case"""
390 # See test_exclude_globbing_filelist above for explanation of what is expected. As this is an include filelist
391 # any lines with no +/- modifier should be treated as if they have a +.
392 # Create a filelist
393 with open('testfiles/include.txt', 'w') as f:
394 f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
395 '- testfiles/select2/3/3sub3/3sub3sub2\n'
396 'testfiles/select2/3/3sub2/3sub2sub2\n'
397 '+ testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
398 '- testfiles/select2/3/3sub1\n'
399 '- testfiles/select2/2/2sub1/2sub1sub3\n'
400 '- testfiles/select2/2/2sub1/2sub1sub2\n'
401 'testfiles/select2/2/2sub1\n'
402 '- testfiles/select2/1/1sub3/1sub3sub2\n'
403 '- testfiles/select2/1/1sub3/1sub3sub1\n'
404 '- testfiles/select2/1/1sub2/1sub2sub3\n'
405 '+ testfiles/select2/1/1sub2/1sub2sub1\n' # + added to ensure it makes no difference
406 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
407 '- testfiles/select2/1/1sub1/1sub1sub2\n'
408 '- testfiles/select2/1/1sub2\n'
409 'testfiles/select2/1.py\n'
410 'testfiles/select2/3\n'
411 'testfiles/select2/1\n'
412 '- testfiles/select2/**')
413 self.backup("full", "testfiles/select2", options=["--include-globbing-filelist=testfiles/include.txt"])
414 self.restore()
415 restore_dir = 'testfiles/restore_out'
416 restored = self.directory_tree_to_list_of_lists(restore_dir)
417 self.assertEqual(restored, self.expected_restored_tree)
418
419 def test_include_globbing_filelist_combined_imperfections(self):
420 """Test that include globbing filelist works with imperfections in the input file"""
421 # This is a combined test for speed reasons. The individual imperfections are tested as unittests in
422 # unit/test_selection.
423 # Imperfections tested are;
424 # * Leading space/spaces before the modifier
425 # * Trailing space/spaces after the filename (but before the newline)
426 # * Blank lines (newline character only)
427 # * Line only containing spaces
428 # * Full-line comments with # as the first character and with leading/trailing spaces
429 # * Unnecessarily quoted filenames with/without modifier (both " and ')
430 # Create a filelist
431 with open('testfiles/include.txt', 'w') as f:
432 f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
433 '- testfiles/select2/3/3sub3/3sub3sub2\n'
434 '"testfiles/select2/3/3sub2/3sub2sub2"\n'
435 ' + testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
436 '- testfiles/select2/3/3sub1\n'
437 '- testfiles/select2/2/2sub1/2sub1sub3\n'
438 ' - "testfiles/select2/2/2sub1/2sub1sub2"\n'
439 'testfiles/select2/2/2sub1 \n'
440 '\n'
441 '- testfiles/select2/1/1sub3/1sub3sub2\n'
442 '- testfiles/select2/1/1sub3/1sub3sub1 \n'
443 "- 'testfiles/select2/1/1sub2/1sub2sub3'\n"
444 ' \n'
445 ' + testfiles/select2/1/1sub2/1sub2sub1 \n' # + added to ensure it makes no difference
446 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
447 ' - testfiles/select2/1/1sub1/1sub1sub2 \n'
448 '# Testing full-line comment\n'
449 '- testfiles/select2/1/1sub2\n'
450 "'testfiles/select2/1.py'\n"
451 'testfiles/select2/3\n'
452 ' # Testing another full-line comment \n'
453 'testfiles/select2/1\n'
454 '- testfiles/select2/**')
455 self.backup("full", "testfiles/select2", options=["--include-globbing-filelist=testfiles/include.txt"])
456 self.restore()
457 restore_dir = 'testfiles/restore_out'
458 restored = self.directory_tree_to_list_of_lists(restore_dir)
459 self.assertEqual(restored, self.expected_restored_tree)
460
461426
462class TestIncludeFilelistTest(IncludeExcludeFunctionalTest):427class TestIncludeFilelistTest(IncludeExcludeFunctionalTest):
463 """428 """
464 Test --include-filelist using duplicity binary.429 Test --include-filelist using duplicity binary.
465 """430 """
466 @unittest.expectedFailure431
467 def test_include_filelist(self):432 def test_include_filelist(self):
468 """Test that include filelist works in the basic case"""433 """Test that include filelist works in the basic case"""
469 # See test_exclude_globbing_filelist above for explanation of what is expected. As this is an include filelist434 # See test_exclude_filelist above for explanation of what is expected. As this is an include filelist
470 # any lines with no +/- modifier should be treated as if they have a +.435 # any lines with no +/- modifier should be treated as if they have a +.
471 # ToDo Currently fails - Bug #1408411 (https://bugs.launchpad.net/duplicity/+bug/1408411)436 # Create a filelist
472 # Create a filelist437 with open('testfiles/include.txt', 'w') as f:
473 with open('testfiles/include.txt', 'w') as f:438 f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
474 f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'439 '- testfiles/select2/3/3sub3/3sub3sub2\n'
475 '- testfiles/select2/3/3sub3/3sub3sub2\n'440 'testfiles/select2/3/3sub2/3sub2sub2\n'
476 'testfiles/select2/3/3sub2/3sub2sub2\n'441 '+ testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
477 '+ testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference442 '- testfiles/select2/3/3sub1\n'
478 '- testfiles/select2/3/3sub1\n'443 '- testfiles/select2/2/2sub1/2sub1sub3\n'
479 '- testfiles/select2/2/2sub1/2sub1sub3\n'444 '- testfiles/select2/2/2sub1/2sub1sub2\n'
480 '- testfiles/select2/2/2sub1/2sub1sub2\n'445 'testfiles/select2/2/2sub1\n'
481 'testfiles/select2/2/2sub1\n'446 '- testfiles/select2/1/1sub3/1sub3sub2\n'
482 '- testfiles/select2/1/1sub3/1sub3sub2\n'447 '- testfiles/select2/1/1sub3/1sub3sub1\n'
483 '- testfiles/select2/1/1sub3/1sub3sub1\n'448 '- testfiles/select2/1/1sub2/1sub2sub3\n'
484 '- testfiles/select2/1/1sub2/1sub2sub3\n'449 '+ testfiles/select2/1/1sub2/1sub2sub1\n' # + added to ensure it makes no difference
485 '+ testfiles/select2/1/1sub2/1sub2sub1\n' # + added to ensure it makes no difference450 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
486 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'451 '- testfiles/select2/1/1sub1/1sub1sub2\n'
487 '- testfiles/select2/1/1sub1/1sub1sub2\n'452 '- testfiles/select2/1/1sub2\n'
488 '- testfiles/select2/1/1sub2\n'453 'testfiles/select2/1.py\n'
489 'testfiles/select2/1.py\n'454 'testfiles/select2/3\n'
490 'testfiles/select2/3\n'455 'testfiles/select2/1\n'
491 '- testfiles/select2/2\n' # es instead of ea as no globbing - **456 '- testfiles/select2/**')
492 'testfiles/select2/1\n'457 self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])
493 '- "testfiles/select2/trailing_space "\n' # es instead of ea as no globbing - **458 self.restore()
494 '- testfiles/select2/1.doc') # es instead of ea as no globbing - **459 restore_dir = 'testfiles/restore_out'
495 self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])460 restored = self.directory_tree_to_list_of_lists(restore_dir)
496 self.restore()461 self.assertEqual(restored, self.expected_restored_tree)
497 restore_dir = 'testfiles/restore_out'462
498 restored = self.directory_tree_to_list_of_lists(restore_dir)463 def test_include_filelist_combined_imperfections(self):
499 self.assertEqual(restored, self.expected_restored_tree)464 """Test that include filelist works with imperfections in the input file"""
500465 # This is a combined test for speed reasons. The individual imperfections are tested as unittests in
501 def test_include_filelist_workaround(self):466 # unit/test_selection.
502 """Test that include filelist works in the basic case"""467 # Imperfections tested are;
503 # This is a modified version of test_include_filelist that passes, despite Bug #1408411468 # * Leading space/spaces before the modifier
504 # It is still a valid test, it just does not test as many selection features as the above.469 # * Trailing space/spaces after the filename (but before the newline)
505 # Create a filelist470 # * Blank lines (newline character only)
506 with open('testfiles/include.txt', 'w') as f:471 # * Line only containing spaces
507 f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'472 # * Full-line comments with # as the first character and with leading/trailing spaces
508 # '- testfiles/select2/3/3sub3/3sub3sub2\n' # Commented out because of Bug #1408411473 # * Unnecessarily quoted filenames with/without modifier (both " and ')
509 'testfiles/select2/3/3sub2/3sub2sub2\n'474 # Create a filelist
510 '+ testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference475 with open('testfiles/include.txt', 'w') as f:
511 '- testfiles/select2/3/3sub1\n'476 f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
512 '- testfiles/select2/2/2sub1/2sub1sub3\n'477 '- testfiles/select2/3/3sub3/3sub3sub2\n'
513 '- testfiles/select2/2/2sub1/2sub1sub2\n'478 '"testfiles/select2/3/3sub2/3sub2sub2"\n'
514 'testfiles/select2/2/2sub1\n'479 ' + testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
515 '- testfiles/select2/2/2sub3\n' # Added because of Bug #1408411480 '- testfiles/select2/3/3sub1\n'
516 '- testfiles/select2/2/2sub2\n' # Added because of Bug #1408411481 '- testfiles/select2/2/2sub1/2sub1sub3\n'
517 '- testfiles/select2/1/1sub3/1sub3sub2\n'482 ' - "testfiles/select2/2/2sub1/2sub1sub2"\n'
518 '- testfiles/select2/1/1sub3/1sub3sub1\n'483 'testfiles/select2/2/2sub1 \n'
519 '- testfiles/select2/1/1sub2/1sub2sub3\n'484 '\n'
520 '- testfiles/select2/1/1sub2/1sub2sub2\n' # Added because of Bug #1408411485 '- testfiles/select2/1/1sub3/1sub3sub2\n'
521 '+ testfiles/select2/1/1sub2/1sub2sub1\n' # + added to ensure it makes no difference486 '- testfiles/select2/1/1sub3/1sub3sub1 \n'
522 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'487 "- 'testfiles/select2/1/1sub2/1sub2sub3'\n"
523 '- testfiles/select2/1/1sub1/1sub1sub2\n'488 ' \n'
524 # '- testfiles/select2/1/1sub2\n' # Commented out because of Bug #1408411489 ' + testfiles/select2/1/1sub2/1sub2sub1 \n' # + added to ensure it makes no difference
525 'testfiles/select2/1.py\n'490 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
526 'testfiles/select2/3\n'491 ' - testfiles/select2/1/1sub1/1sub1sub2 \n'
527 # '- testfiles/select2/2\n' # Commented out because of Bug #1408411492 '# Testing full-line comment\n'
528 'testfiles/select2/1\n'493 '- testfiles/select2/1/1sub2\n'
529 '- "testfiles/select2/trailing_space "\n' # es instead of ea as no globbing - **494 "'testfiles/select2/1.py'\n"
530 '- testfiles/select2/1.doc') # es instead of ea as no globbing - **495 'testfiles/select2/3\n'
531 self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])496 ' # Testing another full-line comment \n'
532 self.restore()497 'testfiles/select2/1\n'
533 restore_dir = 'testfiles/restore_out'498 '- testfiles/select2/**')
534 restored = self.directory_tree_to_list_of_lists(restore_dir)499 self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])
535 self.assertEqual(restored, self.expected_restored_tree)500 self.restore()
536501 restore_dir = 'testfiles/restore_out'
537 def test_include_filelist_workaround_combined_imperfections(self):502 restored = self.directory_tree_to_list_of_lists(restore_dir)
503 self.assertEqual(restored, self.expected_restored_tree)
504
505 def test_include_filelist_workaround_combined_imperfections_no_wildcards(self):
538 """Test that include filelist works with imperfections in the input file"""506 """Test that include filelist works with imperfections in the input file"""
539 # This is a modified version of test_include_filelist that passes, despite Bug #1408411507 # This is a modified version of test_include_filelist that passes, despite Bug #1408411
540 # It is still a valid test, it just does not test as many selection features as the above.508 # It is still a valid test, it just does not test as many selection features as the above.
@@ -574,14 +542,58 @@
574 'testfiles/select2/3\n'542 'testfiles/select2/3\n'
575 # '- testfiles/select2/2\n' # Commented out because of Bug #1408411543 # '- testfiles/select2/2\n' # Commented out because of Bug #1408411
576 'testfiles/select2/1\n'544 'testfiles/select2/1\n'
577 '- "testfiles/select2/trailing_space "\n' # es instead of ea as no globbing - **545 '- "testfiles/select2/trailing_space "\n' # es instead of ea as no wildcard - **
578 '- testfiles/select2/1.doc') # es instead of ea as no globbing - **546 '- testfiles/select2/1.doc') # es instead of ea as no wildcard - **
579 self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])547 self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])
580 self.restore()548 self.restore()
581 restore_dir = 'testfiles/restore_out'549 restore_dir = 'testfiles/restore_out'
582 restored = self.directory_tree_to_list_of_lists(restore_dir)550 restored = self.directory_tree_to_list_of_lists(restore_dir)
583 self.assertEqual(restored, self.expected_restored_tree)551 self.assertEqual(restored, self.expected_restored_tree)
584552
553 def test_include_globbing_filelist_combined_imperfections(self):
554 """Test that include globbing filelist works with imperfections in the input file"""
555 # Identical to test_include_filelist_combined_imperfections and included to ensure that
556 # the deprecated --include-globbing-filelist function works as expected until it is deliberately removed.
557 # This is a combined test for speed reasons. The individual imperfections are tested as unittests in
558 # unit/test_selection.
559 # Imperfections tested are;
560 # * Leading space/spaces before the modifier
561 # * Trailing space/spaces after the filename (but before the newline)
562 # * Blank lines (newline character only)
563 # * Line only containing spaces
564 # * Full-line comments with # as the first character and with leading/trailing spaces
565 # * Unnecessarily quoted filenames with/without modifier (both " and ')
566 # Create a filelist
567 with open('testfiles/include.txt', 'w') as f:
568 f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
569 '- testfiles/select2/3/3sub3/3sub3sub2\n'
570 '"testfiles/select2/3/3sub2/3sub2sub2"\n'
571 ' + testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
572 '- testfiles/select2/3/3sub1\n'
573 '- testfiles/select2/2/2sub1/2sub1sub3\n'
574 ' - "testfiles/select2/2/2sub1/2sub1sub2"\n'
575 'testfiles/select2/2/2sub1 \n'
576 '\n'
577 '- testfiles/select2/1/1sub3/1sub3sub2\n'
578 '- testfiles/select2/1/1sub3/1sub3sub1 \n'
579 "- 'testfiles/select2/1/1sub2/1sub2sub3'\n"
580 ' \n'
581 ' + testfiles/select2/1/1sub2/1sub2sub1 \n' # + added to ensure it makes no difference
582 '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
583 ' - testfiles/select2/1/1sub1/1sub1sub2 \n'
584 '# Testing full-line comment\n'
585 '- testfiles/select2/1/1sub2\n'
586 "'testfiles/select2/1.py'\n"
587 'testfiles/select2/3\n'
588 ' # Testing another full-line comment \n'
589 'testfiles/select2/1\n'
590 '- testfiles/select2/**')
591 self.backup("full", "testfiles/select2", options=["--include-globbing-filelist=testfiles/include.txt"])
592 self.restore()
593 restore_dir = 'testfiles/restore_out'
594 restored = self.directory_tree_to_list_of_lists(restore_dir)
595 self.assertEqual(restored, self.expected_restored_tree)
596
585597
586class TestIncludeExcludedForContents(IncludeExcludeFunctionalTest):598class TestIncludeExcludedForContents(IncludeExcludeFunctionalTest):
587 """ Test to check that folders that are excluded are included if they contain includes of higher priority.599 """ Test to check that folders that are excluded are included if they contain includes of higher priority.
@@ -614,28 +626,28 @@
614626
615 def test_include_globbing_filelist(self):627 def test_include_globbing_filelist(self):
616 """test an excluded folder is included for included contents with an include-globbing-filelist """628 """test an excluded folder is included for included contents with an include-globbing-filelist """
629 # Deprecated, but include for now to ensure it keeps working until it is deliberately removed.
617 self.write_filelist("testfiles/include.txt")630 self.write_filelist("testfiles/include.txt")
618 self.backup("full", "testfiles/select/1", options=["--include-globbing-filelist=testfiles/include.txt"])631 self.backup("full", "testfiles/select/1", options=["--include-globbing-filelist=testfiles/include.txt"])
619 self.restore_and_check()632 self.restore_and_check()
620633
621 def test_exclude_globbing_filelist(self):634 def test_exclude_globbing_filelist(self):
622 """test an excluded folder is included for included contents with an exclude-globbing-filelist """635 """test an excluded folder is included for included contents with an exclude-globbing-filelist """
636 # Deprecated, but include for now to ensure it keeps working until it is deliberately removed.
623 self.write_filelist("testfiles/exclude.txt")637 self.write_filelist("testfiles/exclude.txt")
624 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/exclude.txt"])638 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/exclude.txt"])
625 self.restore_and_check()639 self.restore_and_check()
626640
627 @unittest.expectedFailure
628 def test_include_filelist(self):641 def test_include_filelist(self):
629 """test an excluded folder is included for included contents with an include-filelist (non-globbing) """642 """test an excluded folder is included for included contents with an include-filelist (non-globbing) """
630 # ToDo - currently fails - Bug #1408411 (https://bugs.launchpad.net/duplicity/+bug/1408411)643 # Regression test for Bug #1408411 (https://bugs.launchpad.net/duplicity/+bug/1408411)
631 self.write_filelist("testfiles/include.txt")644 self.write_filelist("testfiles/include.txt")
632 self.backup("full", "testfiles/select/1", options=["--include-filelist=testfiles/include.txt"])645 self.backup("full", "testfiles/select/1", options=["--include-filelist=testfiles/include.txt"])
633 self.restore_and_check()646 self.restore_and_check()
634647
635 @unittest.expectedFailure
636 def test_exclude_filelist(self):648 def test_exclude_filelist(self):
637 """test an excluded folder is included for included contents with an exclude-filelist (non-globbing) """649 """test an excluded folder is included for included contents with an exclude-filelist (non-globbing) """
638 # ToDo - currently fails - Bug #1408411 (https://bugs.launchpad.net/duplicity/+bug/1408411)650 # Regression test for Bug #1408411 (https://bugs.launchpad.net/duplicity/+bug/1408411)
639 self.write_filelist("testfiles/exclude.txt")651 self.write_filelist("testfiles/exclude.txt")
640 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/exclude.txt"])652 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/exclude.txt"])
641 self.restore_and_check()653 self.restore_and_check()
@@ -653,38 +665,38 @@
653 restored = self.directory_tree_to_list_of_lists(restore_dir)665 restored = self.directory_tree_to_list_of_lists(restore_dir)
654 self.assertEqual(restored, [['2'], ['1']])666 self.assertEqual(restored, [['2'], ['1']])
655667
656 def test_exclude_globbing_filelist_asterisks_none(self):668 def test_exclude_filelist_asterisks_none(self):
657 """Basic exclude globbing filelist."""669 """Basic exclude filelist."""
658 with open("testfiles/filelist.txt", 'w') as f:670 with open("testfiles/filelist.txt", 'w') as f:
659 f.write("+ testfiles/select/1/2/1\n"671 f.write("+ testfiles/select/1/2/1\n"
660 "- testfiles/select/1/2\n"672 "- testfiles/select/1/2\n"
661 "- testfiles/select/1/1\n"673 "- testfiles/select/1/1\n"
662 "- testfiles/select/1/3")674 "- testfiles/select/1/3")
663 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/filelist.txt"])675 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
664 self.restore_and_check()676 self.restore_and_check()
665677
666 @unittest.expectedFailure678 @unittest.expectedFailure
667 def test_exclude_globbing_filelist_asterisks_single(self):679 def test_exclude_filelist_asterisks_single(self):
668 """Exclude globbing filelist with asterisks replacing folders."""680 """Exclude filelist with asterisks replacing folders."""
669 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)681 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
670 with open("testfiles/filelist.txt", 'w') as f:682 with open("testfiles/filelist.txt", 'w') as f:
671 f.write("+ */select/1/2/1\n"683 f.write("+ */select/1/2/1\n"
672 "- */select/1/2\n"684 "- */select/1/2\n"
673 "- testfiles/*/1/1\n"685 "- testfiles/*/1/1\n"
674 "- */*/1/3")686 "- */*/1/3")
675 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/filelist.txt"])687 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
676 self.restore_and_check()688 self.restore_and_check()
677689
678 @unittest.expectedFailure690 @unittest.expectedFailure
679 def test_exclude_globbing_filelist_asterisks_double_asterisks(self):691 def test_exclude_filelist_asterisks_double_asterisks(self):
680 """Exclude globbing filelist with double asterisks replacing folders."""692 """Exclude filelist with double asterisks replacing folders."""
681 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)693 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
682 with open("testfiles/filelist.txt", 'w') as f:694 with open("testfiles/filelist.txt", 'w') as f:
683 f.write("+ **/1/2/1\n"695 f.write("+ **/1/2/1\n"
684 "- **/1/2\n"696 "- **/1/2\n"
685 "- **/select/1/1\n"697 "- **/select/1/1\n"
686 "- testfiles/select/1/3")698 "- testfiles/select/1/3")
687 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/filelist.txt"])699 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
688 self.restore_and_check()700 self.restore_and_check()
689701
690 def test_commandline_asterisks_single_excludes_only(self):702 def test_commandline_asterisks_single_excludes_only(self):
@@ -738,43 +750,43 @@
738 restored = self.directory_tree_to_list_of_lists(restore_dir)750 restored = self.directory_tree_to_list_of_lists(restore_dir)
739 self.assertEqual(restored, [['2'], ['1']])751 self.assertEqual(restored, [['2'], ['1']])
740752
741 def test_exclude_globbing_filelist_trailing_slashes(self):753 def test_exclude_filelist_trailing_slashes(self):
742 """test_exclude_globbing_filelist_asterisks_none with trailing slashes."""754 """test_exclude_filelist_asterisks_none with trailing slashes."""
743 with open("testfiles/filelist.txt", 'w') as f:755 with open("testfiles/filelist.txt", 'w') as f:
744 f.write("+ testfiles/select/1/2/1/\n"756 f.write("+ testfiles/select/1/2/1/\n"
745 "- testfiles/select/1/2/\n"757 "- testfiles/select/1/2/\n"
746 "- testfiles/select/1/1/\n"758 "- testfiles/select/1/1/\n"
747 "- testfiles/select/1/3/")759 "- testfiles/select/1/3/")
748 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/filelist.txt"])760 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
749 self.restore_and_check()761 self.restore_and_check()
750762
751 @unittest.expectedFailure763 @unittest.expectedFailure
752 def test_exclude_globbing_filelist_trailing_slashes_single_wildcards_excludes(self):764 def test_exclude_filelist_trailing_slashes_single_wildcards_excludes(self):
753 """test_exclude_globbing_filelist_trailing_slashes with single wildcards in excludes."""765 """test_exclude_filelist_trailing_slashes with single wildcards in excludes."""
754 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)766 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
755 with open("testfiles/filelist.txt", 'w') as f:767 with open("testfiles/filelist.txt", 'w') as f:
756 f.write("+ testfiles/select/1/2/1/\n"768 f.write("+ testfiles/select/1/2/1/\n"
757 "- */select/1/2/\n"769 "- */select/1/2/\n"
758 "- testfiles/*/1/1/\n"770 "- testfiles/*/1/1/\n"
759 "- */*/1/3/")771 "- */*/1/3/")
760 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/filelist.txt"])772 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
761 self.restore_and_check()773 self.restore_and_check()
762774
763 @unittest.expectedFailure775 @unittest.expectedFailure
764 def test_exclude_globbing_filelist_trailing_slashes_double_wildcards_excludes(self):776 def test_exclude_filelist_trailing_slashes_double_wildcards_excludes(self):
765 """test_exclude_globbing_filelist_trailing_slashes with double wildcards in excludes."""777 """test_exclude_filelist_trailing_slashes with double wildcards in excludes."""
766 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)778 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
767 with open("testfiles/filelist.txt", 'w') as f:779 with open("testfiles/filelist.txt", 'w') as f:
768 f.write("+ testfiles/select/1/2/1/\n"780 f.write("+ testfiles/select/1/2/1/\n"
769 "- **/1/2/\n"781 "- **/1/2/\n"
770 "- **/1/1/\n"782 "- **/1/1/\n"
771 "- **/1/3/")783 "- **/1/3/")
772 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/filelist.txt"])784 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
773 self.restore_and_check()785 self.restore_and_check()
774786
775 @unittest.expectedFailure787 @unittest.expectedFailure
776 def test_exclude_globbing_filelist_trailing_slashes_double_wildcards_excludes(self):788 def test_exclude_filelist_trailing_slashes_double_wildcards_excludes(self):
777 """test_exclude_globbing_filelist_trailing_slashes with double wildcards in excludes."""789 """test_exclude_filelist_trailing_slashes with double wildcards in excludes."""
778 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482) and likely790 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482) and likely
779 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)791 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
780 with open("testfiles/filelist.txt", 'w') as f:792 with open("testfiles/filelist.txt", 'w') as f:
@@ -782,11 +794,11 @@
782 "- **/1/2/\n"794 "- **/1/2/\n"
783 "- **/1/1/\n"795 "- **/1/1/\n"
784 "- **/1/3/")796 "- **/1/3/")
785 self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/filelist.txt"])797 self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
786 self.restore_and_check()798 self.restore_and_check()
787799
788 @unittest.expectedFailure800 @unittest.expectedFailure
789 def test_exclude_globbing_filelist_trailing_slashes_wildcards(self):801 def test_exclude_filelist_trailing_slashes_wildcards(self):
790 """test_commandline_asterisks_single_excludes_only with trailing slashes."""802 """test_commandline_asterisks_single_excludes_only with trailing slashes."""
791 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)803 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
792 self.backup("full", "testfiles/select/1",804 self.backup("full", "testfiles/select/1",
@@ -796,7 +808,5 @@
796 "--exclude", "*/select/1/3/"])808 "--exclude", "*/select/1/3/"])
797 self.restore_and_check()809 self.restore_and_check()
798810
799
800
801if __name__ == "__main__":811if __name__ == "__main__":
802 unittest.main()812 unittest.main()
803813
=== added file 'testing/stdin_test.sh'
--- testing/stdin_test.sh 1970-01-01 00:00:00 +0000
+++ testing/stdin_test.sh 2015-03-12 21:50:57 +0000
@@ -0,0 +1,203 @@
1#!/bin/sh
2# Script to show the current behaviour of duplicity's --include/exclude-filelist-stdin
3# function. This is currently hard to show in functional tests because the stdin-processing
4# logic is in the commandline parser.
5# (c) 2015 Aaron Whitehouse <aaron@whitehouse.kiwi.nz>
6# GPLv2 or any later version
7export PASSPHRASE=test
8
9TESTDIR=/tmp/duplicity_test
10mkdir $TESTDIR
11SOURCEDIR=$TESTDIR/dup_source
12mkdir $SOURCEDIR
13TARGETDIR=$TESTDIR/dup_target
14mkdir $TARGETDIR
15RESTOREDIR=$TESTDIR/dup_restore
16mkdir $RESTOREDIR
17
18tar -C $SOURCEDIR -xvf testfiles.tar.gz testfiles/select
19
20DUPLICITY_CMD="../bin/duplicity"
21export PYTHONPATH=../
22
23$DUPLICITY_CMD -V
24
25echo "==========="
26echo "FIRST TEST."
27echo "==========="
28TEST1="Test with exclude-globbing"
29echo "${TEST1}"
30echo "+ $SOURCEDIR/testfiles/select/1/1" > $TESTDIR/exclude.txt
31echo "- $SOURCEDIR/testfiles/select/1/2" >> $TESTDIR/exclude.txt
32echo "+ $SOURCEDIR/testfiles/select/1/3" >> $TESTDIR/exclude.txt
33echo "- $SOURCEDIR/testfiles/select/3" >> $TESTDIR/exclude.txt
34echo "- $SOURCEDIR/**" >> $TESTDIR/exclude.txt
35
36$DUPLICITY_CMD --exclude-globbing-filelist $TESTDIR/exclude.txt $SOURCEDIR file://$TARGETDIR
37$DUPLICITY_CMD file://$TARGETDIR $RESTOREDIR
38echo "Number of files/folders:"
39OUTPUT_TEST1="$(find $RESTOREDIR | wc -l)"
40echo "${OUTPUT_TEST1}"
41
42rm -r $TESTDIR
43
44echo "==========="
45echo "SECOND TEST."
46echo "==========="
47TEST2="Test with exclude"
48echo "${TEST2}"
49
50mkdir $TESTDIR
51mkdir $SOURCEDIR
52mkdir $TARGETDIR
53mkdir $RESTOREDIR
54tar -C $SOURCEDIR -xvf testfiles.tar.gz testfiles/select
55
56echo "+ $SOURCEDIR/testfiles/select/1/1" > $TESTDIR/exclude.txt
57echo "- $SOURCEDIR/testfiles/select/1/2" >> $TESTDIR/exclude.txt
58echo "+ $SOURCEDIR/testfiles/select/1/3" >> $TESTDIR/exclude.txt
59echo "- $SOURCEDIR/testfiles/select/3" >> $TESTDIR/exclude.txt
60echo "- $SOURCEDIR/**" >> $TESTDIR/exclude.txt
61
62$DUPLICITY_CMD --exclude-filelist $TESTDIR/exclude.txt $SOURCEDIR file://$TARGETDIR
63$DUPLICITY_CMD file://$TARGETDIR $RESTOREDIR
64echo "Number of files/folders:"
65find $RESTOREDIR | wc -l
66OUTPUT_TEST2="$(find $RESTOREDIR | wc -l)"
67echo "${OUTPUT_TEST2}"
68
69rm -r $TESTDIR
70
71echo "==========="
72echo "THIRD TEST."
73echo "==========="
74TEST3="Test with stdin with exclude"
75echo "${TEST3}"
76mkdir $TESTDIR
77mkdir $SOURCEDIR
78mkdir $TARGETDIR
79mkdir $RESTOREDIR
80tar -C $SOURCEDIR -xvf testfiles.tar.gz testfiles/select
81
82echo "+ $SOURCEDIR/testfiles/select/1/1" > $TESTDIR/exclude.txt
83echo "- $SOURCEDIR/testfiles/select/1/2" >> $TESTDIR/exclude.txt
84echo "+ $SOURCEDIR/testfiles/select/1/3" >> $TESTDIR/exclude.txt
85echo "- $SOURCEDIR/testfiles/select/3" >> $TESTDIR/exclude.txt
86echo "- $SOURCEDIR/**" >> $TESTDIR/exclude.txt
87
88cat $TESTDIR/exclude.txt | $DUPLICITY_CMD --exclude-filelist-stdin $SOURCEDIR file://$TARGETDIR
89$DUPLICITY_CMD file://$TARGETDIR $RESTOREDIR
90echo "Number of files/folders:"
91OUTPUT_TEST3="$(find $RESTOREDIR | wc -l)"
92echo "${OUTPUT_TEST3}"
93
94rm -r $TESTDIR
95
96echo "==========="
97echo "FOURTH TEST."
98echo "==========="
99TEST4="Test with nothing"
100echo "${TEST4}"
101mkdir $TESTDIR
102mkdir $SOURCEDIR
103mkdir $TARGETDIR
104mkdir $RESTOREDIR
105tar -C $SOURCEDIR -xvf testfiles.tar.gz testfiles/select
106
107echo "+ $SOURCEDIR/testfiles/select/1/1" > $TESTDIR/exclude.txt
108echo "- $SOURCEDIR/testfiles/select/1/2" >> $TESTDIR/exclude.txt
109echo "+ $SOURCEDIR/testfiles/select/1/3" >> $TESTDIR/exclude.txt
110echo "- $SOURCEDIR/testfiles/select/3" >> $TESTDIR/exclude.txt
111echo "- $SOURCEDIR/**" >> $TESTDIR/exclude.txt
112
113$DUPLICITY_CMD $SOURCEDIR file://$TARGETDIR
114$DUPLICITY_CMD file://$TARGETDIR $RESTOREDIR
115echo "Number of files/folders:"
116OUTPUT_TEST4="$(find $RESTOREDIR | wc -l)"
117echo "${OUTPUT_TEST4}"
118
119rm -r $TESTDIR
120
121echo "==========="
122echo "FIFTH TEST."
123echo "==========="
124TEST5="Test using /dev/stdin as a substitute for --exclude-filelist-stdin"
125echo "${TEST5}"
126mkdir $TESTDIR
127mkdir $SOURCEDIR
128mkdir $TARGETDIR
129mkdir $RESTOREDIR
130tar -C $SOURCEDIR -xvf testfiles.tar.gz testfiles/select
131
132echo "+ $SOURCEDIR/testfiles/select/1/1" > $TESTDIR/exclude.txt
133echo "- $SOURCEDIR/testfiles/select/1/2" >> $TESTDIR/exclude.txt
134echo "+ $SOURCEDIR/testfiles/select/1/3" >> $TESTDIR/exclude.txt
135echo "- $SOURCEDIR/testfiles/select/3" >> $TESTDIR/exclude.txt
136echo "- $SOURCEDIR/**" >> $TESTDIR/exclude.txt
137
138cat $TESTDIR/exclude.txt | $DUPLICITY_CMD --exclude-filelist /dev/stdin $SOURCEDIR file://$TARGETDIR
139$DUPLICITY_CMD file://$TARGETDIR $RESTOREDIR
140echo "Number of files/folders:"
141OUTPUT_TEST5="$(find $RESTOREDIR | wc -l)"
142echo "${OUTPUT_TEST5}"
143
144rm -r $TESTDIR
145
146echo "==========="
147echo "SIXTH TEST."
148echo "==========="
149TEST6="Test with stdin with include"
150echo "${TEST6}"
151mkdir $TESTDIR
152mkdir $SOURCEDIR
153mkdir $TARGETDIR
154mkdir $RESTOREDIR
155tar -C $SOURCEDIR -xvf testfiles.tar.gz testfiles/select
156
157echo "+ $SOURCEDIR/testfiles/select/1/1" > $TESTDIR/include.txt
158echo "- $SOURCEDIR/testfiles/select/1/2" >> $TESTDIR/include.txt
159echo "+ $SOURCEDIR/testfiles/select/1/3" >> $TESTDIR/include.txt
160echo "- $SOURCEDIR/testfiles/select/3" >> $TESTDIR/include.txt
161echo "- $SOURCEDIR/**" >> $TESTDIR/include.txt
162
163cat $TESTDIR/include.txt | $DUPLICITY_CMD --include-filelist-stdin $SOURCEDIR file://$TARGETDIR
164$DUPLICITY_CMD file://$TARGETDIR $RESTOREDIR
165echo "Number of files/folders:"
166OUTPUT_TEST6="$(find $RESTOREDIR | wc -l)"
167echo "${OUTPUT_TEST6}"
168
169rm -r $TESTDIR
170
171echo "============"
172echo "SEVENTH TEST."
173echo "============"
174TEST7="Test using /dev/stdin as a substitute for --include-filelist-stdin"
175echo "${TEST7}"
176mkdir $TESTDIR
177mkdir $SOURCEDIR
178mkdir $TARGETDIR
179mkdir $RESTOREDIR
180tar -C $SOURCEDIR -xvf testfiles.tar.gz testfiles/select
181
182echo "+ $SOURCEDIR/testfiles/select/1/1" > $TESTDIR/include.txt
183echo "- $SOURCEDIR/testfiles/select/1/2" >> $TESTDIR/include.txt
184echo "+ $SOURCEDIR/testfiles/select/1/3" >> $TESTDIR/include.txt
185echo "- $SOURCEDIR/testfiles/select/3" >> $TESTDIR/include.txt
186echo "- $SOURCEDIR/**" >> $TESTDIR/include.txt
187
188cat $TESTDIR/include.txt | $DUPLICITY_CMD --include-filelist /dev/stdin $SOURCEDIR file://$TARGETDIR
189$DUPLICITY_CMD file://$TARGETDIR $RESTOREDIR
190echo "Number of files/folders:"
191OUTPUT_TEST7="$(find $RESTOREDIR | wc -l)"
192echo "${OUTPUT_TEST7}"
193
194rm -r $TESTDIR
195
196unset PASSPHRASE
197echo "1.""${TEST1}" "${OUTPUT_TEST1}"
198echo "2.""${TEST2}" "${OUTPUT_TEST2}"
199echo "3.""${TEST3}" "${OUTPUT_TEST3}"
200echo "4.""${TEST4}" "${OUTPUT_TEST4}"
201echo "5.""${TEST5}" "${OUTPUT_TEST5}"
202echo "6.""${TEST6}" "${OUTPUT_TEST6}"
203echo "7.""${TEST7}" "${OUTPUT_TEST7}"
0204
=== modified file 'testing/unit/test_selection.py'
--- testing/unit/test_selection.py 2015-02-01 17:37:37 +0000
+++ testing/unit/test_selection.py 2015-03-12 21:50:57 +0000
@@ -102,311 +102,6 @@
102 assert sf2(self.makeext("what/ever.py")) == 0102 assert sf2(self.makeext("what/ever.py")) == 0
103 assert sf2(self.makeext("what/ever.py/foo")) == 0103 assert sf2(self.makeext("what/ever.py/foo")) == 0
104104
105 def testFilelistInclude(self):
106 """Test included filelist"""
107 fp = StringIO.StringIO("""
108testfiles/select/1/2
109testfiles/select/1
110testfiles/select/1/2/3
111testfiles/select/3/3/2""")
112 sf = self.Select.filelist_get_sf(fp, 1, "test")
113 assert sf(self.root) == 1
114 assert sf(self.makeext("1")) == 1
115 assert sf(self.makeext("1/1")) is None
116 assert sf(self.makeext("1/2/3")) == 1
117 assert sf(self.makeext("2/2")) is None
118 assert sf(self.makeext("3")) == 1
119 assert sf(self.makeext("3/3")) == 1
120 assert sf(self.makeext("3/3/3")) is None
121
122 def test_filelist_include_1_trailing_white_space(self):
123 """Test trailing whitespace is ignored in included filelist (1 space)"""
124 fp = StringIO.StringIO("testfiles/select/1/2\n"
125 "testfiles/select/1 \n"
126 "testfiles/select/1/2/3\n"
127 "testfiles/select/3/3/2")
128 sf = self.Select.filelist_get_sf(fp, 1, "test")
129 assert sf(self.root) == 1
130 assert sf(self.makeext("1")) == 1
131 assert sf(self.makeext("1/1")) is None
132 assert sf(self.makeext("1/2/3")) == 1
133 assert sf(self.makeext("2/2")) is None
134 assert sf(self.makeext("3")) == 1
135 assert sf(self.makeext("3/3")) == 1
136 assert sf(self.makeext("3/3/3")) is None
137
138 def test_filelist_include_2_trailing_white_spaces(self):
139 """Test trailing whitespace is ignored in included filelist (2 space)"""
140 fp = StringIO.StringIO("testfiles/select/1/2\n"
141 "testfiles/select/1\n"
142 "testfiles/select/1/2/3 \n"
143 "testfiles/select/3/3/2")
144 sf = self.Select.filelist_get_sf(fp, 1, "test")
145 assert sf(self.root) == 1
146 assert sf(self.makeext("1")) == 1
147 assert sf(self.makeext("1/1")) is None
148 assert sf(self.makeext("1/2/3")) == 1
149 assert sf(self.makeext("2/2")) is None
150 assert sf(self.makeext("3")) == 1
151 assert sf(self.makeext("3/3")) == 1
152 assert sf(self.makeext("3/3/3")) is None
153
154 def test_filelist_include_1_leading_white_space(self):
155 """Test leading whitespace is ignored in included filelist (1 space)"""
156 fp = StringIO.StringIO(" testfiles/select/1/2\n"
157 "testfiles/select/1\n"
158 "testfiles/select/1/2/3\n"
159 "testfiles/select/3/3/2")
160 sf = self.Select.filelist_get_sf(fp, 1, "test")
161 assert sf(self.root) == 1
162 assert sf(self.makeext("1")) == 1
163 assert sf(self.makeext("1/1")) is None
164 assert sf(self.makeext("1/2/3")) == 1
165 assert sf(self.makeext("2/2")) is None
166 assert sf(self.makeext("3")) == 1
167 assert sf(self.makeext("3/3")) == 1
168 assert sf(self.makeext("3/3/3")) is None
169
170 def test_filelist_include_2_leading_white_spaces(self):
171 """Test leading whitespace is ignored in included filelist (1 space)"""
172 fp = StringIO.StringIO("testfiles/select/1/2\n"
173 "testfiles/select/1\n"
174 "testfiles/select/1/2/3\n"
175 " testfiles/select/3/3/2")
176 sf = self.Select.filelist_get_sf(fp, 1, "test")
177 assert sf(self.root) == 1
178 assert sf(self.makeext("1")) == 1
179 assert sf(self.makeext("1/1")) is None
180 assert sf(self.makeext("1/2/3")) == 1
181 assert sf(self.makeext("2/2")) is None
182 assert sf(self.makeext("3")) == 1
183 assert sf(self.makeext("3/3")) == 1
184 assert sf(self.makeext("3/3/3")) is None
185
186 def testFilelistIncludeNullSep(self):
187 """Test included filelist but with null_separator set"""
188 fp = StringIO.StringIO("""\0testfiles/select/1/2\0testfiles/select/1\0testfiles/select/1/2/3\0testfiles/select/3/3/2\0testfiles/select/hello\nthere\0""")
189 self.set_global('null_separator', 1)
190 sf = self.Select.filelist_get_sf(fp, 1, "test")
191 assert sf(self.root) == 1
192 assert sf(self.makeext("1")) == 1
193 assert sf(self.makeext("1/1")) is None
194 assert sf(self.makeext("1/2/3")) == 1
195 assert sf(self.makeext("2/2")) is None
196 assert sf(self.makeext("3")) == 1
197 assert sf(self.makeext("3/3")) == 1
198 assert sf(self.makeext("3/3/3")) is None
199 assert sf(self.makeext("hello\nthere")) == 1
200
201 def testFilelistExclude(self):
202 """Test included filelist"""
203 fp = StringIO.StringIO("""
204testfiles/select/1/2
205testfiles/select/1
206this is a badly formed line which should be ignored
207
208testfiles/select/1/2/3
209testfiles/select/3/3/2""")
210 sf = self.Select.filelist_get_sf(fp, 0, "test")
211 assert sf(self.root) is None
212 assert sf(self.makeext("1")) == 0
213 assert sf(self.makeext("1/1")) == 0
214 assert sf(self.makeext("1/2/3")) == 0
215 assert sf(self.makeext("2/2")) is None
216 assert sf(self.makeext("3")) is None
217 assert sf(self.makeext("3/3/2")) == 0
218 assert sf(self.makeext("3/3/3")) is None
219
220 def testFilelistInclude2(self):
221 """testFilelistInclude2 - with modifiers"""
222 fp = StringIO.StringIO("""
223testfiles/select/1/1
224- testfiles/select/1/2
225+ testfiles/select/1/3
226- testfiles/select/3""")
227 sf = self.Select.filelist_get_sf(fp, 1, "test1")
228 assert sf(self.makeext("1")) == 1
229 assert sf(self.makeext("1/1")) == 1
230 assert sf(self.makeext("1/1/2")) is None
231 assert sf(self.makeext("1/2")) == 0
232 assert sf(self.makeext("1/2/3")) == 0
233 assert sf(self.makeext("1/3")) == 1
234 assert sf(self.makeext("2")) is None
235 assert sf(self.makeext("3")) == 0
236
237 def testFilelistInclude3(self):
238 """testFilelistInclude3 - with modifiers to check - works as expected"""
239 fp = StringIO.StringIO("""
240testfiles/select/1/1
241- testfiles/select/1/2
242+ testfiles/select/1/3
243testfiles/select/1""")
244 sf = self.Select.filelist_get_sf(fp, 1, "test1")
245 assert sf(self.makeext("1")) == 1
246 assert sf(self.makeext("1/1")) == 1
247 assert sf(self.makeext("1/1/2")) is None
248 assert sf(self.makeext("1/2")) == 0
249 assert sf(self.makeext("1/2/3")) == 0
250 assert sf(self.makeext("1/3")) == 1
251 assert sf(self.makeext("2")) is None
252 assert sf(self.makeext("3")) is None
253
254# def test_filelist_include_excluded_folder_with_included_contents(self):
255# """Check that excluded folder is included if subfolder is included at higher priority. """
256# # ToDo - currently fails. 1/2 should be included (scanned) because 1/2/1 is. Commandline --include/--exclude
257# # ToDo - and globbing filelists work this way
258# fp = StringIO.StringIO("""
259# + testfiles/select/1/2/1
260# - testfiles/select/1/2
261# + testfiles/select/1/3
262# testfiles/select/1""")
263# sf = self.Select.filelist_get_sf(fp, 1, "test1")
264# assert sf(self.makeext("1")) == 1
265# assert sf(self.makeext("1/1")) is None
266# assert sf(self.makeext("1/2/1")) == 1
267# assert sf(self.makeext("1/2")) == 0 # ToDo - what should this return?
268# assert sf(self.makeext("1/2/3")) == 0
269# assert sf(self.makeext("1/3")) == 1
270# assert sf(self.makeext("2")) is None
271# assert sf(self.makeext("3")) is None
272
273 def testFilelistExclude2(self):
274 """testFilelistExclude2 - with modifiers"""
275 fp = StringIO.StringIO("""
276testfiles/select/1/1
277- testfiles/select/1/2
278+ testfiles/select/1/3
279- testfiles/select/3""")
280 sf = self.Select.filelist_get_sf(fp, 0, "test1")
281 sf_val1 = sf(self.root)
282 assert sf_val1 == 1 or sf_val1 is None # either is OK
283 sf_val2 = sf(self.makeext("1"))
284 assert sf_val2 == 1 or sf_val2 is None
285 assert sf(self.makeext("1/1")) == 0
286 assert sf(self.makeext("1/1/2")) == 0
287 assert sf(self.makeext("1/2")) == 0
288 assert sf(self.makeext("1/2/3")) == 0
289 assert sf(self.makeext("1/3")) == 1
290 assert sf(self.makeext("2")) is None
291 assert sf(self.makeext("3")) == 0
292
293 def test_filelist_exclude_2_with_trailing_white_space(self):
294 """testFilelistExclude2 with modifiers - test trailing whitespace is ignored (1 and 2 spaces)"""
295 fp = StringIO.StringIO("testfiles/select/1/1\n"
296 "- testfiles/select/1/2 \n"
297 "+ testfiles/select/1/3 \n"
298 "- testfiles/select/3")
299 sf = self.Select.filelist_get_sf(fp, 0, "test1")
300 sf_val1 = sf(self.root)
301 assert sf_val1 == 1 or sf_val1 is None # either is OK
302 sf_val2 = sf(self.makeext("1"))
303 assert sf_val2 == 1 or sf_val2 is None
304 assert sf(self.makeext("1/1")) == 0
305 assert sf(self.makeext("1/1/2")) == 0
306 assert sf(self.makeext("1/2")) == 0
307 assert sf(self.makeext("1/2/3")) == 0
308 assert sf(self.makeext("1/3")) == 1
309 assert sf(self.makeext("2")) is None
310 assert sf(self.makeext("3")) == 0
311
312 def test_filelist_exclude_with_single_quotes(self):
313 """testFilelistExclude2 with modifiers - test unnecessary single quotes are ignored"""
314 fp = StringIO.StringIO("testfiles/select/1/1\n"
315 "- testfiles/select/1/2\n"
316 "+ 'testfiles/select/1/3'\n"
317 "- testfiles/select/3")
318 sf = self.Select.filelist_get_sf(fp, 0, "test1")
319 sf_val1 = sf(self.root)
320 assert sf_val1 == 1 or sf_val1 is None # either is OK
321 sf_val2 = sf(self.makeext("1"))
322 assert sf_val2 == 1 or sf_val2 is None
323 assert sf(self.makeext("1/1")) == 0
324 assert sf(self.makeext("1/1/2")) == 0
325 assert sf(self.makeext("1/2")) == 0
326 assert sf(self.makeext("1/2/3")) == 0
327 assert sf(self.makeext("1/3")) == 1
328 assert sf(self.makeext("2")) is None
329 assert sf(self.makeext("3")) == 0
330
331 def test_filelist_exclude_with_full_line_comment(self):
332 """testFilelistExclude2 with modifiers - test full-line comment is ignored"""
333 fp = StringIO.StringIO("testfiles/select/1/1\n"
334 "- testfiles/select/1/2\n"
335 "# This is a full-line comment\n"
336 "+ testfiles/select/1/3\n"
337 "- testfiles/select/3")
338 sf = self.Select.filelist_get_sf(fp, 0, "test1")
339 sf_val1 = sf(self.root)
340 assert sf_val1 == 1 or sf_val1 is None # either is OK
341 sf_val2 = sf(self.makeext("1"))
342 assert sf_val2 == 1 or sf_val2 is None
343 assert sf(self.makeext("1/1")) == 0
344 assert sf(self.makeext("1/1/2")) == 0
345 assert sf(self.makeext("1/2")) == 0
346 assert sf(self.makeext("1/2/3")) == 0
347 assert sf(self.makeext("1/3")) == 1
348 assert sf(self.makeext("2")) is None
349 assert sf(self.makeext("3")) == 0
350
351 def test_filelist_exclude_with_blank_line(self):
352 """testFilelistExclude2 with modifiers - test blank line is ignored"""
353 fp = StringIO.StringIO("testfiles/select/1/1\n"
354 "- testfiles/select/1/2\n"
355 "\n"
356 "+ testfiles/select/1/3\n"
357 "- testfiles/select/3")
358 sf = self.Select.filelist_get_sf(fp, 0, "test1")
359 sf_val1 = sf(self.root)
360 assert sf_val1 == 1 or sf_val1 is None # either is OK
361 sf_val2 = sf(self.makeext("1"))
362 assert sf_val2 == 1 or sf_val2 is None
363 assert sf(self.makeext("1/1")) == 0
364 assert sf(self.makeext("1/1/2")) == 0
365 assert sf(self.makeext("1/2")) == 0
366 assert sf(self.makeext("1/2/3")) == 0
367 assert sf(self.makeext("1/3")) == 1
368 assert sf(self.makeext("2")) is None
369 assert sf(self.makeext("3")) == 0
370
371 def test_filelist_exclude_with_blank_line_and_whitespace(self):
372 """testFilelistExclude2 with modifiers - test blank line with whitespace is ignored"""
373 fp = StringIO.StringIO("testfiles/select/1/1\n"
374 "- testfiles/select/1/2\n"
375 " \n"
376 "+ testfiles/select/1/3\n"
377 "- testfiles/select/3")
378 sf = self.Select.filelist_get_sf(fp, 0, "test1")
379 sf_val1 = sf(self.root)
380 assert sf_val1 == 1 or sf_val1 is None # either is OK
381 sf_val2 = sf(self.makeext("1"))
382 assert sf_val2 == 1 or sf_val2 is None
383 assert sf(self.makeext("1/1")) == 0
384 assert sf(self.makeext("1/1/2")) == 0
385 assert sf(self.makeext("1/2")) == 0
386 assert sf(self.makeext("1/2/3")) == 0
387 assert sf(self.makeext("1/3")) == 1
388 assert sf(self.makeext("2")) is None
389 assert sf(self.makeext("3")) == 0
390
391 def test_filelist_exclude_with_double_quotes(self):
392 """testFilelistExclude2 with modifiers - test unnecessary double quotes are ignored"""
393 fp = StringIO.StringIO('testfiles/select/1/1\n'
394 '- testfiles/select/1/2\n'
395 '+ "testfiles/select/1/3"\n'
396 '- testfiles/select/3')
397 sf = self.Select.filelist_get_sf(fp, 0, "test1")
398 sf_val1 = sf(self.root)
399 assert sf_val1 == 1 or sf_val1 is None # either is OK
400 sf_val2 = sf(self.makeext("1"))
401 assert sf_val2 == 1 or sf_val2 is None
402 assert sf(self.makeext("1/1")) == 0
403 assert sf(self.makeext("1/1/2")) == 0
404 assert sf(self.makeext("1/2")) == 0
405 assert sf(self.makeext("1/2/3")) == 0
406 assert sf(self.makeext("1/3")) == 1
407 assert sf(self.makeext("2")) is None
408 assert sf(self.makeext("3")) == 0
409
410 def testGlobRE(self):105 def testGlobRE(self):
411 """testGlobRE - test translation of shell pattern to regular exp"""106 """testGlobRE - test translation of shell pattern to regular exp"""
412 assert self.Select.glob_to_re("hello") == "hello"107 assert self.Select.glob_to_re("hello") == "hello"
@@ -456,12 +151,6 @@
456 assert select.glob_get_sf("**", 0)(root) == 0151 assert select.glob_get_sf("**", 0)(root) == 0
457 assert select.glob_get_sf("/foo/*", 0)(root) is None152 assert select.glob_get_sf("/foo/*", 0)(root) is None
458153
459 assert select.filelist_get_sf(StringIO.StringIO("/"), 1, "test")(root) == 1
460 assert select.filelist_get_sf(StringIO.StringIO("/foo/bar"), 1, "test")(root) == 1
461 assert select.filelist_get_sf(StringIO.StringIO("/"), 0, "test")(root) == 0
462 assert select.filelist_get_sf(StringIO.StringIO("/foo/bar"), 0,
463 "test")(root) is None
464
465 def testOtherFilesystems(self):154 def testOtherFilesystems(self):
466 """Test to see if --exclude-other-filesystems works correctly"""155 """Test to see if --exclude-other-filesystems works correctly"""
467 root = Path("/")156 root = Path("/")
@@ -531,9 +220,9 @@
531 [(), ('1',), ('1', '1'), ('1', '1', '2'),220 [(), ('1',), ('1', '1'), ('1', '1', '2'),
532 ('1', '1', '3')])221 ('1', '1', '3')])
533222
534 def test_globbing_filelist(self):223 def test_filelist(self):
535 """Filelist glob test similar to above testParse2"""224 """Filelist glob test similar to above testParse2"""
536 self.ParseTest([("--include-globbing-filelist", "file")],225 self.ParseTest([("--include-filelist", "file")],
537 [(), ('1',), ('1', '1'), ('1', '1', '2'),226 [(), ('1',), ('1', '1'), ('1', '1', '2'),
538 ('1', '1', '3')],227 ('1', '1', '3')],
539 ["- testfiles/select/1/1/1\n"228 ["- testfiles/select/1/1/1\n"
@@ -541,9 +230,9 @@
541 "- testfiles/select/1\n"230 "- testfiles/select/1\n"
542 "- **"])231 "- **"])
543232
544 def test_include_globbing_filelist_1_trailing_whitespace(self):233 def test_include_filelist_1_trailing_whitespace(self):
545 """Filelist glob test similar to globbing filelist, but with 1 trailing whitespace on include"""234 """Filelist glob test similar to globbing filelist, but with 1 trailing whitespace on include"""
546 self.ParseTest([("--include-globbing-filelist", "file")],235 self.ParseTest([("--include-filelist", "file")],
547 [(), ('1',), ('1', '1'), ('1', '1', '2'),236 [(), ('1',), ('1', '1'), ('1', '1', '2'),
548 ('1', '1', '3')],237 ('1', '1', '3')],
549 ["- testfiles/select/1/1/1\n"238 ["- testfiles/select/1/1/1\n"
@@ -551,9 +240,9 @@
551 "- testfiles/select/1\n"240 "- testfiles/select/1\n"
552 "- **"])241 "- **"])
553242
554 def test_include_globbing_filelist_2_trailing_whitespaces(self):243 def test_include_filelist_2_trailing_whitespaces(self):
555 """Filelist glob test similar to globbing filelist, but with 2 trailing whitespaces on include"""244 """Filelist glob test similar to globbing filelist, but with 2 trailing whitespaces on include"""
556 self.ParseTest([("--include-globbing-filelist", "file")],245 self.ParseTest([("--include-filelist", "file")],
557 [(), ('1',), ('1', '1'), ('1', '1', '2'),246 [(), ('1',), ('1', '1'), ('1', '1', '2'),
558 ('1', '1', '3')],247 ('1', '1', '3')],
559 ["- testfiles/select/1/1/1\n"248 ["- testfiles/select/1/1/1\n"
@@ -561,9 +250,9 @@
561 "- testfiles/select/1\n"250 "- testfiles/select/1\n"
562 "- **"])251 "- **"])
563252
564 def test_include_globbing_filelist_1_leading_whitespace(self):253 def test_include_filelist_1_leading_whitespace(self):
565 """Filelist glob test similar to globbing filelist, but with 1 leading whitespace on include"""254 """Filelist glob test similar to globbing filelist, but with 1 leading whitespace on include"""
566 self.ParseTest([("--include-globbing-filelist", "file")],255 self.ParseTest([("--include-filelist", "file")],
567 [(), ('1',), ('1', '1'), ('1', '1', '2'),256 [(), ('1',), ('1', '1'), ('1', '1', '2'),
568 ('1', '1', '3')],257 ('1', '1', '3')],
569 ["- testfiles/select/1/1/1\n"258 ["- testfiles/select/1/1/1\n"
@@ -571,9 +260,9 @@
571 "- testfiles/select/1\n"260 "- testfiles/select/1\n"
572 "- **"])261 "- **"])
573262
574 def test_include_globbing_filelist_2_leading_whitespaces(self):263 def test_include_filelist_2_leading_whitespaces(self):
575 """Filelist glob test similar to globbing filelist, but with 2 leading whitespaces on include"""264 """Filelist glob test similar to globbing filelist, but with 2 leading whitespaces on include"""
576 self.ParseTest([("--include-globbing-filelist", "file")],265 self.ParseTest([("--include-filelist", "file")],
577 [(), ('1',), ('1', '1'), ('1', '1', '2'),266 [(), ('1',), ('1', '1'), ('1', '1', '2'),
578 ('1', '1', '3')],267 ('1', '1', '3')],
579 ["- testfiles/select/1/1/1\n"268 ["- testfiles/select/1/1/1\n"
@@ -581,9 +270,9 @@
581 "- testfiles/select/1\n"270 "- testfiles/select/1\n"
582 "- **"])271 "- **"])
583272
584 def test_include_globbing_filelist_1_trailing_whitespace_exclude(self):273 def test_include_filelist_1_trailing_whitespace_exclude(self):
585 """Filelist glob test similar to globbing filelist, but with 1 trailing whitespace on exclude"""274 """Filelist glob test similar to globbing filelist, but with 1 trailing whitespace on exclude"""
586 self.ParseTest([("--include-globbing-filelist", "file")],275 self.ParseTest([("--include-filelist", "file")],
587 [(), ('1',), ('1', '1'), ('1', '1', '2'),276 [(), ('1',), ('1', '1'), ('1', '1', '2'),
588 ('1', '1', '3')],277 ('1', '1', '3')],
589 ["- testfiles/select/1/1/1 \n"278 ["- testfiles/select/1/1/1 \n"
@@ -591,9 +280,9 @@
591 "- testfiles/select/1\n"280 "- testfiles/select/1\n"
592 "- **"])281 "- **"])
593282
594 def test_include_globbing_filelist_2_trailing_whitespace_exclude(self):283 def test_include_filelist_2_trailing_whitespace_exclude(self):
595 """Filelist glob test similar to globbing filelist, but with 2 trailing whitespaces on exclude"""284 """Filelist glob test similar to globbing filelist, but with 2 trailing whitespaces on exclude"""
596 self.ParseTest([("--include-globbing-filelist", "file")],285 self.ParseTest([("--include-filelist", "file")],
597 [(), ('1',), ('1', '1'), ('1', '1', '2'),286 [(), ('1',), ('1', '1'), ('1', '1', '2'),
598 ('1', '1', '3')],287 ('1', '1', '3')],
599 ["- testfiles/select/1/1/1 \n"288 ["- testfiles/select/1/1/1 \n"
@@ -601,9 +290,9 @@
601 "- testfiles/select/1\n"290 "- testfiles/select/1\n"
602 "- **"])291 "- **"])
603292
604 def test_include_globbing_filelist_1_leading_whitespace_exclude(self):293 def test_include_filelist_1_leading_whitespace_exclude(self):
605 """Filelist glob test similar to globbing filelist, but with 1 leading whitespace on exclude"""294 """Filelist glob test similar to globbing filelist, but with 1 leading whitespace on exclude"""
606 self.ParseTest([("--include-globbing-filelist", "file")],295 self.ParseTest([("--include-filelist", "file")],
607 [(), ('1',), ('1', '1'), ('1', '1', '2'),296 [(), ('1',), ('1', '1'), ('1', '1', '2'),
608 ('1', '1', '3')],297 ('1', '1', '3')],
609 [" - testfiles/select/1/1/1\n"298 [" - testfiles/select/1/1/1\n"
@@ -611,9 +300,9 @@
611 "- testfiles/select/1\n"300 "- testfiles/select/1\n"
612 "- **"])301 "- **"])
613302
614 def test_include_globbing_filelist_2_leading_whitespaces_exclude(self):303 def test_include_filelist_2_leading_whitespaces_exclude(self):
615 """Filelist glob test similar to globbing filelist, but with 2 leading whitespaces on exclude"""304 """Filelist glob test similar to globbing filelist, but with 2 leading whitespaces on exclude"""
616 self.ParseTest([("--include-globbing-filelist", "file")],305 self.ParseTest([("--include-filelist", "file")],
617 [(), ('1',), ('1', '1'), ('1', '1', '2'),306 [(), ('1',), ('1', '1'), ('1', '1', '2'),
618 ('1', '1', '3')],307 ('1', '1', '3')],
619 [" - testfiles/select/1/1/1\n"308 [" - testfiles/select/1/1/1\n"
@@ -621,9 +310,9 @@
621 "- testfiles/select/1\n"310 "- testfiles/select/1\n"
622 "- **"])311 "- **"])
623312
624 def test_include_globbing_filelist_check_excluded_folder_included_for_contents(self):313 def test_include_filelist_check_excluded_folder_included_for_contents(self):
625 """Filelist glob test to check excluded folder is included if contents are"""314 """Filelist glob test to check excluded folder is included if contents are"""
626 self.ParseTest([("--include-globbing-filelist", "file")],315 self.ParseTest([("--include-filelist", "file")],
627 [(), ('1',), ('1', '1'), ('1', '1', '1'), ('1', '1', '2'),316 [(), ('1',), ('1', '1'), ('1', '1', '1'), ('1', '1', '2'),
628 ('1', '1', '3'), ('1', '2'), ('1', '2', '1'), ('1', '3'), ('1', '3', '1'), ('1', '3', '2'),317 ('1', '1', '3'), ('1', '2'), ('1', '2', '1'), ('1', '3'), ('1', '3', '1'), ('1', '3', '2'),
629 ('1', '3', '3')],318 ('1', '3', '3')],
@@ -632,9 +321,9 @@
632 "testfiles/select/1\n"321 "testfiles/select/1\n"
633 "- **"])322 "- **"])
634323
635 def test_include_globbing_filelist_with_unnecessary_quotes(self):324 def test_include_filelist_with_unnecessary_quotes(self):
636 """Filelist glob test similar to globbing filelist, but with quotes around one of the paths."""325 """Filelist glob test similar to globbing filelist, but with quotes around one of the paths."""
637 self.ParseTest([("--include-globbing-filelist", "file")],326 self.ParseTest([("--include-filelist", "file")],
638 [(), ('1',), ('1', '1'), ('1', '1', '2'),327 [(), ('1',), ('1', '1'), ('1', '1', '2'),
639 ('1', '1', '3')],328 ('1', '1', '3')],
640 ["- 'testfiles/select/1/1/1'\n"329 ["- 'testfiles/select/1/1/1'\n"
@@ -642,9 +331,9 @@
642 "- testfiles/select/1\n"331 "- testfiles/select/1\n"
643 "- **"])332 "- **"])
644333
645 def test_include_globbing_filelist_with_unnecessary_double_quotes(self):334 def test_include_filelist_with_unnecessary_double_quotes(self):
646 """Filelist glob test similar to globbing filelist, but with double quotes around one of the paths."""335 """Filelist glob test similar to globbing filelist, but with double quotes around one of the paths."""
647 self.ParseTest([("--include-globbing-filelist", "file")],336 self.ParseTest([("--include-filelist", "file")],
648 [(), ('1',), ('1', '1'), ('1', '1', '2'),337 [(), ('1',), ('1', '1'), ('1', '1', '2'),
649 ('1', '1', '3')],338 ('1', '1', '3')],
650 ['- "testfiles/select/1/1/1"\n'339 ['- "testfiles/select/1/1/1"\n'
@@ -652,9 +341,9 @@
652 '- testfiles/select/1\n'341 '- testfiles/select/1\n'
653 '- **'])342 '- **'])
654343
655 def test_include_globbing_filelist_with_full_line_comment(self):344 def test_include_filelist_with_full_line_comment(self):
656 """Filelist glob test similar to globbing filelist, but with a full-line comment."""345 """Filelist glob test similar to globbing filelist, but with a full-line comment."""
657 self.ParseTest([("--include-globbing-filelist", "file")],346 self.ParseTest([("--include-filelist", "file")],
658 [(), ('1',), ('1', '1'), ('1', '1', '2'),347 [(), ('1',), ('1', '1'), ('1', '1', '2'),
659 ('1', '1', '3')],348 ('1', '1', '3')],
660 ['- testfiles/select/1/1/1\n'349 ['- testfiles/select/1/1/1\n'
@@ -663,9 +352,9 @@
663 '- testfiles/select/1\n'352 '- testfiles/select/1\n'
664 '- **'])353 '- **'])
665354
666 def test_include_globbing_filelist_with_blank_line(self):355 def test_include_filelist_with_blank_line(self):
667 """Filelist glob test similar to globbing filelist, but with a blank line."""356 """Filelist glob test similar to globbing filelist, but with a blank line."""
668 self.ParseTest([("--include-globbing-filelist", "file")],357 self.ParseTest([("--include-filelist", "file")],
669 [(), ('1',), ('1', '1'), ('1', '1', '2'),358 [(), ('1',), ('1', '1'), ('1', '1', '2'),
670 ('1', '1', '3')],359 ('1', '1', '3')],
671 ['- testfiles/select/1/1/1\n'360 ['- testfiles/select/1/1/1\n'
@@ -674,9 +363,9 @@
674 '- testfiles/select/1\n'363 '- testfiles/select/1\n'
675 '- **'])364 '- **'])
676365
677 def test_include_globbing_filelist_with_blank_line_and_whitespace(self):366 def test_include_filelist_with_blank_line_and_whitespace(self):
678 """Filelist glob test similar to globbing filelist, but with a blank line and whitespace."""367 """Filelist glob test similar to globbing filelist, but with a blank line and whitespace."""
679 self.ParseTest([("--include-globbing-filelist", "file")],368 self.ParseTest([("--include-filelist", "file")],
680 [(), ('1',), ('1', '1'), ('1', '1', '2'),369 [(), ('1',), ('1', '1'), ('1', '1', '2'),
681 ('1', '1', '3')],370 ('1', '1', '3')],
682 ['- testfiles/select/1/1/1\n'371 ['- testfiles/select/1/1/1\n'
@@ -685,19 +374,19 @@
685 '- testfiles/select/1\n'374 '- testfiles/select/1\n'
686 '- **'])375 '- **'])
687376
688 def test_include_globbing_filelist_asterisk(self):377 def test_include_filelist_asterisk(self):
689 """Filelist glob test with * instead of 'testfiles'"""378 """Filelist glob test with * instead of 'testfiles'"""
690 # Thank you to Elifarley Cruz for this test case379 # Thank you to Elifarley Cruz for this test case
691 # (https://bugs.launchpad.net/duplicity/+bug/884371).380 # (https://bugs.launchpad.net/duplicity/+bug/884371).
692 self.ParseTest([("--include-globbing-filelist", "file")],381 self.ParseTest([("--include-filelist", "file")],
693 [(), ('1',), ('1', '1'), ('1', '1', '1'),382 [(), ('1',), ('1', '1'), ('1', '1', '1'),
694 ('1', '1', '2'), ('1', '1', '3')],383 ('1', '1', '2'), ('1', '1', '3')],
695 ["*/select/1/1\n"384 ["*/select/1/1\n"
696 "- **"])385 "- **"])
697386
698 def test_include_globbing_filelist_asterisk_2(self):387 def test_include_filelist_asterisk_2(self):
699 """Identical to test_globbing_filelist, but with the exclude 'select' replaced with '*'"""388 """Identical to test_filelist, but with the exclude 'select' replaced with '*'"""
700 self.ParseTest([("--include-globbing-filelist", "file")],389 self.ParseTest([("--include-filelist", "file")],
701 [(), ('1',), ('1', '1'), ('1', '1', '2'),390 [(), ('1',), ('1', '1'), ('1', '1', '2'),
702 ('1', '1', '3')],391 ('1', '1', '3')],
703 ["- testfiles/*/1/1/1\n"392 ["- testfiles/*/1/1/1\n"
@@ -706,10 +395,10 @@
706 "- **"])395 "- **"])
707396
708 @unittest.expectedFailure397 @unittest.expectedFailure
709 def test_include_globbing_filelist_asterisk_3(self):398 def test_include_filelist_asterisk_3(self):
710 """Identical to test_globbing_filelist, but with the auto-include 'select' replaced with '*'"""399 """Identical to test_filelist, but with the auto-include 'select' replaced with '*'"""
711 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)400 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
712 self.ParseTest([("--include-globbing-filelist", "file")],401 self.ParseTest([("--include-filelist", "file")],
713 [(), ('1',), ('1', '1'), ('1', '1', '2'),402 [(), ('1',), ('1', '1'), ('1', '1', '2'),
714 ('1', '1', '3')],403 ('1', '1', '3')],
715 ["- testfiles/select/1/1/1\n"404 ["- testfiles/select/1/1/1\n"
@@ -718,10 +407,10 @@
718 "- **"])407 "- **"])
719408
720 @unittest.expectedFailure409 @unittest.expectedFailure
721 def test_include_globbing_filelist_asterisk_4(self):410 def test_include_filelist_asterisk_4(self):
722 """Identical to test_globbing_filelist, but with a specific include 'select' replaced with '*'"""411 """Identical to test_filelist, but with a specific include 'select' replaced with '*'"""
723 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)412 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
724 self.ParseTest([("--include-globbing-filelist", "file")],413 self.ParseTest([("--include-filelist", "file")],
725 [(), ('1',), ('1', '1'), ('1', '1', '2'),414 [(), ('1',), ('1', '1'), ('1', '1', '2'),
726 ('1', '1', '3')],415 ('1', '1', '3')],
727 ["- testfiles/select/1/1/1\n"416 ["- testfiles/select/1/1/1\n"
@@ -730,10 +419,10 @@
730 "- **"])419 "- **"])
731420
732 @unittest.expectedFailure421 @unittest.expectedFailure
733 def test_include_globbing_filelist_asterisk_5(self):422 def test_include_filelist_asterisk_5(self):
734 """Identical to test_globbing_filelist, but with all 'select's replaced with '*'"""423 """Identical to test_filelist, but with all 'select's replaced with '*'"""
735 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)424 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
736 self.ParseTest([("--include-globbing-filelist", "file")],425 self.ParseTest([("--include-filelist", "file")],
737 [(), ('1',), ('1', '1'), ('1', '1', '2'),426 [(), ('1',), ('1', '1'), ('1', '1', '2'),
738 ('1', '1', '3')],427 ('1', '1', '3')],
739 ["- testfiles/*/1/1/1\n"428 ["- testfiles/*/1/1/1\n"
@@ -741,9 +430,9 @@
741 "- testfiles/*/1\n"430 "- testfiles/*/1\n"
742 "- **"])431 "- **"])
743432
744 def test_include_globbing_filelist_asterisk_6(self):433 def test_include_filelist_asterisk_6(self):
745 """Identical to test_globbing_filelist, but with numerous excluded folders replaced with '*'"""434 """Identical to test_filelist, but with numerous excluded folders replaced with '*'"""
746 self.ParseTest([("--include-globbing-filelist", "file")],435 self.ParseTest([("--include-filelist", "file")],
747 [(), ('1',), ('1', '1'), ('1', '1', '2'),436 [(), ('1',), ('1', '1'), ('1', '1', '2'),
748 ('1', '1', '3')],437 ('1', '1', '3')],
749 ["- */*/1/1/1\n"438 ["- */*/1/1/1\n"
@@ -752,10 +441,10 @@
752 "- **"])441 "- **"])
753442
754 @unittest.expectedFailure443 @unittest.expectedFailure
755 def test_include_globbing_filelist_asterisk_7(self):444 def test_include_filelist_asterisk_7(self):
756 """Identical to test_globbing_filelist, but with numerous included/excluded folders replaced with '*'"""445 """Identical to test_filelist, but with numerous included/excluded folders replaced with '*'"""
757 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)446 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
758 self.ParseTest([("--include-globbing-filelist", "file")],447 self.ParseTest([("--include-filelist", "file")],
759 [(), ('1',), ('1', '1'), ('1', '1', '2'),448 [(), ('1',), ('1', '1'), ('1', '1', '2'),
760 ('1', '1', '3')],449 ('1', '1', '3')],
761 ["- */*/1/1/1\n"450 ["- */*/1/1/1\n"
@@ -763,9 +452,9 @@
763 "- */*/1\n"452 "- */*/1\n"
764 "- **"])453 "- **"])
765454
766 def test_include_globbing_filelist_double_asterisk_1(self):455 def test_include_filelist_double_asterisk_1(self):
767 """Identical to test_globbing_filelist, but with the exclude 'select' replaced with '**'"""456 """Identical to test_filelist, but with the exclude 'select' replaced with '**'"""
768 self.ParseTest([("--include-globbing-filelist", "file")],457 self.ParseTest([("--include-filelist", "file")],
769 [(), ('1',), ('1', '1'), ('1', '1', '2'),458 [(), ('1',), ('1', '1'), ('1', '1', '2'),
770 ('1', '1', '3')],459 ('1', '1', '3')],
771 ["- testfiles/**/1/1/1\n"460 ["- testfiles/**/1/1/1\n"
@@ -774,10 +463,10 @@
774 "- **"])463 "- **"])
775464
776 @unittest.expectedFailure465 @unittest.expectedFailure
777 def test_include_globbing_filelist_double_asterisk_2(self):466 def test_include_filelist_double_asterisk_2(self):
778 """Identical to test_globbing_filelist, but with the include 'select' replaced with '**'"""467 """Identical to test_filelist, but with the include 'select' replaced with '**'"""
779 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)468 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
780 self.ParseTest([("--include-globbing-filelist", "file")],469 self.ParseTest([("--include-filelist", "file")],
781 [(), ('1',), ('1', '1'), ('1', '1', '2'),470 [(), ('1',), ('1', '1'), ('1', '1', '2'),
782 ('1', '1', '3')],471 ('1', '1', '3')],
783 ["- testfiles/select/1/1/1\n"472 ["- testfiles/select/1/1/1\n"
@@ -785,9 +474,9 @@
785 "- testfiles/select/1\n"474 "- testfiles/select/1\n"
786 "- **"])475 "- **"])
787476
788 def test_include_globbing_filelist_double_asterisk_3(self):477 def test_include_filelist_double_asterisk_3(self):
789 """Identical to test_globbing_filelist, but with the exclude 'testfiles/select' replaced with '**'"""478 """Identical to test_filelist, but with the exclude 'testfiles/select' replaced with '**'"""
790 self.ParseTest([("--include-globbing-filelist", "file")],479 self.ParseTest([("--include-filelist", "file")],
791 [(), ('1',), ('1', '1'), ('1', '1', '2'),480 [(), ('1',), ('1', '1'), ('1', '1', '2'),
792 ('1', '1', '3')],481 ('1', '1', '3')],
793 ["- **/1/1/1\n"482 ["- **/1/1/1\n"
@@ -796,10 +485,10 @@
796 "- **"])485 "- **"])
797486
798 @unittest.expectedFailure487 @unittest.expectedFailure
799 def test_include_globbing_filelist_double_asterisk_4(self):488 def test_include_filelist_double_asterisk_4(self):
800 """Identical to test_globbing_filelist, but with the include 'testfiles/select' replaced with '**'"""489 """Identical to test_filelist, but with the include 'testfiles/select' replaced with '**'"""
801 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)490 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
802 self.ParseTest([("--include-globbing-filelist", "file")],491 self.ParseTest([("--include-filelist", "file")],
803 [(), ('1',), ('1', '1'), ('1', '1', '2'),492 [(), ('1',), ('1', '1'), ('1', '1', '2'),
804 ('1', '1', '3')],493 ('1', '1', '3')],
805 ["- testfiles/select/1/1/1\n"494 ["- testfiles/select/1/1/1\n"
@@ -808,10 +497,10 @@
808 "- **"])497 "- **"])
809498
810 @unittest.expectedFailure499 @unittest.expectedFailure
811 def test_include_globbing_filelist_double_asterisk_5(self):500 def test_include_filelist_double_asterisk_5(self):
812 """Identical to test_globbing_filelist, but with all 'testfiles/select's replaced with '**'"""501 """Identical to test_filelist, but with all 'testfiles/select's replaced with '**'"""
813 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)502 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
814 self.ParseTest([("--include-globbing-filelist", "file")],503 self.ParseTest([("--include-filelist", "file")],
815 [(), ('1',), ('1', '1'), ('1', '1', '2'),504 [(), ('1',), ('1', '1'), ('1', '1', '2'),
816 ('1', '1', '3')],505 ('1', '1', '3')],
817 ["- **/1/1/1\n"506 ["- **/1/1/1\n"
@@ -819,9 +508,9 @@
819 "- **/1\n"508 "- **/1\n"
820 "- **"])509 "- **"])
821510
822 def test_include_globbing_filelist_trailing_slashes(self):511 def test_include_filelist_trailing_slashes(self):
823 """Filelist glob test similar to globbing filelist, but with trailing slashes"""512 """Filelist glob test similar to globbing filelist, but with trailing slashes"""
824 self.ParseTest([("--include-globbing-filelist", "file")],513 self.ParseTest([("--include-filelist", "file")],
825 [(), ('1',), ('1', '1'), ('1', '1', '2'),514 [(), ('1',), ('1', '1'), ('1', '1', '2'),
826 ('1', '1', '3')],515 ('1', '1', '3')],
827 ["- testfiles/select/1/1/1/\n"516 ["- testfiles/select/1/1/1/\n"
@@ -830,10 +519,10 @@
830 "- **"])519 "- **"])
831520
832 @unittest.expectedFailure521 @unittest.expectedFailure
833 def test_include_globbing_filelist_trailing_slashes_and_single_asterisks(self):522 def test_include_filelist_trailing_slashes_and_single_asterisks(self):
834 """Filelist glob test similar to globbing filelist, but with trailing slashes and single asterisks"""523 """Filelist glob test similar to globbing filelist, but with trailing slashes and single asterisks"""
835 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)524 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
836 self.ParseTest([("--include-globbing-filelist", "file")],525 self.ParseTest([("--include-filelist", "file")],
837 [(), ('1',), ('1', '1'), ('1', '1', '2'),526 [(), ('1',), ('1', '1'), ('1', '1', '2'),
838 ('1', '1', '3')],527 ('1', '1', '3')],
839 ["- */select/1/1/1/\n"528 ["- */select/1/1/1/\n"
@@ -842,10 +531,10 @@
842 "- **"])531 "- **"])
843532
844 @unittest.expectedFailure533 @unittest.expectedFailure
845 def test_include_globbing_filelist_trailing_slashes_and_double_asterisks(self):534 def test_include_filelist_trailing_slashes_and_double_asterisks(self):
846 """Filelist glob test similar to globbing filelist, but with trailing slashes and double asterisks"""535 """Filelist glob test similar to globbing filelist, but with trailing slashes and double asterisks"""
847 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)536 # Todo: Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
848 self.ParseTest([("--include-globbing-filelist", "file")],537 self.ParseTest([("--include-filelist", "file")],
849 [(), ('1',), ('1', '1'), ('1', '1', '2'),538 [(), ('1',), ('1', '1'), ('1', '1', '2'),
850 ('1', '1', '3')],539 ('1', '1', '3')],
851 ["- **/1/1/1/\n"540 ["- **/1/1/1/\n"
@@ -853,9 +542,18 @@
853 "- **/1/\n"542 "- **/1/\n"
854 "- **"])543 "- **"])
855544
856 def test_exclude_globbing_filelist(self):545
857 """Exclude version of test_globbing_filelist"""546 def test_filelist_null_separator(self):
858 self.ParseTest([("--exclude-globbing-filelist", "file")],547 """test_filelist, but with null_separator set"""
548 self.set_global('null_separator', 1)
549 self.ParseTest([("--include-filelist", "file")],
550 [(), ('1',), ('1', '1'), ('1', '1', '2'),
551 ('1', '1', '3')],
552 ["\0- testfiles/select/1/1/1\0testfiles/select/1/1\0- testfiles/select/1\0- **\0"])
553
554 def test_exclude_filelist(self):
555 """Exclude version of test_filelist"""
556 self.ParseTest([("--exclude-filelist", "file")],
859 [(), ('1',), ('1', '1'), ('1', '1', '2'),557 [(), ('1',), ('1', '1'), ('1', '1', '2'),
860 ('1', '1', '3')],558 ('1', '1', '3')],
861 ["testfiles/select/1/1/1\n"559 ["testfiles/select/1/1/1\n"
@@ -863,17 +561,17 @@
863 "testfiles/select/1\n"561 "testfiles/select/1\n"
864 "- **"])562 "- **"])
865563
866 def test_exclude_globbing_filelist_asterisk_1(self):564 def test_exclude_filelist_asterisk_1(self):
867 """Exclude version of test_include_globbing_filelist_asterisk"""565 """Exclude version of test_include_filelist_asterisk"""
868 self.ParseTest([("--exclude-globbing-filelist", "file")],566 self.ParseTest([("--exclude-filelist", "file")],
869 [(), ('1',), ('1', '1'), ('1', '1', '1'),567 [(), ('1',), ('1', '1'), ('1', '1', '1'),
870 ('1', '1', '2'), ('1', '1', '3')],568 ('1', '1', '2'), ('1', '1', '3')],
871 ["+ */select/1/1\n"569 ["+ */select/1/1\n"
872 "- **"])570 "- **"])
873571
874 def test_exclude_globbing_filelist_asterisk_2(self):572 def test_exclude_filelist_asterisk_2(self):
875 """Identical to test_exclude_globbing_filelist, but with the exclude 'select' replaced with '*'"""573 """Identical to test_exclude_filelist, but with the exclude 'select' replaced with '*'"""
876 self.ParseTest([("--exclude-globbing-filelist", "file")],574 self.ParseTest([("--exclude-filelist", "file")],
877 [(), ('1',), ('1', '1'), ('1', '1', '2'),575 [(), ('1',), ('1', '1'), ('1', '1', '2'),
878 ('1', '1', '3')],576 ('1', '1', '3')],
879 ["testfiles/*/1/1/1\n"577 ["testfiles/*/1/1/1\n"
@@ -882,10 +580,10 @@
882 "- **"])580 "- **"])
883581
884 @unittest.expectedFailure582 @unittest.expectedFailure
885 def test_exclude_globbing_filelist_asterisk_3(self):583 def test_exclude_filelist_asterisk_3(self):
886 """Identical to test_exclude_globbing_filelist, but with the include 'select' replaced with '*'"""584 """Identical to test_exclude_filelist, but with the include 'select' replaced with '*'"""
887 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)585 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
888 self.ParseTest([("--exclude-globbing-filelist", "file")],586 self.ParseTest([("--exclude-filelist", "file")],
889 [(), ('1',), ('1', '1'), ('1', '1', '2'),587 [(), ('1',), ('1', '1'), ('1', '1', '2'),
890 ('1', '1', '3')],588 ('1', '1', '3')],
891 ["testfiles/select/1/1/1\n"589 ["testfiles/select/1/1/1\n"
@@ -893,9 +591,9 @@
893 "testfiles/select/1\n"591 "testfiles/select/1\n"
894 "- **"])592 "- **"])
895593
896 def test_exclude_globbing_filelist_asterisk_4(self):594 def test_exclude_filelist_asterisk_4(self):
897 """Identical to test_exclude_globbing_filelist, but with numerous excluded folders replaced with '*'"""595 """Identical to test_exclude_filelist, but with numerous excluded folders replaced with '*'"""
898 self.ParseTest([("--exclude-globbing-filelist", "file")],596 self.ParseTest([("--exclude-filelist", "file")],
899 [(), ('1',), ('1', '1'), ('1', '1', '2'),597 [(), ('1',), ('1', '1'), ('1', '1', '2'),
900 ('1', '1', '3')],598 ('1', '1', '3')],
901 ["*/select/1/1/1\n"599 ["*/select/1/1/1\n"
@@ -904,10 +602,10 @@
904 "- **"])602 "- **"])
905603
906 @unittest.expectedFailure604 @unittest.expectedFailure
907 def test_exclude_globbing_filelist_asterisk_5(self):605 def test_exclude_filelist_asterisk_5(self):
908 """Identical to test_exclude_globbing_filelist, but with numerous included/excluded folders replaced with '*'"""606 """Identical to test_exclude_filelist, but with numerous included/excluded folders replaced with '*'"""
909 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)607 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
910 self.ParseTest([("--exclude-globbing-filelist", "file")],608 self.ParseTest([("--exclude-filelist", "file")],
911 [(), ('1',), ('1', '1'), ('1', '1', '2'),609 [(), ('1',), ('1', '1'), ('1', '1', '2'),
912 ('1', '1', '3')],610 ('1', '1', '3')],
913 ["*/select/1/1/1\n"611 ["*/select/1/1/1\n"
@@ -916,10 +614,10 @@
916 "- **"])614 "- **"])
917615
918 @unittest.expectedFailure616 @unittest.expectedFailure
919 def test_exclude_globbing_filelist_double_asterisk(self):617 def test_exclude_filelist_double_asterisk(self):
920 """Identical to test_exclude_globbing_filelist, but with all included/excluded folders replaced with '**'"""618 """Identical to test_exclude_filelist, but with all included/excluded folders replaced with '**'"""
921 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)619 # Todo: Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
922 self.ParseTest([("--exclude-globbing-filelist", "file")],620 self.ParseTest([("--exclude-filelist", "file")],
923 [(), ('1',), ('1', '1'), ('1', '1', '2'),621 [(), ('1',), ('1', '1'), ('1', '1', '2'),
924 ('1', '1', '3')],622 ('1', '1', '3')],
925 ["**/1/1/1\n"623 ["**/1/1/1\n"
@@ -956,9 +654,9 @@
956 ('3', '3'),654 ('3', '3'),
957 ('3', '3', '2')])655 ('3', '3', '2')])
958656
959 def test_globbing_filelist2(self):657 def test_filelist2(self):
960 """Filelist glob test similar to above testGlob"""658 """Filelist glob test similar to above testGlob"""
961 self.ParseTest([("--exclude-globbing-filelist", "asoeuth")],659 self.ParseTest([("--exclude-filelist", "asoeuth")],
962 [(), ('1',), ('1', '1'),660 [(), ('1',), ('1', '1'),
963 ('1', '1', '1'), ('1', '1', '2'),661 ('1', '1', '1'), ('1', '1', '2'),
964 ('1', '2'), ('1', '2', '1'), ('1', '2', '2')],662 ('1', '2'), ('1', '2', '1'), ('1', '2', '2')],
@@ -967,7 +665,7 @@
967+ testfiles/select/1665+ testfiles/select/1
968**666**
969"""])667"""])
970 self.ParseTest([("--include-globbing-filelist", "file")],668 self.ParseTest([("--include-filelist", "file")],
971 [(), ('1',), ('1', '1'),669 [(), ('1',), ('1', '1'),
972 ('1', '1', '2'),670 ('1', '1', '2'),
973 ('1', '2'),671 ('1', '2'),

Subscribers

People subscribed via source and target branches