def _addAppYaml(self): """Create a Google production app.yaml configuration. The file is copied and modified from the upstream app.yaml.template, configure for Google's Summer of Code App Engine instance, and committed. """ if self.wc.exists(self._branchPath('app/app.yaml')): raise ObstructionError('app/app.yaml exists already') yaml_path = self._branchPath('app/app.yaml') self.wc.copy(yaml_path + '.template', yaml_path) yaml = io.fileToLines(self.wc.path(yaml_path)) out = [] for i, line in enumerate(yaml): stripped_line = line.strip() if 'TODO' in stripped_line: continue elif stripped_line == '# application: FIXME': out.append('application: socghop') elif stripped_line.startswith('version:'): out.append(line.lstrip() + 'g0') out.append('# * initial Google fork of Melange ' + self.branch) else: out.append(line) io.linesToFile(self.wc.path(yaml_path), out) self.wc.commit('Create app.yaml with Google patch version g0 ' 'in branch ' + self.branch)
def _switchBranch(self, release): """Activate the branch matching the given release. Once activated, this branch is the target of future release operations. None can be passed as the release. The result is that no branch is active, and all operations that require an active branch will fail until a branch is activated again. This is used only at initialization, when it is detected that there are no available release branches to activate. Args: release: The version number of a Melange release already imported in the release repository, or None to activate no branch. """ if release is None: self.branch = None self.branch_dir = None log.info('No release branch available') else: self.wc.update() assert self.wc.exists('branches/' + release) io.linesToFile(self.path(self.BRANCH_FILE), [release]) self.branch = release self.branch_dir = 'branches/' + release self.wc.update(self.branch_dir, depth='infinity') log.info('Working on branch ' + self.branch)
def cherryPickChange(self): """Cherry-pick a change from the Melange trunk""" rev = io.getNumber('Revision number to cherry-pick:') bug = io.getNumber('Issue fixed by this change:') diff = subversion.diff(self.upstream_repos + '/trunk', rev) if not diff.strip(): raise error.ExpectationFailed( 'Retrieved diff is empty. ' 'Did you accidentally cherry-pick a branch change?') util.run(['patch', '-p0'], cwd=self.wc.path(self.branch_dir), stdin=diff) self.wc.addRemove(self.branch_dir) yaml_path = self.wc.path(self._branchPath('app/app.yaml')) out = [] updated_patchlevel = False for line in io.fileToLines(yaml_path): if line.strip().startswith('version: '): version = line.strip().split()[-1] base, patch = line.rsplit('g', 1) new_version = '%sg%d' % (base, int(patch) + 1) message = ('Cherry-picked r%d from /p/soc/ to fix issue %d' % (rev, bug)) out.append('version: ' + new_version) out.append('# * ' + message) updated_patchlevel = True else: out.append(line) if not updated_patchlevel: log.error('Failed to update Google patch revision') log.error('Cherry-picking failed') io.linesToFile(yaml_path, out) log.info('Check the diff about to be committed with:') log.info('svn diff ' + self.wc.path(self.branch_dir)) if not io.confirm('Commit this change?'): raise error.AbortedByUser('Cherry-pick aborted') self.wc.commit(message) log.info('Cherry-picked r%d from the Melange trunk.' % rev)
def _applyGooglePatches(self): """Apply Google-specific patches to a vanilla Melange release. Each patch is applied and committed in turn. """ # Edit the base template to point users to the Google fork # of the Melange codebase instead of the vanilla release. tmpl_file = self.wc.path( self._branchPath('app/soc/templates/soc/base.html')) tmpl = io.fileToLines(tmpl_file) for i, line in enumerate(tmpl): if 'http://code.google.com/p/soc/source/browse/tags/' in line: tmpl[i] = line.replace('/p/soc/', '/p/soc-google/') break else: raise error.ExpectationFailed( 'No source code link found in base.html') io.linesToFile(tmpl_file, tmpl) self.wc.commit( 'Customize the Melange release link in the sidebar menu')