def git_switch_branch(self, stdout_in, stderr_in): path = self.source['path'] branch = self.source.get('branch', 'master') rbp = self._remote_branch_prefix cmd = self.run_git(["branch", "-a"], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("'git branch -a' failed.\n%s" % stderr) stdout_in += stdout stderr_in += stderr if 'rev' in self.source: # A tag or revision was specified instead of a branch argv = ["checkout", self.source['rev']] elif re.search(b("^(\*| ) %s$" % re.escape(branch)), stdout, re.M): # the branch is local, normal checkout will work argv = ["checkout", branch] elif re.search(b("^ " + re.escape(rbp) + "\/" + re.escape(branch) + "$"), stdout, re.M): # the branch is not local, normal checkout won't work here argv = ["checkout", "-b", branch, "%s/%s" % (rbp, branch)] else: logger.error("No such branch %r", branch) sys.exit(1) # runs the checkout with predetermined arguments cmd = self.run_git(argv, cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("git checkout of branch '%s' failed.\n%s" % (branch, stderr)) return (stdout_in + stdout, stderr_in + stderr)
def git_switch_branch(self, stdout_in, stderr_in): path = self.source['path'] branch = self.source.get('branch', 'master') rbp = self._remote_branch_prefix cmd = self.run_git(["branch", "-a"], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("'git branch -a' failed.\n%s" % stderr) stdout_in += stdout stderr_in += stderr if 'rev' in self.source: # A tag or revision was specified instead of a branch argv = ["checkout", self.source['rev']] elif re.search(b("^(\*| ) %s$" % re.escape(branch)), stdout, re.M): # the branch is local, normal checkout will work argv = ["checkout", branch] elif re.search( b("^ " + re.escape(rbp) + "\/" + re.escape(branch) + "$"), stdout, re.M): # the branch is not local, normal checkout won't work here argv = ["checkout", "-b", branch, "%s/%s" % (rbp, branch)] else: logger.error("No such branch %r", branch) sys.exit(1) # runs the checkout with predetermined arguments cmd = self.run_git(argv, cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("git checkout of branch '%s' failed.\n%s" % (branch, stderr)) return (stdout_in + stdout, stderr_in + stderr)
def _svn_check_version(self): global _svn_version_warning try: cmd = subprocess.Popen(["svn", "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: if getattr(sys.exc_info()[1], 'errno', None) == 2: logger.error("Couldn't find 'svn' executable on your PATH.") sys.exit(1) raise stdout, stderr = cmd.communicate() lines = stdout.split(b('\n')) version = None if len(lines): version = re.search(b('(\d+)\.(\d+)(\.\d+)?'), lines[0]) if version is not None: version = version.groups() if len(version) == 3: version = (int(version[0]), int(version[1]), int(version[2][1:])) else: version = (int(version[0]), int(version[1])) if (cmd.returncode != 0) or (version is None): logger.error("Couldn't determine the version of 'svn' command.") logger.error("Subversion output:\n%s\n%s" % (s(stdout), s(stderr))) sys.exit(1) if (version < (1, 5)) and not _svn_version_warning: logger.warning("The installed 'svn' command is too old. Expected 1.5 or newer, got %s." % ".".join([str(x) for x in version])) _svn_version_warning = True
def git_branch_status(self, branch): output = self.git_run(["branch", "-a"], cwd=self.source['path']) is_local = False is_remote = False if re.search(b("^(\*| ) %s$" % re.escape(branch)), output, re.M): is_local = True if re.search(b("^ " + re.escape(self._remote_branch_prefix) + "\/" + re.escape(branch) + "$"), output, re.M): is_remote = True return (is_local, is_remote)
def status(self, **kwargs): path = self.source['path'] output = self.git_run(["status", "-s", "-b"], cwd=path) lines = output.strip().split(b('\n')) if len(lines) == 1: if b('ahead') in lines[0]: status = 'ahead' else: status = 'clean' else: status = 'dirty' if kwargs.get('verbose', False): return status, self.git_output() else: return status
def git_version(self): try: output = self.git_run(['--version']) except GitError as error: logger.error("Could not determine git version") logger.error(error.args[0]) sys.exit(1) m = re.search(b("git version (\d+)\.(\d+)(\.\d+)?(\.\d+)?"), output) if m is None: logger.error("Unable to parse git version output") logger.error("'git --version' output was:\n%s" % (output)) sys.exit(1) version = m.groups() if version[3] is not None: version = ( int(version[0]), int(version[1]), int(version[2][1:]), int(version[3][1:])) elif version[2] is not None: version = ( int(version[0]), int(version[1]), int(version[2][1:])) else: version = (int(version[0]), int(version[1])) if version < (1, 5): logger.error( "Git version %s is unsupported, please upgrade", ".".join([str(v) for v in version])) sys.exit(1) return version
def status(self, **kwargs): path = self.source['path'] cmd = self.run_git(["status", "-s", "-b"], cwd=path) stdout, stderr = cmd.communicate() lines = stdout.strip().split(b('\n')) if len(lines) == 1: if b('ahead') in lines[0]: status = 'ahead' else: status = 'clean' else: status = 'dirty' if kwargs.get('verbose', False): return status, stdout else: return status
def git_merge_rbranch(self, stdout_in, stderr_in, accept_missing=False): path = self.source['path'] branch = self.source.get('branch', 'master') cmd = self.run_git(["branch", "-a"], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("'git branch -a' failed.\n%s" % stderr) stdout_in += stdout stderr_in += stderr if not re.search(b("^(\*| ) %s$" % re.escape(branch)), stdout, re.M): # The branch is not local. We should not have reached # this, unless no branch was specified and we guess wrong # that it should be master. if accept_missing: logger.info("No such branch %r", branch) return (stdout_in, stderr_in) else: logger.error("No such branch %r", branch) sys.exit(1) rbp = self._remote_branch_prefix cmd = self.run_git(["merge", "%s/%s" % (rbp, branch)], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("git merge of remote branch 'origin/%s' failed.\n%s" % (branch, stderr)) return (stdout_in + stdout, stderr_in + stderr)
def _svn_communicate(self, args, url, **kwargs): auth = self._svn_auth_get(url) if auth is not None: args[2:2] = ["--username", auth['user'], "--password", auth['passwd']] if not kwargs.get('verbose', False): args[2:2] = ["--quiet"] accept_invalid_cert = self._svn_accept_invalid_cert_get(url) if 'always_accept_server_certificate' in kwargs: if kwargs['always_accept_server_certificate']: accept_invalid_cert = True if accept_invalid_cert is True: args[2:2] = ["--trust-server-cert"] elif accept_invalid_cert is False: raise SVNCertificateRejectedError("Server certificate rejected by user.") args[2:2] = ["--no-auth-cache"] interactive_args = args[:] args[2:2] = ["--non-interactive"] cmd = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode != 0: lines = stderr.strip().split(b('\n')) if 'authorization failed' in lines[-1] or 'Could not authenticate to server' in lines[-1]: raise SVNAuthorizationError(stderr.strip()) if 'Server certificate verification failed: issuer is not trusted' in lines[-1]: cmd = subprocess.Popen(interactive_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate('t') raise SVNCertificateError(stderr.strip()) return stdout, stderr, cmd.returncode
def git_version(self): cmd = self.run_git(['--version']) stdout, stderr = cmd.communicate() if cmd.returncode != 0: logger.error("Could not determine git version") logger.error("'git --version' output was:\n%s\n%s" % (stdout, stderr)) sys.exit(1) m = re.search(b("git version (\d+)\.(\d+)(\.\d+)?(\.\d+)?"), stdout) if m is None: logger.error("Unable to parse git version output") logger.error("'git --version' output was:\n%s\n%s" % (stdout, stderr)) sys.exit(1) version = m.groups() if version[3] is not None: version = (int(version[0]), int(version[1]), int(version[2][1:]), int(version[3][1:])) elif version[2] is not None: version = (int(version[0]), int(version[1]), int(version[2][1:])) else: version = (int(version[0]), int(version[1])) if version < (1, 5): logger.error("Git version %s is unsupported, please upgrade", ".".join([str(v) for v in version])) sys.exit(1) return version
def git_merge_rbranch(self, stdout_in, stderr_in, accept_missing=False): path = self.source['path'] branch = self.source.get('branch', 'master') cmd = self.run_git(["branch", "-a"], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("'git branch -a' failed.\n%s" % stderr) stdout_in += stdout stderr_in += stderr if not re.search(b("^(\*| ) %s$" % re.escape(branch)), stdout, re.M): # The branch is not local. We should not have reached # this, unless no branch was specified and we guess wrong # that it should be master. if accept_missing: logger.info("No such branch %r", branch) return (stdout_in, stderr_in) else: logger.error("No such branch %r", branch) sys.exit(1) rbp = self._remote_branch_prefix cmd = self.run_git(["merge", "%s/%s" % (rbp, branch)], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError( "git merge of remote branch 'origin/%s' failed.\n%s" % (branch, stderr)) return (stdout_in + stdout, stderr_in + stderr)
def status(self, **kwargs): path = self.source['path'] env = dict(os.environ) env.pop('PYTHONPATH', None) cmd = subprocess.Popen(['hg', 'status'], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() status = stdout and 'dirty' or 'clean' if status == 'clean': cmd = subprocess.Popen(['hg', 'outgoing'], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) outgoing_stdout, stderr = cmd.communicate() stdout += b('\n') + outgoing_stdout if cmd.returncode == 0: status = 'ahead' if kwargs.get('verbose', False): return status, stdout else: return status
def git_switch_branch(self, stdout_in, stderr_in, accept_missing=False): """Switch branches. If accept_missing is True, we do not switch the branch if it is not there. Useful for switching back to master. """ path = self.source['path'] branch = self.source.get('branch', 'master') rbp = self._remote_branch_prefix cmd = self.run_git(["branch", "-a"], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("'git branch -a' failed.\n%s" % stderr) stdout_in += stdout stderr_in += stderr if 'rev' in self.source: # A tag or revision was specified instead of a branch argv = ["checkout", self.source['rev']] self.output( (logger.info, "Switching to rev '%s'." % self.source['rev'])) elif re.search(b("^(\*| ) %s$" % re.escape(branch)), stdout, re.M): # the branch is local, normal checkout will work argv = ["checkout", branch] self.output((logger.info, "Switching to branch '%s'." % branch)) elif re.search( b("^ " + re.escape(rbp) + "\/" + re.escape(branch) + "$"), stdout, re.M): # the branch is not local, normal checkout won't work here rbranch = "%s/%s" % (rbp, branch) argv = ["checkout", "-b", branch, rbranch] self.output( (logger.info, "Switching to remote branch '%s'." % rbranch)) elif accept_missing: self.output((logger.info, "No such branch %r", branch)) return (stdout_in + stdout, stderr_in + stderr) else: self.output((logger.error, "No such branch %r", branch)) sys.exit(1) # runs the checkout with predetermined arguments cmd = self.run_git(argv, cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("git checkout of branch '%s' failed.\n%s" % (branch, stderr)) return (stdout_in + stdout, stderr_in + stderr)
def matches(self): name = self.source['name'] path = self.source['path'] env = dict(os.environ) env.pop('PYTHONPATH', None) cmd = subprocess.Popen( ['hg', 'showconfig', 'paths.default'], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise MercurialError( 'hg showconfig for %r failed.\n%s' % (name, stderr)) # now check that the working branch is the same return b(self.source['url'] + '\n') == stdout
def matches(self): name = self.source['name'] path = self.source['path'] env = dict(os.environ) env.pop('PYTHONPATH', None) cmd = subprocess.Popen(['hg', 'showconfig', 'paths.default'], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise MercurialError('hg showconfig for %r failed.\n%s' % (name, stderr)) # now check that the working branch is the same return b(self.source['url'] + '\n') == stdout
def matches(self): name = self.source["name"] path = self.source["path"] env = dict(os.environ) env.pop("PYTHONPATH", None) cmd = subprocess.Popen( [self.hg_executable, "showconfig", "paths.default"], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise MercurialError("hg showconfig for %r failed.\n%s" % (name, stderr)) # now check that the working branch is the same return b(self.source["url"] + "\n") == stdout
def status(self, **kwargs): path = self.source['path'] env = dict(os.environ) env.pop('PYTHONPATH', None) cmd = subprocess.Popen( ['hg', 'status'], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() status = stdout and 'dirty' or 'clean' if status == 'clean': cmd = subprocess.Popen( ['hg', 'outgoing'], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) outgoing_stdout, stderr = cmd.communicate() stdout += b('\n') + outgoing_stdout if cmd.returncode == 0: status = 'ahead' if kwargs.get('verbose', False): return status, stdout else: return status
def status(self, **kwargs): path = self.source["path"] env = dict(os.environ) env.pop("PYTHONPATH", None) cmd = subprocess.Popen( [self.hg_executable, "status"], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout, stderr = cmd.communicate() status = stdout and "dirty" or "clean" if status == "clean": cmd = subprocess.Popen( [self.hg_executable, "outgoing"], cwd=path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) outgoing_stdout, stderr = cmd.communicate() stdout += b("\n") + outgoing_stdout if cmd.returncode == 0: status = "ahead" if kwargs.get("verbose", False): return status, stdout else: return status
def git_version(self): cmd = self.run_git(['--version']) stdout, stderr = cmd.communicate() if cmd.returncode != 0: logger.error("Could not determine git version") logger.error("'git --version' output was:\n%s\n%s" % (stdout, stderr)) sys.exit(1) m = re.search(b("git version (\d+)\.(\d+)(\.\d+)?(\.\d+)?"), stdout) if m is None: logger.error("Unable to parse git version output") logger.error("'git --version' output was:\n%s\n%s" % (stdout, stderr)) sys.exit(1) version = m.groups() if version[3] is not None: version = ( int(version[0]), int(version[1]), int(version[2][1:]), int(version[3][1:]) ) elif version[2] is not None: version = ( int(version[0]), int(version[1]), int(version[2][1:]) ) else: version = (int(version[0]), int(version[1])) if version < (1, 5): logger.error( "Git version %s is unsupported, please upgrade", ".".join([str(v) for v in version])) sys.exit(1) return version
def testUpdateWithRevisionPin(self, develop, src, tempdir): from mr.developer.commands import CmdCheckout from mr.developer.commands import CmdUpdate repository = tempdir['repository'] os.mkdir(repository) process = Process(cwd=repository) lines = process.check_call("hg init %s" % repository) foo = repository['foo'] foo.create_file('foo') lines = process.check_call("hg add %s" % foo, echo=False) # create branch for testing lines = process.check_call("hg branch test", echo=False) lines = process.check_call("hg commit %s -m foo -u test" % foo, echo=False) # get comitted rev lines = process.check_call("hg log %s" % foo, echo=False) try: # XXX older version rev = lines[0].split()[1].split(b(':'))[1] except: rev = lines[0].split()[1] # return to default branch lines = process.check_call("hg branch default", echo=False) bar = repository['bar'] bar.create_file('bar') lines = process.check_call("hg add %s" % bar, echo=False) lines = process.check_call("hg commit %s -m bar -u test" % bar, echo=False) # check rev develop.sources = { 'egg': Source( kind='hg', name='egg', rev=rev, url='%s' % repository, path=os.path.join(src, 'egg'))} CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) CmdUpdate(develop)(develop.parser.parse_args(['up', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) # check branch develop.sources = { 'egg': Source( kind='hg', name='egg', branch='test', url='%s' % repository, path=os.path.join(src, 'egg'))} CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) CmdUpdate(develop)(develop.parser.parse_args(['up', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) # we can't use both rev and branch pytest.raises(SystemExit, """ develop.sources = { 'egg': Source( kind='hg', name='egg', branch='test', rev=rev, url='%s' % repository, path=os.path.join(src, 'egg-failed'))} CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) """)
def testUpdateWithRevisionPin(self, develop, src, tempdir): from mr.developer.commands import CmdCheckout from mr.developer.commands import CmdUpdate repository = tempdir['repository'] os.mkdir(repository) process = Process(cwd=repository) lines = process.check_call("hg init %s" % repository) foo = repository['foo'] foo.create_file('foo') lines = process.check_call("hg add %s" % foo, echo=False) # create branch for testing lines = process.check_call("hg branch test", echo=False) lines = process.check_call("hg commit %s -m foo -u test" % foo, echo=False) # get comitted rev lines = process.check_call("hg log %s" % foo, echo=False) try: # XXX older version rev = lines[0].split()[1].split(b(':'))[1] except Exception: rev = lines[0].split()[1] # return to default branch lines = process.check_call("hg branch default", echo=False) bar = repository['bar'] bar.create_file('bar') lines = process.check_call("hg add %s" % bar, echo=False) lines = process.check_call("hg commit %s -m bar -u test" % bar, echo=False) # check rev develop.sources = { 'egg': Source(kind='hg', name='egg', rev=rev, url='%s' % repository, path=os.path.join(src, 'egg')) } CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) CmdUpdate(develop)(develop.parser.parse_args(['up', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) # check branch develop.sources = { 'egg': Source(kind='hg', name='egg', branch='test', url='%s' % repository, path=os.path.join(src, 'egg')) } CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) CmdUpdate(develop)(develop.parser.parse_args(['up', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) # we can't use both rev and branch with pytest.raises(SystemExit): develop.sources = { 'egg': Source(kind='hg', name='egg', branch='test', rev=rev, url='%s' % repository, path=os.path.join(src, 'egg-failed')) } CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg']))
def testUpdateWithRevisionPin(self): from mr.developer.develop import CmdCheckout from mr.developer.develop import CmdUpdate repository = os.path.join(self.tempdir, 'repository') os.mkdir(repository) process = Process(cwd=repository) rc, lines = process.popen( "hg init %s" % repository) assert rc == 0 foo = os.path.join(repository, 'foo') self.mkfile(foo, 'foo') rc, lines = process.popen( "hg add %s" % foo, echo=False) assert rc == 0 # create branch for testing rc, lines = process.popen( "hg branch test", echo=False) assert rc == 0 rc, lines = process.popen( "hg commit %s -m foo -u test" % foo, echo=False) assert rc == 0 # get comitted rev rc, lines = process.popen( "hg log %s" % foo, echo=False) assert rc == 0 try: # XXX older version rev = lines[0].split()[1].split(b(':'))[1] except: rev = lines[0].split()[1] # return to default branch rc, lines = process.popen( "hg branch default", echo=False) assert rc == 0 bar = os.path.join(repository, 'bar') self.mkfile(bar, 'bar') rc, lines = process.popen( "hg add %s" % bar, echo=False) assert rc == 0 rc, lines = process.popen( "hg commit %s -m bar -u test" % bar, echo=False) assert rc == 0 src = os.path.join(self.tempdir, 'src') os.mkdir(src) develop = MockDevelop() # check rev develop.sources = { 'egg': Source( kind='hg', name='egg', rev=rev, url='%s' % repository, path=os.path.join(src, 'egg'))} CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) CmdUpdate(develop)(develop.parser.parse_args(['up', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) # check branch develop.sources = { 'egg': Source( kind='hg', name='egg', branch='test', url='%s' % repository, path=os.path.join(src, 'egg'))} CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) CmdUpdate(develop)(develop.parser.parse_args(['up', 'egg'])) assert set(os.listdir(os.path.join(src, 'egg'))) == set(('.hg', 'foo')) # we can't use both rev and branch pytest.raises(SystemExit, """ develop.sources = { 'egg': Source( kind='hg', name='egg', branch='test', rev=rev, url='%s' % repository, path=os.path.join(src, 'egg-failed'))} CmdCheckout(develop)(develop.parser.parse_args(['co', 'egg'])) """)