Skip to content

Commit fecd72a

Browse files
committed
Merge pull request #22 from longaccess/ignore
support .gitignore like files when uploading
2 parents ffb4f8d + 8606fb3 commit fecd72a

File tree

5 files changed

+57
-10
lines changed

5 files changed

+57
-10
lines changed

BigStash/filename.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import os.path
66
import posixpath
7+
import fnmatch
78
from functools import partial
89
from operator import contains
910

@@ -58,6 +59,20 @@
5859
}
5960

6061

62+
class FnMatches(object):
63+
def __init__(self, patterns=[]):
64+
self.patterns = patterns
65+
66+
def __call__(self, path):
67+
return any(map(partial(fnmatch.fnmatch, path), self.patterns))
68+
69+
70+
def setup_user_ignore(ignorefile):
71+
with open(os.path.expanduser(ignorefile)) as ignorefile:
72+
p = list(l.strip() for l in ignorefile if not l.startswith('#'))
73+
IGNORE_TESTS['is user ignored'] = FnMatches(p)
74+
75+
6176
def splitpath(path):
6277
_, path = os.path.splitdrive(path)
6378
folders = []
@@ -91,6 +106,6 @@ def get_validator(tests={}, search={}, match={}):
91106
return lambda path: ((m, f, p) for p in splitpath(path)
92107
for m, f in validators if p != os.sep and f(p))
93108

94-
should_ignore = get_validator(tests=IGNORE_TESTS)
95-
is_invalid = get_validator(
109+
should_ignore = lambda: get_validator(tests=IGNORE_TESTS)
110+
is_invalid = lambda: get_validator(
96111
search=SEARCH_PATTERNS, match=MATCH_PATTERNS)

BigStash/manifest.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55
import collections
66
import os.path
7+
import six
78
from datetime import datetime
89
from cached_property import cached_property
910
from functools import partial
@@ -78,21 +79,30 @@ def files(self):
7879
@classmethod
7980
def from_paths(cls, paths, title=''):
8081
errors = []
82+
ignored_files = []
8183

8284
def ignored(path, reason, *args):
85+
ignored_files.append((path, reason))
8386
log.debug("Ignoring {}: {}".format(path, reason))
87+
return True
8488

8589
def invalid(path, reason, *args):
8690
errors.append((path, reason))
8791
log.debug("Invalid file {}: {}".format(path, reason))
92+
return True
93+
94+
validators = {
95+
ignored: filename.should_ignore(),
96+
invalid: filename.is_invalid()
97+
}
8898

8999
def _include_file(path):
90100
if not os.path.exists(path):
91101
return invalid(path, "File doesn't exist")
102+
validations = [starmap(partial(c, path), v(path))
103+
for c, v in six.iteritems(validators)]
92104

93-
return not any(chain(
94-
starmap(partial(ignored, path), filename.should_ignore(path)),
95-
starmap(partial(invalid, path), filename.is_invalid(path))))
105+
return not any(chain(*validations))
96106

97107
def _walk_dirs(paths):
98108
for path in paths:
@@ -115,4 +125,4 @@ def _tofile(path):
115125

116126
files = map(_tofile, map(os.path.abspath, _walk_dirs(paths)))
117127

118-
return (cls(title=title, files=files), errors)
128+
return (cls(title=title, files=files), errors, ignored_files)

BigStash/upload.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""bgst is a command line client to BigStash.co
22
33
Usage:
4-
bgst put [-t TITLE] [--silent] [--dont-wait] FILES...
4+
bgst put [--ignore-file IGNORE] [-t TITLE] [--silent] [--dont-wait] FILES...
55
bgst settings [--user=USERNAME] [--password=PASSWORD]
66
bgst settings --reset
77
bgst list [--limit=NUMBER]
@@ -22,6 +22,7 @@
2222
--reset Remove saved configuration, revoke
2323
authentication token.
2424
--limit=NUMBER Show up to NUMBER results. [default: 10]
25+
--ignore-file=IGNORE Path to a .gitignore like file.
2526
"""
2627

2728
from __future__ import print_function
@@ -33,8 +34,10 @@
3334
import logging
3435
import posixpath
3536
import threading
37+
import inflect
3638
from wrapt import decorator
3739
from BigStash import __version__
40+
from BigStash.filename import setup_user_ignore
3841
from BigStash.auth import get_api_credentials
3942
from BigStash.conf import BigStashAPISettings
4043
from BigStash import BigStashAPI, BigStashError
@@ -45,6 +48,8 @@
4548

4649
log = logging.getLogger('bigstash.upload')
4750

51+
peng = inflect.engine()
52+
4853

4954
def smart_str(s):
5055
if isinstance(s, six.text_type):
@@ -195,16 +200,30 @@ def bgst_put(args, settings):
195200
opt_dont_wait = False if not args['--dont-wait'] else True
196201
upload = None
197202
filepaths = map(smart_str, args['FILES'])
198-
manifest, errors = Manifest.from_paths(paths=filepaths, title=title)
203+
ignorefile = args['--ignore-file']
204+
if ignorefile:
205+
setup_user_ignore(ignorefile)
206+
manifest, errors, ignored = Manifest.from_paths(
207+
paths=filepaths, title=title)
208+
ignored_msg = ''
209+
if ignored:
210+
ignored_msg = "({} {} ignored)".format(
211+
len(ignored), peng.plural("file", len(ignored)))
212+
if len(manifest) == 0:
213+
print(" ".join(["No files found", ignored_msg]))
214+
sys.exit(5)
199215
if errors:
200216
errtext = [": ".join(e) for e in errors]
201217
print("\n".join(["There were errors:"] + errtext))
202218
sys.exit(4)
203219
k, s = get_api_credentials(settings)
204220
bigstash = BigStashAPI(key=k, secret=s, settings=settings)
205221
upload = bigstash.CreateUpload(manifest=manifest)
222+
filecount = len(manifest)
206223
if not opt_silent:
207-
print("Uploading {}..".format(upload.archive.key))
224+
msg = "Uploading {} {} as archive {}..".format(
225+
filecount, peng.plural("file", filecount), upload.archive.key)
226+
print(" ".join([msg, ignored_msg]))
208227
s3 = boto3.resource(
209228
's3', region_name=upload.s3.region,
210229
aws_access_key_id=upload.s3.token_access_key,

requirements/base.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ retrying==1.3.3
2222
boto3==0.0.17
2323
# sha256: SbOoJSgL1ms6qDWF71nEqMgvLIpSLb51SovI0IyFxJE
2424
docopt==0.6.2
25+
# sha256: DiNY9PRqVMyj13uYP6NwiwLcg6zY0oRmpn6Ity5cGzQ
26+
inflect==0.2.5

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def pep386adapt(version):
2424
'wrapt',
2525
'boto3',
2626
'cached_property',
27-
'docopt'
27+
'docopt',
28+
'inflect'
2829
]
2930

3031

0 commit comments

Comments
 (0)