def status(self, **kwargs): name = self.source['name'] path = self.source['path'] cmd = subprocess.Popen(["svn", "status", "--xml", path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise SVNError("Subversion status for '%s' failed.\n%s" % (name, s(stderr))) info = etree.fromstring(stdout) clean = True for target in info.findall('target'): for entry in target.findall('entry'): status = entry.find('wc-status') if status is not None and status.get('item') != 'external': clean = False break if clean: status = 'clean' else: status = 'dirty' if kwargs.get('verbose', False): cmd = subprocess.Popen(["svn", "status", path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise SVNError("Subversion status for '%s' failed.\n%s" % (name, s(stderr))) return status, s(stdout) else: return status
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 _svn_checkout(self, **kwargs): name = self.source['name'] path = self.source['path'] url = self.source['url'] args = ["svn", "checkout", url, path] stdout, stderr, returncode = self._svn_communicate(args, url, **kwargs) if returncode != 0: raise SVNError("Subversion checkout for '%s' failed.\n%s" % (name, s(stderr))) if kwargs.get('verbose', False): return s(stdout)
def git_init_submodules(self, stdout_in, stderr_in): cmd = self.run_git(['submodule', 'init'], cwd=self.source['path']) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("git submodule init failed.\n") output = s(stdout) if not output: output = s(stderr) initialized_submodules = re.findall(r'\s+[\'"](.*?)[\'"]\s+\(.+\)', output) return (stdout_in + stdout, stderr_in + stderr, initialized_submodules)
def _svn_update(self, **kwargs): name = self.source['name'] path = self.source['path'] url, rev = self._normalized_url_rev() args = ["svn", "update", path] if rev is not None and not rev.startswith('>'): args.insert(2, '-r%s' % rev) stdout, stderr, returncode = self._svn_communicate(args, url, **kwargs) if returncode != 0: raise SVNError("Subversion update of '%s' failed.\n%s" % (name, s(stderr))) if kwargs.get('verbose', False): return s(stdout)
def git_run(self, commands, **kwargs): commands.insert(0, self.git_executable) kwargs['stdout'] = subprocess.PIPE kwargs['stderr'] = subprocess.PIPE # This should ease things up when multiple processes are trying to send # back to the main one large chunks of output kwargs['bufsize'] = -1 cmd = subprocess.Popen(commands, **kwargs) stdout, stderr = cmd.communicate() self._git_stdout.append(s(stdout)) if cmd.returncode != 0: raise GitError("'%s'\n%s\n%s" % ( ' '.join(commands), s(stdout), s(stderr))) return stdout
def _svn_info(self): name = self.source['name'] if name in self._svn_info_cache: return self._svn_info_cache[name] path = self.source['path'] cmd = subprocess.Popen(["svn", "info", "--non-interactive", "--xml", path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise SVNError("Subversion info for '%s' failed.\n%s" % (name, s(stderr))) info = etree.fromstring(stdout) result = {} entry = info.find('entry') if entry is not None: rev = entry.attrib.get('revision') if rev is not None: result['revision'] = rev info_url = entry.find('url') if info_url is not None: result['url'] = info_url.text entry = info.find('entry') if entry is not None: root = entry.find('root') if root is not None: result['root'] = root.text self._svn_info_cache[name] = result return result
def matches(self): name = self.source['name'] path = self.source['path'] # This is the old matching code: it does not work on 1.5 due to the # lack of the -v switch output = self.git_run(["remote", "show", "-n", self._upstream_name], cwd=path) return (self.source['url'] in s(output).split())
def matches(self): name = self.source['name'] path = self.source['path'] # This is the old matching code: it does not work on 1.5 due to the # lack of the -v switch cmd = self.run_git(["remote", "show", "-n", self._upstream_name], cwd=path) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("git remote of '%s' failed.\n%s" % (name, stderr)) return (self.source['url'] in s(stdout).split())
def git_init_submodules(self, stdout_in, stderr_in): cmd = self.run_git( [ 'submodule', 'init'], cwd=self.source['path']) stdout, stderr = cmd.communicate() if cmd.returncode != 0: raise GitError("git submodule init failed.\n") initialized_submodules = re.findall( r'\s+[\'"](.*?)[\'"]\s+\(.+\)', s(stdout)) return (stdout_in + stdout, stderr_in + stderr, initialized_submodules)
def tee2(process, filter_func): """Read lines from process.stderr and echo them to sys.stderr. The 'filter_func' is a callable which is invoked for every line, receiving the line as argument. If the filter_func returns True, the line is echoed to sys.stderr. """ while True: line = process.stderr.readline() if line: stripped_line = line.rstrip() if filter_func(stripped_line): sys.stderr.write(s(line)) elif process.poll() is not None: break
def tee(process, filter_func): """Read lines from process.stdout and echo them to sys.stdout. Returns a list of lines read. Lines are not newline terminated. The 'filter_func' is a callable which is invoked for every line, receiving the line as argument. If the filter_func returns True, the line is echoed to sys.stdout. """ # We simply use readline here, more fancy IPC is not warranted # in the context of this package. lines = [] while True: line = process.stdout.readline() if line: stripped_line = line.rstrip() if filter_func(stripped_line): sys.stdout.write(s(line)) lines.append(stripped_line) elif process.poll() is not None: break return lines
def git_current_branch(self, **kwargs): try: output = self.git_run(["symbolic-ref", "--short", "HEAD"], **kwargs) except GitError: return None return s(output).strip()
def git_init_submodules(self): output = self.git_run(['submodule', 'init'], cwd=self.source['path']) return re.findall( r'\s+[\'"](.*?)[\'"]\s+\(.+\)', s(output))