コード例 #1
0
 def ensure_repo_id(self):
     val = self.config(b'bup.repo-id')
     if val is not None:
         return
     # create lots of random bits ...
     randgen = random.SystemRandom()
     chars = b'abcdefghijklmnopqrstuvwxyz0123456789'
     new_id = b''.join(
         bytes_from_byte(randgen.choice(chars)) for x in range(31))
     self.write_repo_id(new_id)
コード例 #2
0
ファイル: helpers.py プロジェクト: jmberg/bup
    def __init__(self, infd, outp):
        BaseConn.__init__(self, outp)
        # Anything that comes through before the sync string was not
        # multiplexed and can be assumed to be debug/log before mux init.
        stderr = byte_stream(sys.stderr)
        cookie = b'BUPMUX'
        pos = 0
        while True:
            b = os.read(infd, 1)
            # Make sure to write all pre-BUPMUX output to stderr
            if not b:
                ex = IOError('demux: unexpected EOF during initialization')
                with pending_raise(ex):
                    stderr.write(cookie[:pos])
                    stderr.flush()

            if b == bytes_from_byte(cookie[pos]):
                pos += 1
                if pos == len(cookie):
                    break
                continue

            # If we can't find a new char of 'BUPMUX' then we must have some
            # pre-mux log messages - output those as soon and as complete as
            # possible.
            #
            # \r\n interacts badly with print_clean_line() in the main bup
            # so remove all the \r so we see the full the lines. This assumes
            # that nothing at this point will intentionally delete lines, but
            # as we're just during SSH init that seems reasonable.
            if b == b'\r':
                continue

            stderr.write(cookie[:pos]) # could be we have "BU" in the logs or so
            pos = 0
            stderr.write(b)  # pre-mux log messages
            stderr.flush()
        self.infd = infd
        self.reader = None
        self.buf = None
        self.closed = False
コード例 #3
0
def test_valid_save_name():
    valid = helpers.valid_save_name
    WVPASS(valid(b'x'))
    WVPASS(valid(b'x@'))
    WVFAIL(valid(b'@'))
    WVFAIL(valid(b'/'))
    WVFAIL(valid(b'/foo'))
    WVFAIL(valid(b'foo/'))
    WVFAIL(valid(b'/foo/'))
    WVFAIL(valid(b'foo//bar'))
    WVFAIL(valid(b'.'))
    WVFAIL(valid(b'bar.'))
    WVFAIL(valid(b'foo@{'))
    for x in b' ~^:?*[\\':
        WVFAIL(valid(b'foo' + bytes_from_byte(x)))
    for i in range(20):
        WVFAIL(valid(b'foo' + bytes_from_uint(i)))
    WVFAIL(valid(b'foo' + bytes_from_uint(0x7f)))
    WVFAIL(valid(b'foo..bar'))
    WVFAIL(valid(b'bar.lock/baz'))
    WVFAIL(valid(b'foo/bar.lock/baz'))
    WVFAIL(valid(b'.bar/baz'))
    WVFAIL(valid(b'foo/.bar/baz'))
コード例 #4
0
ファイル: shquote.py プロジェクト: gdt/bup
def unfinished_word(line):
    """Returns the quotechar,word of any unfinished word at the end of 'line'.

    You can use this to determine if 'line' is a completely parseable line
    (ie. one that quotesplit() will finish successfully) or if you need
    to read more bytes first.

    Args:
      line: bytes
    Returns:
      quotechar,word: the initial quote char (or None), and the partial word.
    """
    try:
        for (wordstart, word) in _quotesplit(line):
            pass
    except QuoteError:
        firstchar = bytes_from_byte(line[wordstart])
        if firstchar in [q, qq]:
            return (firstchar, word)
        else:
            return (None, word)
    else:
        return (None, b'')
コード例 #5
0
ファイル: shquote.py プロジェクト: gdt/bup
def _quotesplit(line):
    inquote = None
    inescape = None
    wordstart = 0
    word = b''
    for i in range(len(line)):
        c = bytes_from_byte(line[i])
        if inescape:
            if inquote == q and c != q:
                word += b'\\'  # single-q backslashes can only quote single-q
            word += c
            inescape = False
        elif c == b'\\':
            inescape = True
        elif c == inquote:
            inquote = None
            # this is un-sh-like, but do it for sanity when autocompleting
            yield (wordstart, word)
            word = b''
            wordstart = i + 1
        elif not inquote and not word and c in (q, qq):
            # the 'not word' constraint on this is un-sh-like, but do it
            # for sanity when autocompleting
            inquote = c
            wordstart = i
        elif not inquote and c in [b' ', b'\n', b'\r', b'\t']:
            if word:
                yield (wordstart, word)
            word = b''
            wordstart = i + 1
        else:
            word += c
    if word:
        yield (wordstart, word)
    if inquote or inescape or word:
        raise QuoteError()
コード例 #6
0
ファイル: git.py プロジェクト: zzmjohn/bup
def parse_tz_offset(s):
    """UTC offset in seconds."""
    tz_off = (int(s[1:3]) * 60 * 60) + (int(s[3:5]) * 60)
    if bytes_from_byte(s[0]) == b'-':
        return -tz_off
    return tz_off
コード例 #7
0
ファイル: tgit.py プロジェクト: zzmjohn/bup
def test_commit_parsing():

    def restore_env_var(name, val):
        if val is None:
            del environ[name]
        else:
            environ[name] = val

    def showval(commit, val):
        return readpipe([b'git', b'show', b'-s',
                         b'--pretty=format:%s' % val, commit]).strip()

    with no_lingering_errors():
        with test_tempdir(b'bup-tgit-') as tmpdir:
            orig_cwd = os.getcwd()
            workdir = tmpdir + b'/work'
            repodir = workdir + b'/.git'
            orig_author_name = environ.get(b'GIT_AUTHOR_NAME')
            orig_author_email = environ.get(b'GIT_AUTHOR_EMAIL')
            orig_committer_name = environ.get(b'GIT_COMMITTER_NAME')
            orig_committer_email = environ.get(b'GIT_COMMITTER_EMAIL')
            environ[b'GIT_AUTHOR_NAME'] = b'bup test'
            environ[b'GIT_COMMITTER_NAME'] = environ[b'GIT_AUTHOR_NAME']
            environ[b'GIT_AUTHOR_EMAIL'] = b'bup@a425bc70a02811e49bdf73ee56450e6f'
            environ[b'GIT_COMMITTER_EMAIL'] = environ[b'GIT_AUTHOR_EMAIL']
            try:
                readpipe([b'git', b'init', workdir])
                environ[b'GIT_DIR'] = environ[b'BUP_DIR'] = repodir
                git.check_repo_or_die(repodir)
                os.chdir(workdir)
                with open('foo', 'w') as f:
                    print('bar', file=f)
                readpipe([b'git', b'add', b'.'])
                readpipe([b'git', b'commit', b'-am', b'Do something',
                          b'--author', b'Someone <someone@somewhere>',
                          b'--date', b'Sat Oct 3 19:48:49 2009 -0400'])
                commit = readpipe([b'git', b'show-ref', b'-s', b'master']).strip()
                parents = showval(commit, b'%P')
                tree = showval(commit, b'%T')
                cname = showval(commit, b'%cn')
                cmail = showval(commit, b'%ce')
                cdate = showval(commit, b'%ct')
                coffs = showval(commit, b'%ci')
                coffs = coffs[-5:]
                coff = (int(coffs[-4:-2]) * 60 * 60) + (int(coffs[-2:]) * 60)
                if bytes_from_byte(coffs[-5]) == b'-':
                    coff = - coff
                commit_items = git.get_commit_items(commit, git.cp())
                WVPASSEQ(commit_items.parents, [])
                WVPASSEQ(commit_items.tree, tree)
                WVPASSEQ(commit_items.author_name, b'Someone')
                WVPASSEQ(commit_items.author_mail, b'someone@somewhere')
                WVPASSEQ(commit_items.author_sec, 1254613729)
                WVPASSEQ(commit_items.author_offset, -(4 * 60 * 60))
                WVPASSEQ(commit_items.committer_name, cname)
                WVPASSEQ(commit_items.committer_mail, cmail)
                WVPASSEQ(commit_items.committer_sec, int(cdate))
                WVPASSEQ(commit_items.committer_offset, coff)
                WVPASSEQ(commit_items.message, b'Do something\n')
                with open(b'bar', 'wb') as f:
                    f.write(b'baz\n')
                readpipe([b'git', b'add', '.'])
                readpipe([b'git', b'commit', b'-am', b'Do something else'])
                child = readpipe([b'git', b'show-ref', b'-s', b'master']).strip()
                parents = showval(child, b'%P')
                commit_items = git.get_commit_items(child, git.cp())
                WVPASSEQ(commit_items.parents, [commit])
            finally:
                os.chdir(orig_cwd)
                restore_env_var(b'GIT_AUTHOR_NAME', orig_author_name)
                restore_env_var(b'GIT_AUTHOR_EMAIL', orig_author_email)
                restore_env_var(b'GIT_COMMITTER_NAME', orig_committer_name)
                restore_env_var(b'GIT_COMMITTER_EMAIL', orig_committer_email)
コード例 #8
0
def parse_args(args):
    class GetOpts:
        pass

    opt = GetOpts()
    opt.help = False
    opt.verbose = 0
    opt.quiet = False
    opt.print_commits = opt.print_trees = opt.print_tags = False
    opt.bwlimit = None
    opt.compress = 1
    opt.source = opt.remote = None
    opt.target_specs = []

    remaining = args[1:]  # Skip argv[0]
    while remaining:
        arg = remaining[0]
        if arg in (b'-h', b'--help'):
            sys.stdout.write(usage(argspec))
            sys.exit(0)
        elif arg in (b'-v', b'--verbose'):
            opt.verbose += 1
            remaining = remaining[1:]
        elif arg in (b'--ff', b'--append', b'--pick', b'--force-pick',
                     b'--new-tag', b'--replace', b'--unnamed'):
            (ref, ), remaining = require_n_args_or_die(1, remaining)
            opt.target_specs.append(
                Spec(method=arg[2:].decode('ascii'), src=ref, dest=None))
        elif arg in (b'--ff:', b'--append:', b'--pick:', b'--force-pick:',
                     b'--new-tag:', b'--replace:'):
            (ref, dest), remaining = require_n_args_or_die(2, remaining)
            opt.target_specs.append(
                Spec(method=arg[2:-1].decode('ascii'), src=ref, dest=dest))
        elif arg in (b'-s', b'--source'):
            (opt.source, ), remaining = require_n_args_or_die(1, remaining)
        elif arg in (b'-r', b'--remote'):
            (opt.remote, ), remaining = require_n_args_or_die(1, remaining)
        elif arg in (b'-c', b'--print-commits'):
            opt.print_commits, remaining = True, remaining[1:]
        elif arg in (b'-t', b'--print-trees'):
            opt.print_trees, remaining = True, remaining[1:]
        elif arg == b'--print-tags':
            opt.print_tags, remaining = True, remaining[1:]
        elif arg in (b'-0', b'-1', b'-2', b'-3', b'-4', b'-5', b'-6', b'-7',
                     b'-8', b'-9'):
            opt.compress = int(arg[1:])
            remaining = remaining[1:]
        elif arg == b'--compress':
            (opt.compress, ), remaining = require_n_args_or_die(1, remaining)
            opt.compress = int(opt.compress)
        elif arg == b'--bwlimit':
            (opt.bwlimit, ), remaining = require_n_args_or_die(1, remaining)
            opt.bwlimit = int(opt.bwlimit)
        elif arg.startswith(b'-') and len(arg) > 2 and arg[1] != b'-':
            # Try to interpret this as -xyz, i.e. "-xyz -> -x -y -z".
            # We do this last so that --foo -bar is valid if --foo
            # requires a value.
            remaining[0:1] = (b'-' + bytes_from_byte(c) for c in arg[1:])
            # FIXME
            continue
        else:
            misuse()
    return opt