def main(self, argv): # DO NOT CALL BaseCliModule.main(self) # we are initializing tito to work in this module and # calling main will result in a configuration error. (self.options, self.args) = self.parser.parse_args(argv) should_commit = False rel_eng_dir = os.path.join(find_git_root(), '.tito') print("Creating tito metadata in: %s" % rel_eng_dir) propsfile = os.path.join(rel_eng_dir, TITO_PROPS) if not os.path.exists(propsfile): if not os.path.exists(rel_eng_dir): getoutput("mkdir -p %s" % rel_eng_dir) print(" - created %s" % rel_eng_dir) # write out tito.props out_f = open(propsfile, 'w') out_f.write("[buildconfig]\n") out_f.write("builder = %s\n" % 'tito.builder.Builder') out_f.write("tagger = %s\n" % 'tito.tagger.VersionTagger') out_f.write("changelog_do_not_remove_cherrypick = 0\n") out_f.write("changelog_format = %s (%ae)\n") out_f.close() print(" - wrote %s" % TITO_PROPS) getoutput('git add %s' % propsfile) should_commit = True # prep the packages metadata directory pkg_dir = os.path.join(rel_eng_dir, "packages") readme = os.path.join(pkg_dir, '.readme') if not os.path.exists(readme): if not os.path.exists(pkg_dir): getoutput("mkdir -p %s" % pkg_dir) print(" - created %s" % pkg_dir) # write out readme file explaining what pkg_dir is for readme = os.path.join(pkg_dir, '.readme') out_f = open(readme, 'w') out_f.write( "the .tito/packages directory contains metadata files\n") out_f.write( "named after their packages. Each file has the latest tagged\n" ) out_f.write("version and the project's relative directory.\n") out_f.close() print(" - wrote %s" % readme) getoutput('git add %s' % readme) should_commit = True if should_commit: getoutput('git commit -m "Initialized to use tito. "') print(" - committed to git") info_out("Done!") return []
def _create_build_dirs(self): """ Create the build directories. Can safely be called multiple times. """ getoutput("mkdir -p %s %s %s %s" % (self.rpmbuild_basedir, self.rpmbuild_dir, self.rpmbuild_sourcedir, self.rpmbuild_builddir)) self._check_build_dirs_access()
def _create_build_dirs(self): """ Create the build directories. Can safely be called multiple times. """ getoutput("mkdir -p %s %s %s %s" % ( self.rpmbuild_basedir, self.rpmbuild_dir, self.rpmbuild_sourcedir, self.rpmbuild_builddir)) self._check_build_dirs_access()
def main(self, argv): # DO NOT CALL BaseCliModule.main(self) # we are initializing tito to work in this module and # calling main will result in a configuration error. (self.options, self.args) = self.parser.parse_args(argv) should_commit = False rel_eng_dir = os.path.join(find_git_root(), '.tito') print("Creating tito metadata in: %s" % rel_eng_dir) propsfile = os.path.join(rel_eng_dir, TITO_PROPS) if not os.path.exists(propsfile): if not os.path.exists(rel_eng_dir): getoutput("mkdir -p %s" % rel_eng_dir) print(" - created %s" % rel_eng_dir) # write out tito.props out_f = open(propsfile, 'w') out_f.write("[buildconfig]\n") out_f.write("builder = %s\n" % 'tito.builder.Builder') out_f.write( "tagger = %s\n" % 'tito.tagger.VersionTagger') out_f.write("changelog_do_not_remove_cherrypick = 0\n") out_f.write("changelog_format = %s (%ae)\n") out_f.close() print(" - wrote %s" % TITO_PROPS) getoutput('git add %s' % propsfile) should_commit = True # prep the packages metadata directory pkg_dir = os.path.join(rel_eng_dir, "packages") readme = os.path.join(pkg_dir, '.readme') if not os.path.exists(readme): if not os.path.exists(pkg_dir): getoutput("mkdir -p %s" % pkg_dir) print(" - created %s" % pkg_dir) # write out readme file explaining what pkg_dir is for readme = os.path.join(pkg_dir, '.readme') out_f = open(readme, 'w') out_f.write("the .tito/packages directory contains metadata files\n") out_f.write("named after their packages. Each file has the latest tagged\n") out_f.write("version and the project's relative directory.\n") out_f.close() print(" - wrote %s" % readme) getoutput('git add %s' % readme) should_commit = True if should_commit: getoutput('git commit -m "Initialized to use tito. "') print(" - committed to git") info_out("Done!") return []
def cleanup(self): """ Remove all temporary files and directories. """ if not self.no_cleanup: os.chdir('/') debug("Cleaning up [%s]" % self.rpmbuild_dir) getoutput("rm -rf %s" % self.rpmbuild_dir) else: print("WARNING: Leaving rpmbuild files in: %s" % self.rpmbuild_dir)
def test_git_contains_cargo(self): """ Check presence of the Cargo.toml file in the last commit (tag) """ diff = getoutput("git diff HEAD^ -- Cargo.toml") assert diff.find("-version = \"0.0.1\"") != -1 assert diff.find("+version = \"0.1.8\"") != -1
def test_undo_tag(self): os.chdir(self.repo_dir) original_head = getoutput('git show-ref -s refs/heads/master') # Create tito tag, which adds a new commit and moves head. tito("tag --accept-auto-changelog --debug") tag = "%s-0.0.2-1" % PKG_NAME check_tag_exists(tag, offline=True) new_head = getoutput('git show-ref -s refs/heads/master') self.assertNotEqual(original_head, new_head) # Undo tito tag, which rewinds one commit to original head. tito("tag -u") self.assertFalse(tag_exists_locally(tag)) new_head = getoutput('git show-ref -s refs/heads/master') self.assertEqual(original_head, new_head)
def release(self, dry_run=False, no_build=False, scratch=False): self.dry_run = dry_run self.no_build = no_build getoutput("mkdir -p %s" % self.working_dir) os.chdir(self.working_dir) run_command("%s co %s %s" % (self.cli_tool, self.obs_project_name, self.obs_package_name)) os.chdir(self.package_workdir) self.builder.tgz() if self.test: self.builder._setup_test_specfile() self._obs_sync_files(self.package_workdir) self._obs_user_confirm_commit(self.package_workdir)
def test_tag_with_changelog_multiple(self): tito("tag --accept-auto-changelog --use-version 9.0.0 --changelog=Test --changelog=Fake") check_tag_exists("%s-9.0.0-1" % PKG_NAME, offline=True) changelog = getoutput("cat *.spec") self.assertTrue('- Test' in changelog) self.assertTrue('- Fake' in changelog)
def build_in_mock(self, branch): """Build the sources in self.package_workdir as rhpkg woulb build them if they were pushed to the specified distgit branch The following environment variables can affect how this method works: - KOJI_TOPURL: Specifies a Koji package mirror to use - KOJI_PROFILE: Specifies which Koji configuration profile to use (defaults to 'brew') """ print("Building branch '{0}' in Mock".format(branch)) out_dir = os.path.join( self.builder.rpmbuild_basedir, '{0}-{1}'.format(self.project_name, self.builder.build_version), branch) getoutput("mkdir -p %s" % out_dir) print('build output will be written to {0}'.format(out_dir)) # Logic taken from pyrpkg sources: target = '%s-candidate' % branch mock_conf = mock_config.compose( mock_config.from_koji( target=target, topurl=os.environ.get('KOJI_TOPURL', None), koji_profile=os.environ.get('KOJI_PROFILE', 'brew'), ), mock_config.to['resultdir'].set(out_dir), mock_config.to['root_cache_enable'].set(True), mock_config.to['yum_cache_enable'].set(True)) extra_yum_config = self._build_extra_yum_config(branch) if extra_yum_config: print('Injecting extra yum configuration to Mock') mock_conf.append(mock_config.to['yum.conf'].add(extra_yum_config)) debug('Dumping mock configuration') debug(str(mock_conf)) mock = MockChroot(config=mock_conf) print('Building SRPM in Mock') mock.buildsrpm( spec=self.builder.spec_file, sources=self.package_workdir, ) srpms = glob('{0}/*.src.rpm'.format(out_dir)) if len(srpms) == 0: raise RuntimeError('no srpms found in {0}'.format(out_dir)) elif len(srpms) > 1: raise RuntimeError('multiple srpms found in {0}'.format(out_dir)) else: srpm = srpms[0] print('Building RPM in Mock') mock.rebuild(src_rpm=srpm, no_clean=True)
def test_cargo_toml_tag(self): """ Check that the version string in Cargo.toml file is the same as in spec file """ changelog = getoutput("grep version Cargo.toml") re_version = re.compile(r'"(\d+\.\d+\.\d+)"') version = re_version.findall(changelog) assert version[0] == "0.1.8"
def _git_release(self): getoutput("mkdir -p %s" % self.working_dir) os.chdir(self.working_dir) run_command("%s clone %s" % (self.cli_tool, self.project_name)) project_checkout = os.path.join(self.working_dir, self.project_name) os.chdir(project_checkout) run_command("%s switch-branch %s" % (self.cli_tool, self.git_branches[0])) self.builder.tgz() if self.test: self.builder._setup_test_specfile() self._git_sync_files(project_checkout) self._git_upload_sources(project_checkout) self._git_user_confirm_commit(project_checkout)
def build_in_mock(self, branch): """Build the sources in self.package_workdir as rhpkg woulb build them if they were pushed to the specified distgit branch The following environment variables can affect how this method works: - KOJI_TOPURL: Specifies a Koji package mirror to use - KOJI_PROFILE: Specifies which Koji configuration profile to use (defaults to 'brew') """ print("Building branch '{0}' in Mock".format(branch)) out_dir = os.path.join( self.builder.rpmbuild_basedir, "{0}-{1}".format(self.project_name, self.builder.build_version), branch ) getoutput("mkdir -p %s" % out_dir) print("build output will be written to {0}".format(out_dir)) # Logic taken from pyrpkg sources: target = "%s-candidate" % branch mock_conf = mock_config.compose( mock_config.from_koji( target=target, topurl=os.environ.get("KOJI_TOPURL", None), koji_profile=os.environ.get("KOJI_PROFILE", "brew"), ), mock_config.to["resultdir"].set(out_dir), mock_config.to["root_cache_enable"].set(True), mock_config.to["yum_cache_enable"].set(True), ) extra_yum_config = self._build_extra_yum_config(branch) if extra_yum_config: print("Injecting extra yum configuration to Mock") mock_conf.append(mock_config.to["yum.conf"].add(extra_yum_config)) debug("Dumping mock configuration") debug(str(mock_conf)) mock = MockChroot(config=mock_conf) print("Building SRPM in Mock") mock.buildsrpm(spec=self.builder.spec_file, sources=self.package_workdir) srpms = glob("{0}/*.src.rpm".format(out_dir)) if len(srpms) == 0: raise RuntimeError("no srpms found in {0}".format(out_dir)) elif len(srpms) > 1: raise RuntimeError("multiple srpms found in {0}".format(out_dir)) else: srpm = srpms[0] print("Building RPM in Mock") mock.rebuild(src_rpm=srpm, no_clean=True)
def release(self, dry_run=False, no_build=False, scratch=False): self.dry_run = dry_run self.no_build = no_build getoutput("mkdir -p %s" % self.working_dir) os.chdir(self.working_dir) run_command( "%s co %s %s" % (self.cli_tool, self.obs_project_name, self.obs_package_name)) os.chdir(self.package_workdir) self.builder.tgz() if self.test: self.builder._setup_test_specfile() self._obs_sync_files(self.package_workdir) self._obs_user_confirm_commit(self.package_workdir)
def _git_release(self): getoutput("mkdir -p %s" % self.working_dir) with chdir(self.working_dir): run_command("%s clone %s" % (self.cli_tool, self.project_name)) with chdir(self.package_workdir): run_command("%s switch-branch %s" % (self.cli_tool, self.git_branches[0])) # Mead builds need to be in the git_root. Other builders are agnostic. with chdir(self.git_root): self.builder.tgz() if self.test: self.builder._setup_test_specfile() self._git_sync_files(self.package_workdir) self._git_upload_sources(self.package_workdir) self._git_user_confirm_commit(self.package_workdir)
def _git_release(self): getoutput("mkdir -p %s" % self.package_workdir) # Mead builds need to be in the git_root. Other builders are agnostic. with chdir(self.git_root): self.builder.tgz() if self.test: self.builder._setup_test_specfile() debug("Searching for source files to build") files_to_copy = self._list_files_to_copy() self._sync_files(files_to_copy, self.package_workdir) debug("would build with specfile: {0} and sources at: {1}".format(self.builder.spec_file, self.package_workdir)) debug("build branches: {0}".format(self.git_branches)) for branch in self.git_branches: self.build_in_mock(branch)
def test_tag_with_custom_message(self): os.chdir(self.repo_dir) with open(os.path.join(self.repo_dir, '.tito', 'tito.props'), 'a') as f: f.write('tag_commit_message_format = No info plz\n') tito("tag --accept-auto-changelog") last_msg = getoutput('git log -n 1 --pretty=format:%s') self.assertEqual('No info plz', last_msg.strip())
def test_tag_with_custom_message_containing_quotes(self): os.chdir(self.repo_dir) with open(os.path.join(self.repo_dir, '.tito', 'tito.props'), 'a') as f: f.write('tag_commit_message_format = Hack"%(name)s\\\n') tito("tag --accept-auto-changelog") last_msg = getoutput('git log -n 1 --pretty=format:%s') self.assertEqual('Hack"titotestpkg\\', last_msg.strip())
def _git_release(self): getoutput("mkdir -p %s" % self.package_workdir) # Mead builds need to be in the git_root. Other builders are agnostic. with chdir(self.git_root): self.builder.tgz() if self.test: self.builder._setup_test_specfile() debug("Searching for source files to build") files_to_copy = self._list_files_to_copy() self._sync_files(files_to_copy, self.package_workdir) debug("would build with specfile: {0} and sources at: {1}".format( self.builder.spec_file, self.package_workdir)) debug("build branches: {0}".format(self.git_branches)) for branch in self.git_branches: self.build_in_mock(branch)
def copy_extra_sources(self): # C&P from tito/builder.main.py cmd = "spectool -S '%s' --define '_sourcedir %s' | awk '{print $2}'"\ % (self.spec_file, self.start_dir) sources = getoutput(cmd).split("\n") for source in sources[1:]: if not source.startswith("https://"): # so far we don't have local sources in copr project continue target = os.path.join( self.rpmbuild_sourcedir, os.path.basename(source), ) # TODO: check md5sum somehow info_out("Downloading %s into %s" % (source, target)) urllib.request.urlretrieve(source, target) self.sources.append(target)
def test_tag(self): """ Check that the tag is correct """ latest_tag = getoutput("git describe --abbrev=0 --tags") assert latest_tag == 'hello_tito-v0.1.8'