示例#1
0
    def clean(self):
        result = run([
            self.executable(),
            'revert',
            '-R',
            self.root_path,
        ],
                     cwd=self.root_path).returncode
        if result:
            return result

        for line in reversed(
                run([self.executable(), 'status'],
                    cwd=self.root_path,
                    capture_output=True,
                    encoding='utf-8').stdout.splitlines()):
            candidate = line.split('       ')
            if candidate[0] != '?':
                continue
            path = os.path.join(self.root_path, '       '.join(candidate[1:]))
            if os.path.isdir(path):
                shutil.rmtree(path, ignore_errors=True)
            elif os.path.exists(path):
                os.remove(path)
        return 0
示例#2
0
    def test_documentation(self):
        with OutputCapture():
            with mocks.Subprocess(
                    'ls',
                    completion=mocks.ProcessCompletion(
                        returncode=0, stdout='file1.txt\nfile2.txt\n'),
            ):
                result = run(['ls'], capture_output=True, encoding='utf-8')
                assert result.returncode == 0
                assert result.stdout == 'file1.txt\nfile2.txt\n'

            with mocks.Subprocess(
                    'ls',
                    completion=mocks.ProcessCompletion(
                        returncode=0, stdout='file1.txt\nfile2.txt\n'),
            ):
                assert subprocess.check_output(['ls'
                                                ]) == b'file1.txt\nfile2.txt\n'
                assert subprocess.check_call(['ls']) == 0

            with mocks.Subprocess(
                    mocks.Subprocess.CommandRoute(
                        'command-a',
                        'argument',
                        completion=mocks.ProcessCompletion(returncode=0)),
                    mocks.Subprocess.CommandRoute(
                        'command-b',
                        completion=mocks.ProcessCompletion(returncode=-1)),
            ):
                result = run(['command-a', 'argument'])
                assert result.returncode == 0

                result = run(['command-b'])
                assert result.returncode == -1
示例#3
0
    def test_implied_route(self):
        with mocks.Subprocess(
                'command', completion=mocks.ProcessCompletion(returncode=0)):
            self.assertEqual(run(['command']).returncode, 0)

            with self.assertRaises(OSError):
                run(['invalid-file'])
示例#4
0
文件: git.py 项目: eocanha/webkit
    def checkout(self, argument):
        if not isinstance(argument, six.string_types):
            raise ValueError(
                "Expected 'argument' to be a string, not '{}'".format(
                    type(argument)))

        self._branch = None

        if log.level > logging.WARNING:
            log_arg = ['-q']
        elif log.level < logging.WARNING:
            log_arg = ['--progress']
        else:
            log_arg = []

        parsed_commit = Commit.parse(argument, do_assert=False)
        if parsed_commit:
            commit = self.commit(
                hash=parsed_commit.hash,
                revision=parsed_commit.revision,
                identifier=parsed_commit.identifier,
                branch=parsed_commit.branch,
            )
            return None if run(
                [self.executable(), 'checkout'] + [commit.hash] + log_arg,
                cwd=self.root_path,
            ).returncode else commit

        return None if run(
            [self.executable(), 'checkout'] + [argument] + log_arg,
            cwd=self.root_path,
        ).returncode else self.commit()
示例#5
0
 def pull(self):
     commit = self.commit()
     code = run([self.executable(), 'pull'], cwd=self.root_path).returncode
     if not code and self.is_svn:
         return run([
             self.executable(), 'svn', 'fetch', '--log-window-size=5000', '-r', '{}:HEAD'.format(commit.revision),
         ], cwd=self.root_path).returncode
     return code
示例#6
0
    def branch(self):
        status = run([self.executable(), 'status'], cwd=self.root_path, capture_output=True, encoding='utf-8')
        if status.returncode:
            raise self.Exception('Failed to run `git status` for {}'.format(self.root_path))
        if status.stdout.splitlines()[0].startswith('HEAD detached at'):
            return None

        result = run([self.executable(), 'rev-parse', '--abbrev-ref', 'HEAD'], cwd=self.root_path, capture_output=True, encoding='utf-8')
        if result.returncode:
            raise self.Exception('Failed to retrieve branch for {}'.format(self.root_path))
        return result.stdout.rstrip()
示例#7
0
 def test_argument_priority(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 '--help',
                 completion=mocks.ProcessCompletion(returncode=0)),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
     ):
         self.assertEqual(run(['command']).returncode, 1)
         self.assertEqual(run(['command', '--help']).returncode, 0)
示例#8
0
 def test_cwd_priority(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=0),
                 cwd='/example'),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
     ):
         self.assertEqual(run(['command']).returncode, 1)
         self.assertEqual(run(['command'], cwd='/example').returncode, 0)
示例#9
0
 def test_input_priority(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=0),
                 input='stdin'),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
     ):
         self.assertEqual(run(['command']).returncode, 1)
         self.assertEqual(run(['command'], input='stdin').returncode, 0)
         self.assertEqual(
             run(['command'], stdin=BytesIO(b'stdin')).returncode, 0)
示例#10
0
 def test_ordered(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=0)),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
             ordered=True,
     ):
         self.assertEqual(run(['command']).returncode, 0)
         self.assertEqual(run(['command']).returncode, 1)
         with self.assertRaises(OSError):
             run(['command'])
示例#11
0
    def info(self, branch=None, revision=None, tag=None):
        if tag and branch:
            raise ValueError('Cannot specify both branch and tag')
        if tag and revision:
            raise ValueError('Cannot specify both branch and tag')

        revision = Commit._parse_revision(revision)
        if branch and branch != self.default_branch and '/' not in branch:
            branch = 'branches/{}'.format(branch)
        additional_args = [
            '^/{}'.format(branch)
        ] if branch and branch != self.default_branch else []
        additional_args += ['^/tags/{}'.format(tag)] if tag else []
        additional_args += ['-r', str(revision)] if revision else []

        info_result = run([self.executable(), 'info'] + additional_args,
                          cwd=self.root_path,
                          capture_output=True,
                          encoding='utf-8')
        if info_result.returncode:
            return {}

        result = {}
        for line in info_result.stdout.splitlines():
            split = line.split(': ')
            result[split[0]] = ': '.join(split[1:])
        return result
示例#12
0
 def test_run(self):
     result = run([sys.executable, '-c', 'print("message")'],
                  capture_output=True,
                  encoding='utf-8')
     self.assertEqual(0, result.returncode)
     self.assertEqual(result.stdout, 'message\n')
     self.assertEqual(result.stderr, '')
示例#13
0
    def find(self, argument, include_log=True):
        if not isinstance(argument, six.string_types):
            raise ValueError(
                "Expected 'argument' to be a string, not '{}'".format(
                    type(argument)))

        parsed_commit = Commit.parse(argument, do_assert=False)
        if parsed_commit:
            return self.commit(
                hash=parsed_commit.hash,
                revision=parsed_commit.revision,
                identifier=parsed_commit.identifier,
                branch=parsed_commit.branch,
                include_log=include_log,
            )

        output = run(
            [self.executable(), 'rev-parse', argument],
            cwd=self.root_path,
            capture_output=True,
            encoding='utf-8',
        )
        if output.returncode:
            raise ValueError(
                "'{}' is not an argument recognized by git".format(argument))
        return self.commit(hash=output.stdout.rstrip(),
                           include_log=include_log)
示例#14
0
 def _commit_count(self, native_parameter):
     revision_count = run(
         [self.executable(), 'rev-list', '--count', '--no-merges', native_parameter],
         cwd=self.root_path, capture_output=True, encoding='utf-8',
     )
     if revision_count.returncode:
         raise self.Exception('Failed to retrieve revision count for {}'.format(native_parameter))
     return int(revision_count.stdout)
示例#15
0
文件: git.py 项目: eocanha/webkit
 def root_path(self):
     result = run([self.executable(), 'rev-parse', '--show-toplevel'],
                  cwd=self.path,
                  capture_output=True,
                  encoding='utf-8')
     if result.returncode:
         return None
     return result.stdout.rstrip()
示例#16
0
文件: git.py 项目: eocanha/webkit
 def clean(self):
     return run([
         self.executable(),
         'reset',
         'HEAD',
         '--hard',
     ],
                cwd=self.root_path).returncode
示例#17
0
文件: git.py 项目: butday/webkit
 def remote(self, name=None):
     result = run([self.executable, 'remote', 'get-url', name or 'origin'],
                  cwd=self.root_path,
                  capture_output=True,
                  encoding='utf-8')
     if result.returncode:
         raise self.Exception('Failed to retrieve remote for {}'.format(
             self.root_path))
     return result.stdout.rstrip()
示例#18
0
    def test_popen(self):
        with OutputCapture() as captured:
            with mocks.Subprocess(MockSubprocess.LS):
                result = run(['ls'])
                self.assertEqual(result.returncode, 0)
                self.assertEqual(result.stdout, None)
                self.assertEqual(result.stderr, None)

        self.assertEqual(captured.stdout.getvalue(), 'file1.txt\nfile2.txt\n')
示例#19
0
文件: git.py 项目: eocanha/webkit
 def tags(self):
     tags = run([self.executable(), 'tag'],
                cwd=self.root_path,
                capture_output=True,
                encoding='utf-8')
     if tags.returncode:
         raise self.Exception('Failed to retrieve tag list for {}'.format(
             self.root_path))
     return tags.stdout.splitlines()
示例#20
0
 def list(self, category):
     list_result = run([self.executable, 'list', '^/{}'.format(category)],
                       cwd=self.path,
                       capture_output=True,
                       encoding='utf-8')
     if list_result.returncode:
         return []
     return [
         element.rstrip('/') for element in list_result.stdout.splitlines()
     ]
示例#21
0
    def checkout(self, argument):
        commit = self.find(argument)
        if not commit:
            return None

        command = [self.executable(), 'up', '-r', str(commit.revision)]
        if log.level > logging.WARNING:
            command.append('-q')

        return None if run(command, cwd=self.root_path).returncode else commit
示例#22
0
 def default_branch(self):
     result = run([self.executable(), 'rev-parse', '--abbrev-ref', 'origin/HEAD'], cwd=self.path, capture_output=True, encoding='utf-8')
     if result.returncode:
         candidates = self.branches
         if 'master' in candidates:
             return 'master'
         if 'main' in candidates:
             return 'main'
         return None
     return '/'.join(result.stdout.rstrip().split('/')[1:])
示例#23
0
    def _branch_for(self, revision):
        candidates = [
            branch for branch, revisions in self._metadata_cache.items()
            if branch != 'version' and revision in revisions
        ]
        candidate = self.prioritize_branches(
            candidates) if candidates else None

        # In the default branch case, we don't even need to ask the remote
        if candidate == self.default_branch:
            return candidate

        process = run(
            [
                self.executable(), 'log', '-v', '-q',
                self.remote(), '-r',
                str(revision), '-l', '1'
            ],
            cwd=self.root_path,
            capture_output=True,
            encoding='utf-8',
        )

        # If we didn't get a valid answer from the remote, but we found a matching candidate, we return that.
        # This is a bit risky because there is a chance the branch we have cached is not the canonical branch
        # for a revision, but this is pretty unlikely because it would require the n + 1 level branch to be cached
        # but not the n level branch.
        if process.returncode or not process.stdout:
            if candidate:
                return candidate
            raise self.Exception(
                "Failed to retrieve branch for '{}'".format(revision))

        partial = None
        for line in process.stdout.splitlines():
            if partial is None and line == 'Changed paths:':
                partial = ''
            elif partial == '':
                partial = line.lstrip()[2:]
            elif partial:
                line = line.lstrip()
                while line.startswith(
                    ('A ', 'D ', 'M ')) and not line[2:].startswith(partial):
                    partial = partial[:-1]

        if len(partial) <= 3:
            raise self.Exception('Malformed set  of edited files')
        partial = partial.split(' ')[0]
        candidate = partial.split(
            '/')[2 if partial.startswith('/branches') else 1]

        # Tags are a unique case for SVN, because they're treated as branches in native SVN
        if candidate == 'tags':
            return partial[1:].rstrip('/')
        return candidate
示例#24
0
    def main(cls, args, repository, subversion=None, **kwargs):
        if not repository.path:
            sys.stderr.write('Cannot setup git-svn on remote repository\n')
            return 1
        if not repository.is_git:
            sys.stderr.write('Cannot setup git-svn on Subversion repository\n')
            return 1
        if not subversion:
            sys.stderr.write(
                'Failed to find Subversion remote: {}\n'.format(subversion))
            return 1

        print('Adding svn-remote to git config')
        config_path = os.path.join(repository.root_path, '.git', 'config')
        config_data = []
        with open(config_path, 'r') as config:
            is_in_svn_remote = False
            for line in config.readlines():
                if is_in_svn_remote and not line[:1].isspace():
                    is_in_svn_remote = False
                if line.startswith('[svn-remote "svn"]'):
                    is_in_svn_remote = True
                if not is_in_svn_remote:
                    config_data.append(line)

        with open(config_path, 'w') as config:
            for line in config_data:
                config.write(line)
            config.write('[svn-remote "svn"]\n')
            config.write('\turl = {}\n'.format(subversion))
            config.write('\tfetch = trunk:refs/remotes/origin/{}\n'.format(
                repository.default_branch))

            if args.all_branches:
                svn_remote = remote.Svn(
                    url=subversion,
                    dev_branches=repository.dev_branches,
                    prod_branches=repository.prod_branches,
                    contributors=repository.contributors,
                )

                git_branches = repository.branches
                for branch in sorted(svn_remote.branches):
                    if branch not in git_branches:
                        continue
                    config.write(
                        '\tfetch = branches/{branch}:refs/remotes/origin/{branch}\n'
                        .format(branch=branch))

        print('Populating svn commit mapping (will take a few minutes)...')
        return run([
            repository.executable(), 'svn', 'fetch', '--log-window-size=5000',
            '-r', '1:HEAD'
        ],
                   cwd=repository.root_path).returncode
示例#25
0
 def _branches_for(self, hash=None):
     branch = run(
         [self.executable(), 'branch', '-a'] + (['--contains', hash] if hash else []),
         cwd=self.root_path,
         capture_output=True,
         encoding='utf-8',
     )
     if branch.returncode:
         raise self.Exception('Failed to retrieve branch list for {}'.format(self.root_path))
     result = [branch.lstrip(' *') for branch in filter(lambda branch: '->' not in branch, branch.stdout.splitlines())]
     return sorted(set(['/'.join(branch.split('/')[2:]) if branch.startswith('remotes/origin/') else branch for branch in result]))
示例#26
0
 def is_svn(self):
     try:
         return run(
             [self.executable(), 'svn', 'find-rev', 'r1'],
             cwd=self.root_path,
             capture_output=True,
             encoding='utf-8',
             timeout=1,
         ).returncode == 0
     except TimeoutExpired:
         return False
示例#27
0
文件: git.py 项目: butday/webkit
 def branches(self):
     branch = run([self.executable, 'branch', '-a'],
                  cwd=self.root_path,
                  capture_output=True,
                  encoding='utf-8')
     if branch.returncode:
         raise self.Exception(
             'Failed to retrieve branch list for {}'.format(self.root_path))
     return [
         branch.lstrip(' *') for branch in filter(
             lambda branch: '->' not in branch, branch.stdout.splitlines())
     ]
示例#28
0
    def executable(cls, program):
        for candidate in ['/usr/bin', '/usr/bin/local']:
            candidate = os.path.join(candidate, program)
            if os.path.exists(candidate):
                return candidate

        which = run(['/usr/bin/which', program],
                    capture_output=True,
                    encoding='utf-8')
        if not which.returncode:
            return os.path.realpath(which.stdout.rstrip())
        raise OSError("Cannot find '{}' program".format(program))
示例#29
0
    def info(self):
        if not self.is_svn:
            raise self.Exception('Cannot run SVN info on a git checkout which is not git-svn')

        info_result = run([self.executable(), 'svn', 'info'], cwd=self.path, capture_output=True, encoding='utf-8')
        if info_result.returncode:
            return {}

        result = {}
        for line in info_result.stdout.splitlines():
            split = line.split(': ')
            result[split[0]] = ': '.join(split[1:])
        return result
示例#30
0
    def info(self):
        info_result = run([self.executable, 'info'],
                          cwd=self.path,
                          capture_output=True,
                          encoding='utf-8')
        if info_result.returncode:
            return {}

        result = {}
        for line in info_result.stdout.splitlines():
            split = line.split(': ')
            result[split[0]] = ': '.join(split[1:])
        return result