def GitCloneToMirror(self): """Clone the upstream git repo into a local mirror. """ git_url, git_commit = self.URL.split('@', 2) # Clone upstream git repo into local mirror, or update the existing # mirror. git_mirror = git_url.split('://', 2)[1] git_mirror = git_mirror.replace('/', '_') mirror_dir = os.path.join(paths.CACHE_ROOT, git_mirror) if os.path.exists(mirror_dir): if RunGitCmd(mirror_dir, ['rev-parse', git_commit + '^{commit}'], error_ok=True) != 0: Log('Updating git mirror: %s' % util.RelPath(mirror_dir)) RunGitCmd(mirror_dir, ['remote', 'update', '--prune']) else: Log('Mirroring upstream git repo: %s' % self.URL) RunGitCmd(paths.CACHE_ROOT, ['clone', '--mirror', git_url, git_mirror]) Log('git mirror up-to-date: %s' % util.RelPath(mirror_dir)) return mirror_dir, git_commit
def Extract(self): """Extract the package archive into its build location. This method assumes the package has already been downloaded. """ if self.IsGitUpstream(): self.GitClone() return archive = self.DownloadLocation() if not archive: self.Log('Skipping extract; No upstream archive') return dest = self.GetBuildLocation() output_path, new_foldername = os.path.split(dest) util.Makedirs(output_path) # Check existing stamp file contents stamp_file = self.GetExtractStamp() stamp_contents = self.GetExtractStampContent() if os.path.exists(dest): if StampContentsMatch(stamp_file, stamp_contents): Log('Already up-to-date: %s' % util.RelPath(dest)) return raise Error("Upstream archive or patch has changed.\n" + "Please remove existing checkout and try again: '%s'" % dest) util.LogHeading('Extracting') util.Makedirs(paths.OUT_DIR) tmp_output_path = tempfile.mkdtemp(dir=paths.OUT_DIR) try: ExtractArchive(archive, tmp_output_path) src = os.path.join(tmp_output_path, new_foldername) if not os.path.isdir(src): raise Error('Archive contents not found: %s' % src) LogVerbose("renaming '%s' -> '%s'" % (src, dest)) os.rename(src, dest) finally: util.RemoveTree(tmp_output_path) self.RemoveStamps() WriteStamp(stamp_file, stamp_contents)
def Download(self, force_mirror=None): """Download upstream sources and verify integrity.""" if self.IsGitUpstream(): self.GitCloneToMirror() return archive = self.DownloadLocation() if not archive: return if force_mirror is None: force_mirror = os.environ.get('FORCE_MIRROR', False) self.DownloadArchive(force_mirror=force_mirror) if self.SHA1 is None: raise PkgFormatError('missing SHA1 attribute: %s' % self.info) util.VerifyHash(archive, self.SHA1) Log('verified: %s' % util.RelPath(archive))
def UpdatePatch(self): if self.URL is None: return git_dir = self.GetBuildLocation() if not os.path.exists(git_dir): raise Error('Source directory not found: %s' % git_dir) try: diff = subprocess.check_output( ['git', 'diff', 'upstream', '--no-ext-diff'], cwd=git_dir) except subprocess.CalledProcessError as e: raise Error('error running git in %s: %s' % (git_dir, str(e))) # Drop index lines for a more stable diff. diff = re.sub('\nindex [^\n]+\n', '\n', diff) # Drop binary files, as they don't work anyhow. diff = re.sub( 'diff [^\n]+\n' '(new file [^\n]+\n)?' '(deleted file mode [^\n]+\n)?' 'Binary files [^\n]+ differ\n', '', diff) # Filter out things from an optional per port skip list. diff_skip = os.path.join(self.root, 'diff_skip.txt') if os.path.exists(diff_skip): names = open(diff_skip).read().splitlines() new_diff = '' skipping = False for line in diff.splitlines(): if line.startswith('diff --git '): skipping = False for name in names: if line == 'diff --git a/%s b/%s' % (name, name): skipping = True if not skipping: new_diff += line + '\n' diff = new_diff # Write back out the diff. patch_path = self.GetPatchFile() preexisting = os.path.exists(patch_path) if not diff: if preexisting: Log('removing patch file: %s' % util.RelPath(patch_path)) os.remove(patch_path) else: Log('no patch required: %s' % util.RelPath(git_dir)) return if preexisting: with open(patch_path) as f: if diff == f.read(): Log('patch unchanged: %s' % util.RelPath(patch_path)) return with open(patch_path, 'w') as f: f.write(diff) if preexisting: Log('created patch: %s' % util.RelPath(patch_path)) else: Log('updated patch: %s' % util.RelPath(patch_path))
def testRelPath(self): self.assertEqual('bar', util.RelPath('/foo/bar')) self.assertEqual('../baz/bar', util.RelPath('/baz/bar'))