def patched(self, project_dir, spec, sack): f = NamedTemporaryFile(delete=False, prefix="rpg_plugin_c_") file_name = f.name f.close() out = Command(["find " + str(project_dir) + " -name *.c -o -name *.h"]).execute() files_list = [str(s) for s in out.splitlines()] makedepend = "makedepend -w10000 -f" + file_name + " -I" \ + str(project_dir) + " " + \ ' '.join(files_list) + " 2>/dev/null" Command(makedepend).execute() regex = compile(r'.*\.h') regex2 = compile(str(project_dir) + ".*") unlink(file_name + ".bak") with open(file_name, "r") as f: _ret_paths = set([path.dirname(s) for s in f.read().split() if regex.match(s) and not regex2.match(s)]) unlink(file_name) spec.required_files = spec.required_files.union(_ret_paths) spec.build_required_files = spec.build_required_files.union(_ret_paths)
def test_command_concat(self): cmd = Command("cd %s" % self.test_project_dir) cmd.append("cmake ..") cmd.append(["make", "make test"]) self.assertRaises(TypeError, cmd.append, 4) expected = "cd %s\ncmake ..\nmake\nmake test" % self.test_project_dir self.assertEqual(expected, str(cmd))
def test_spec_assignment(self): self.assertEqual("", self.spec.Name) self.assertTrue(isinstance(self.spec.build, Command)) self.assertEqual("", str(self.spec.build)) self.spec.build = Command(["cmake .", "make"]) self.assertTrue(isinstance(self.spec.build, Command)) self.spec.install = Command("make install") self.assertTrue(isinstance(self.spec.install, Command)) self.spec.check = Command("make test") self.assertTrue(isinstance(self.spec.check, Command)) self.assertTrue(isinstance(self.spec.Requires, set)) self.spec.Requires.add("python3") self.assertTrue(isinstance(self.spec.Requires, set)) self.spec.Requires.add("python3-qt5") self.spec.Requires = sorted(list(self.spec.Requires)) expected = "Requires:\tpython3\n" \ "Requires:\tpython3-qt5\n" \ "%build\ncmake .\nmake\n\n" \ "%install\nmake install\n\n" \ "%check\nmake test\n\n" self.assertEqual(expected, str(self.spec)) self.spec.files = set([("f1", "a1", ""), ("f2", "a2", ""), ("f3", "a3", "")]) self.spec.files = sorted(list(self.spec.files)) expected += "%files\n" \ "a1 f1\n" \ "a2 f2\n" \ "a3 f3\n\n" self.assertEqual(expected, str(self.spec))
def patched(self, project_dir, spec, sack): """ Finds dependencies via makedepend - This is not garanteed to be all of them. Makedepend uses macro preprocessor and if it throws and error makedepend didn't print deps. """ out = Command([ "find " + path_to_str(project_dir) + " -name " + " -o -name ".join( ["'*." + ex + "'" for ex in self.EXT_CPP] ) ]).execute() cc_makedep = "" cc_included_files = [] for _f in out.splitlines(): try: cc_makedep = Command("makedepend -w 1000 " + str(_f) + " -f- 2>/dev/null").execute() except CalledProcessError as e: logging.warn(str(e.cmd) + "\n" + str(e.output)) continue cc_included_files += [ s for s in cc_makedep.split() if (s.startswith("/usr") or s.startswith("/include")) and str(project_dir) not in s] spec.required_files.update(cc_included_files) spec.build_required_files.update(cc_included_files)
def copy_dir(self, path, ex_dir): """ Copies directory tree and adds command to prep macro """ prep = Command("cp -rf " + path + " " + ex_dir) prep.execute() self.prep.append(str(prep))
def load_project_from_url(self, path): """executed in background after dir/tarball/SRPM selection""" if not isdir(str(path)) and not isfile(str(path)): temp = Path(gettempdir()) / "rpg-download" self._plugin_engine.execute_download(path, temp) path = temp self.source_path = path = Path(path) self._hash = self._compute_checksum(path) self._setup_workspace() if isdir(str(path)): Command("cp -pr " + str(path) + " " + str(self.extracted_dir))\ .execute() else: self._plugin_engine.execute_extraction(path, self.extracted_dir) direc = [str(f) for f in self.extracted_dir.iterdir()] if len(direc) == 1 and isdir(direc[0]): direc = direc[0] temp = mkdtemp() Command('mv ' + direc + '/* ' + temp + ' && rm -rf ' + direc + ' && mv ' + temp + '/* ' + str(self.extracted_dir))\ .execute() rmtree(temp) logging.debug(str(direc)) self.spec.prep = Command("%autosetup")
def patched(self, project_dir, spec, sack): if (project_dir / "setup.py").is_file(): spec.BuildRequires.add("python3-setuptools") logging.debug('setup.py found') spec.build = Command("python3 setup.py build") spec.install = Command( "python3 setup.py install " "--skip-build --root $RPM_BUILD_ROOT")
def create_archive(self): """ Creates archive (archvie_path) from Source folder """ self.spec.Source = self.spec.Name + "-" + self.spec.Version + ".tar.gz" _tar = Command("tar zcf " + str(self.archive_path) + " -C " + str(self.extracted_dir) + " . --transform='s/^\./" + self.spec.Name + "-" + self.spec.Version + "/g'") _tar.execute() logging.debug(str(_tar))
def patched(self, project_dir, spec, sack): if (project_dir / "CMakeLists.txt").is_file(): logging.debug('CMakeLists.txt found') build = Command() build.append_cmdlines("cmake " + str(project_dir)) build.append_cmdlines("make") install = Command("make install DESTDIR=$RPM_BUILD_ROOT") spec.scripts["%build"] = build spec.scripts["%install"] = install
def build_srpm(spec_file, tarball, output_dir): """ Builds source rpm from spec and tarball and moves it to the output directory """ Command("rpmdev-setuptree").execute() Command("cp " + path_to_str(tarball) + ' $(rpm --eval "%{_topdir}")/SOURCES').execute() output = Command("rpmbuild -bs " + path_to_str(spec_file)).execute() Command("mv " + path_to_str(output.split()[-1]) + " " + path_to_str(output_dir)).execute()
def create_archive(self): """ Creates archive (archvie_path) from Source folder """ self.spec.Source = self.spec.Name + "-" + self.spec.Version + ".tar.gz" _tar = Command("tar zcf " + path_to_str(self.archive_path) + " -C " + path_to_str(self.extracted_dir) + " . --transform='s/^\./" + self.spec.Name + "-" + self.spec.Version + "/g'") _tar.execute() logging.debug(str(_tar))
def move_files(output, files): if not output.exists() and not output.is_dir(): Command("mkdir " + path_to_str(output)).execute() for _out in files: try: Command("mv " + path_to_str(_out) + " " + path_to_str(output)).execute() except: pass
def build_srpm(spec_file, tarball, output_dir): """builds RPM package with build_srpm and build_rpm""" # Build srpm pakcage from given spec_file and tarball Command("rpmdev-setuptree").execute() Command("cp " + path_to_str(tarball) + ' $(rpm --eval "%{_topdir}")/SOURCES').execute() output = Command("rpmbuild -bs " + path_to_str(spec_file)).execute() Command("mv " + path_to_str(output.split()[-1]) + " " + path_to_str(output_dir)).execute()
def patched(self, project_dir, spec, sack): if (project_dir / "CMakeLists.txt").is_file(): spec.BuildRequires.add("cmake") logging.debug('CMakeLists.txt found') build = Command() build.append("cmake .") build.append("make") install = Command("make install DESTDIR=$RPM_BUILD_ROOT") spec.build = build spec.install = install
def patched(self, project_dir, spec, sack): """ Appends commands to build project with Autotools build system and appends dependencies """ if (project_dir / "configure").is_file(): logging.debug('configure found') spec.build.append(["%{configure}", "%{make_build}"]) spec.install.append(['make install DESTDIR="$RPM_BUILD_ROOT"']) elif ((project_dir / "configure.ac").is_file() and (project_dir / "Makefile.am").is_file()): logging.debug('configure.ac and Makefile.am found') spec.BuildRequires.update(["autoconf", "automake", "libtool"]) build = Command() if (project_dir / "autogen.sh").is_file(): logging.debug('autogen.sh found') build.append("./autogen.sh") else: build.append("autoreconf --install --force") build.append("%{configure}") build.append("%{make_build}") spec.build = build spec.install = Command("make install DESTDIR=\"$RPM_BUILD_ROOT\"") elif (project_dir / "configure.ac").is_file(): logging.warning('configure.ac found, Makefile.am missing') elif (project_dir / "Makefile.am").is_file(): logging.warning('Makefile.am found, configure.ac missing')
def patched(self, project_dir, spec, sack): if (project_dir / "Makefile").is_file() or\ (project_dir / "makefile").is_file(): spec.BuildRequires.add("make") logging.debug('Makefile found') cmd_build = Command("make") cmd_install = Command("make install DESTDIR=$RPM_BUILD_ROOT") spec.build = cmd_build spec.install = cmd_install
def patched(self, project_dir, spec, sack): """ Appends commands to build Project with CMake build system """ if (project_dir / "CMakeLists.txt").is_file(): spec.BuildRequires.add("cmake") logging.debug("CMakeLists.txt found") build = Command() build.append("cmake .") build.append("%{make_build}") install = Command('make install DESTDIR="$RPM_BUILD_ROOT"') _parse(project_dir, spec) spec.build = build spec.install = install
def validatePage(self): self.base.spec.scripts['%prep'] = Command( self.prepareEdit.toPlainText()) self.base.spec.scripts['%build'] = Command( self.buildEdit.toPlainText()) self.base.spec.scripts['%install'] = Command( self.installEdit.toPlainText()) self.base.spec.scripts['%check'] = Command( self.checkEdit.toPlainText()) if self.buildArchCheckbox.isChecked(): self.base.spec.tags['BuildArch'] = "noarch" else: self.base.spec.tags.pop('BuildArch', None) return True
def test_command_execute_from(self): cmd = Command("pwd\ncd c\npwd") output = cmd.execute_from(self.test_project_dir) path = self.test_project_dir.resolve() expected = "%s\n%s/c\n" % (path, path) self.assertEqual(expected, output) # doesn't add 'cd work_dir' during execute to command lines cur_dir = Path('.') with self.assertRaises(subprocess.CalledProcessError) as ctx: cmd.execute_from(cur_dir) expected = "Command '['/bin/sh', '-c', 'cd %s && pwd && cd c && pwd" \ "']' returned non-zero exit status 1" % cur_dir.resolve() self.assertEqual(expected, str(ctx.exception))
def test_command_execute_from(self): cmd = Command("pwd\ncd c 2>/dev/null\npwd") output = cmd.execute(self.test_project_dir) path = path_to_str(self.test_project_dir.resolve()) expected = "%s\n%s/c\n" % (path, path) self.assertEqual(expected, output) # doesn't add 'cd work_dir' during execute to command lines cur_dir = Path('.') with self.assertRaises(subprocess.CalledProcessError) as ctx: cmd.execute(cur_dir) expected = "Command '['/bin/sh', '-c', 'cd %s "\ "&& pwd && cd c 2>/dev/null && pwd']' "\ "returned non-zero exit status 1"\ % path_to_str(cur_dir.resolve()) self.assertEqual(expected, str(ctx.exception))
def build_rpm_recover(self, distro, arch): """ Repeatedly build rpm with mock and finds all build errors. May raise RuntimeError on failed recover. """ def build(): self.build_srpm() self.build_rpm(distro, arch) def analyse(): _files_to_pkgs.installed(self.base_dir, self.spec, self.sack) self.write_spec() _files_to_pkgs = FilesToPkgsPlugin() analyse() while True: try: build() except BuildException as be: if not self._plugin_engine.execute_mock_recover(be.errors): if be.return_code: raise RuntimeError( "Build failed! See logs in '{}'".format( self._package_builder.mock_logs)) break Command("rm -rf {}".format(path_to_str(self.spec_path))).execute() analyse()
def extraction(self, source, dest): source = path_to_str(source) if is_tarfile(source): Command("tar xf {} -C {}".format(source, path_to_str(dest))).execute() return True else: return False
def _compute_checksum(sources): if sources.is_dir(): cmd = "find %s -type f -print0 | sort -z | xargs " \ "-0 sha1sum | sha1sum" % path_to_str(sources.resolve()) else: cmd = "cat %s | sha1sum" % path_to_str(sources.resolve()) logging.error(str(cmd)) return Command([cmd]).execute()[:7]
def patched(self, project_dir, spec, sack): if (project_dir / "pom.xml").is_file(): logging.debug('pom.xml found') spec.BuildRequires.add("maven-local") spec.build = Command('%mvn_build -f') install = Command() install.append('xmvn-install -R .xmvn-reactor -n ' + spec.Name + ' -d "$RPM_BUILD_ROOT"') install.append('jdir=target/site/apidocs; [ -d .xmvn/apidocs ] ' '&& jdir=.xmvn/apidocs; ' 'if [ -d "${jdir}" ]; then ' 'install -dm755 "$RPM_BUILD_ROOT"/usr/share/' 'javadoc/' + spec.Name + '; ' 'cp -pr "${jdir}"/* "$RPM_BUILD_ROOT"/usr/share/' 'javadoc/' + spec.Name + '; ' 'echo \'/usr/share/javadoc/' + spec.Name + '\' >>.mfiles-javadoc; fi') spec.install = install
def _process_dir(ext_dir): """ Pops dir from ext_dir when needed """ direc = [str(path) for path in Path(ext_dir).iterdir()] if len(direc) == 1 and isdir(direc[0]): direc = direc[0] temp = mkdtemp() Command('mv ' + direc + '/* ' + temp + ' && rm -rf ' + direc + ' && mv ' + temp + '/* ' + ext_dir).execute() rmtree(temp)
def patched(self, project_dir, spec, sack): if (project_dir / "CMakeLists.txt").is_file(): spec.BuildRequires.add("cmake") logging.debug('CMakeLists.txt found') build = Command() build.append("cmake .") build.append("%{make_build}") install = Command('make install DESTDIR="$RPM_BUILD_ROOT"') _parse(project_dir, spec) spec.build = build spec.install = install
def patched(self, project_dir, spec, sack): out = Command([ "find " + path_to_str(project_dir) + " -name " + " -o -name ".join( ["'*." + ex + "'" for ex in self.EXT_CPP] ) ]).execute() cc_makedep = "" cc_included_files = [] for _f in out.splitlines(): try: cc_makedep = Command("makedepend -w 1000 " + str(_f) + " -f- 2>/dev/null").execute() except CalledProcessError as e: logging.warn(str(e.cmd) + "\n" + str(e.output)) continue cc_included_files += [ s for s in cc_makedep.split() if (s.startswith("/usr") or s.startswith("/include")) and str(project_dir) not in s] spec.required_files.update(cc_included_files) spec.build_required_files.update(cc_included_files)
def test_command_concat(self): cmd = Command("cd %s" % path_to_str(self.test_project_dir)) cmd.append("cmake ..") cmd.append(["make", "make test"]) self.assertRaises(TypeError, cmd.append, 4) expected = "cd %s\ncmake ..\nmake\nmake test" %\ path_to_str(self.test_project_dir) self.assertEqual(expected, str(cmd))
def _extract(cls, arch, extraction_dir, compr): """ Extracts files from archive (can be combinated like tar and gz) """ extr_cmd = cls._compressions[compr[0]] _cmd = "" try: ext_cmd = extr_cmd[3][compr[1]] _cmd += ext_cmd[0] + " " + ext_cmd[1] + " " + arch + " | " arch = "-" except IndexError: pass Command(_cmd + extr_cmd[0] + " " + extr_cmd[1] + " " + arch + " " + extr_cmd[2] + " " + extraction_dir).execute()
def installed(self, project_dir, spec, sack): python_version = "" for py_file in list(project_dir.glob('**/*.py')): if rpm.expandMacro("%{python_sitearch}") in str(py_file) or\ rpm.expandMacro("%{python_sitelib}") in str(py_file): python_version = "python2" elif rpm.expandMacro("%{python3_sitearch}") in str(py_file) or\ rpm.expandMacro("%{python3_sitelib}") in str(py_file): python_version = "python3" Command([ python_version + ' ' + sw + ' -c \'import compileall; compileall.compile_file("' + str(py_file) + '")\'' for sw in ["-O", ""] ]).execute() spec.files.update([("/" + str(_f.relative_to(project_dir)), None, None) for _f in project_dir.glob('**/*.py*')])
def load_project_from_url(self, path): """executed in background after dir/tarball/SRPM selection""" temp_arch = "downloaded_archive.tar.gz" if search(r"github\.com/[^/]+/[^/]+/?$", str(path)): self._source_loader.download_git_repo(path, temp_arch) path = Path(temp_arch) elif str(path).startswith("http"): temp_arch = search(r"([^/]+\.[^/]+(?:\.[^/]+)?)$", str(path))\ .group(0) self._source_loader.download_archive(path, temp_arch) path = Path(temp_arch) else: temp_arch = None path = Path(path) self._hash = self._compute_checksum(path) self._input_name = path.name self._setup_workspace() self._source_loader.load_sources(path, self.extracted_dir) self.spec.prep = Command("%autosetup") if temp_arch: remove(temp_arch)
def patched(self, project_dir, spec, sack): """ Parses pom.xml file used by Maven build system for Java """ if (project_dir / "pom.xml").is_file(): logging.debug('pom.xml found') spec.BuildRequires.add("maven-local") spec.build = Command('%mvn_build -f') install = Command() install.append('xmvn-install -R .xmvn-reactor -n ' + spec.Name + ' -d "$RPM_BUILD_ROOT"') install.append('jdir=target/site/apidocs; [ -d .xmvn/apidocs ] ' '&& jdir=.xmvn/apidocs; ' 'if [ -d "${jdir}" ]; then ' 'install -dm755 "$RPM_BUILD_ROOT"/usr/share/' 'javadoc/' + spec.Name + '; ' 'cp -pr "${jdir}"/* "$RPM_BUILD_ROOT"/usr/share/' 'javadoc/' + spec.Name + '; ' 'echo \'/usr/share/javadoc/' + spec.Name + '\' >>.mfiles-javadoc; fi') spec.install = install
def test_rpg_project(self): self.base = Base() self.base.sack = self.base.load_dnf_sack() self.base.load_plugins() self.base.load_project_from_url("https://github.com/openSUSE/libsolv") self.base.spec.Name = "LibSolv" self.base.spec.Version = "0.6.11" self.base.spec.Release = "1%{?snapshot}%{?dist}" self.base.spec.License = "GPLv2" self.base.spec.Summary = "Library for solving repository info" self.base.spec.description = ( "This is libsolv, a free package dependency solver " "using a satisfiability algorithm.") self.base.spec.URL = "https://github.com/openSUSE/libsolv" self.base.target_arch = "x86_64" self.base.target_distro = "fedora-22" self.base.fetch_repos(self.base.target_distro, self.base.target_arch) self.base.run_extracted_source_analysis() self.base.run_patched_source_analysis() self.base.spec.build = Command([ r'cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo ' r'-DENABLE_PERL=1 ' r'-DENABLE_PYTHON=1 ' r'-DENABLE_RUBY=1 ' r'-DUSE_VENDORDIRS=1 ' r'-DFEDORA=1 ' r'-DENABLE_LZMA_COMPRESSION=1' "make" ]) self.base.build_project() self.base.run_compiled_source_analysis() self.base.install_project() self.base.run_installed_source_analysis() self.base.build_srpm() self.assertTrue(self.base.srpm_path.exists()) self.base.build_rpm_recover(self.base.target_distro, self.base.target_arch) self.assertTrue(self.base.rpm_path)
def test_rpg_project(self): self.base = Base() self.base.sack = self.base.load_dnf_sack() self.base.load_plugins() self.base.load_project_from_url( "https://github.com/rh-lab-q/rpg/archive/master.zip") self.base.spec.Name = "rpg" self.base.spec.Version = "0.0.2" self.base.spec.Release = "1%{?snapshot}%{?dist}" self.base.spec.License = "GPLv2" self.base.spec.Summary = "RPM Package Generator" self.base.spec.description = ( "RPG is tool, that guides people through" "the creation of a RPM package. RPG makes packaging much easier" "due to the automatic analysis of packaged files. Beginners can" "get familiar with packaging process or the advanced users can" "use our tool for a quick creation of a package.") self.base.spec.URL = "https://github.com/rh-lab-q/rpg" self.base.target_arch = "x86_64" self.base.target_distro = "fedora-22" self.base.spec.Requires.update(['makedepend', 'mock']) self.base.spec.BuildRequires.update(['makedepend', 'mock', 'python3-nose']) self.base.fetch_repos(self.base.target_distro, self.base.target_arch) self.base.run_extracted_source_analysis() self.base.run_patched_source_analysis() self.base.spec.check = Command(["make test-unit"]) self.base.build_project() self.base.run_compiled_source_analysis() self.base.install_project() self.base.run_installed_source_analysis() self.base.build_srpm() self.assertTrue(self.base.srpm_path.exists()) self.base.build_rpm_recover( self.base.target_distro, self.base.target_arch) self.assertTrue(self.base.rpm_path)
def patched(self, project_dir, spec, sack): out = Command([ "find " + path_to_str(project_dir) + " -name " + " -o -name ".join(["'*." + ex + "'" for ex in self.EXT_CPP]) ]).execute() cc_makedep = "" cc_included_files = [] for _f in out.splitlines(): try: cc_makedep = Command("makedepend -w 1000 " + str(_f) + " -f- 2>/dev/null").execute() except CalledProcessError as e: logging.warn(str(e.cmd) + "\n" + str(e.output)) continue cc_included_files += [ s for s in cc_makedep.split() if (s.startswith("/usr") or s.startswith("/include")) and str(project_dir) not in s ] spec.required_files.update(cc_included_files) spec.build_required_files.update(cc_included_files)
def patched(self, project_dir, spec, sack): """ Finds dependencies via makedepend - This is not garanteed to be all of them. Makedepend uses macro preprocessor and if it throws and error makedepend didn't print deps. """ out = Command([ "find " + path_to_str(project_dir) + " -name " + " -o -name ".join(["'*." + ex + "'" for ex in self.EXT_CPP]) ]).execute() cc_makedep = "" cc_included_files = [] for _f in out.splitlines(): try: cc_makedep = Command("makedepend -w 1000 " + str(_f) + " -f- 2>/dev/null").execute() except CalledProcessError as e: logging.warn(str(e.cmd) + "\n" + str(e.output)) continue cc_included_files += [ s for s in cc_makedep.split() if (s.startswith("/usr") or s.startswith("/include")) and str(project_dir) not in s ] spec.required_files.update(cc_included_files) spec.build_required_files.update(cc_included_files)
def patched(self, project_dir, spec, sack): if (project_dir / "configure").is_file(): logging.debug('configure found') build = Command() build.append("./configure") build.append("make") spec.build = build spec.install = Command('make install DESTDIR="$RPM_BUILD_ROOT"') elif ((project_dir / "configure.ac").is_file() and (project_dir / "Makefile.am").is_file()): logging.debug('configure.ac and Makefile.am found') spec.BuildRequires.add("autoconf") spec.BuildRequires.add("automake") spec.BuildRequires.add("libtool") f = (project_dir / "configure.ac").open() regex = re.compile( r"PKG_CHECK_MODULES\s*\(.*?,\s*(.*?)\s*?[,\)]", re.DOTALL) deps = _extract_dependencies(regex, f) for dep in deps: spec.BuildRequires.add(dep) build = Command() if (project_dir / "autogen.sh").is_file(): logging.debug('autogen.sh found') build.append("./autogen.sh") else: build.append("autoreconf --install --force") build.append("./configure") build.append("make") spec.build = build spec.install = Command("make install DESTDIR=\"$RPM_BUILD_ROOT\"") elif (project_dir / "configure.ac").is_file(): logging.warning('configure.ac found, Makefile.am missing') elif (project_dir / "Makefile.am").is_file(): logging.warning('Makefile.am found, configure.ac missing')
def test_new_line(self): cmd = Command("a\nb\n") self.assertEqual("a\nb", str(cmd))
def test_compare(self): cmd1 = Command("test") cmd2 = Command("test") self.assertEqual(cmd1, cmd2)
def test_execute(self): cmd = Command("echo bla") output = cmd.execute() self.assertEqual("bla\n", output)
def __init__(self): self.prep = Command()
def extract(self, arch, extract, compr): """ Extracts files from archive """ prep = Command() if compr[0] == "tar": tar_compr = "" if compr[1] == "xz": tar_compr = "J" elif compr[1] == "gz": tar_compr = "z" elif compr[1] == "bz2": tar_compr = "j" elif compr[1] == "lz": tar_compr = "--lzip " elif compr[1] == "xz": tar_compr = "z" elif compr[1] == "lzma": tar_compr = "--lzma " else: raise SystemExit("Internal error: Unknown compression \ method: " + compr) prep.append("tar " + tar_compr + "xf " + arch + " -C " + extract) elif compr[0] == "tgz": prep.append("tar xzf " + arch + " -C " + extract) elif compr[0] == "tbz2": prep.append("tar xjf " + arch + " -C " + extract) elif compr[0] == "zip": prep.append("unzip " + arch + " -d " + extract) elif compr[0] == "rar": prep.append("unrar x " + arch + " " + extract) elif compr[0] == "7z": prep.append("7z x " + arch + " -o " + extract) else: raise SystemExit("Internal error: Unknown compression \ method: " + compr[0] + "." + compr[1]) prep.execute() self.prep.append(str(prep))
def __init__(self): # tags self.Name = "" self.Version = "" self.Release = "" self.Summary = "" self.Group = "" self.License = "" self.URL = "" self.Source = "" self.Patch = "" self.BuildArch = "" self.BuildRoot = "" self.Obsoletes = "" self.Conflicts = "" self.Vendor = "" self.Packager = "" self.package = "" self.description = "" self.BuildRequires = set() self.Requires = set() self.Provides = set() self.files = set() self.changelog = [] self.prep = Command() self.build = Command() self.pre = Command() self.install = Command() self.check = Command() self.post = Command() self.preun = Command() self.postun = Command() self.pretrans = Command() self.posttrans = Command() self.clean = Command() # list of generated translation files self.files_translations = [] # (Build)Required file list that will be traslated into packages self.build_required_files = set() self.required_files = set()
class SourceLoader(object): def __init__(self): self.prep = Command() def extract(self, arch, extract, compr): """ Extracts files from archive """ prep = Command() if compr[0] == "tar": tar_compr = "" if compr[1] == "xz": tar_compr = "J" elif compr[1] == "gz": tar_compr = "z" elif compr[1] == "bz2": tar_compr = "j" elif compr[1] == "lz": tar_compr = "--lzip " elif compr[1] == "xz": tar_compr = "z" elif compr[1] == "lzma": tar_compr = "--lzma " else: raise SystemExit("Internal error: Unknown compression \ method: " + compr) prep.append("tar " + tar_compr + "xf " + arch + " -C " + extract) elif compr[0] == "tgz": prep.append("tar xzf " + arch + " -C " + extract) elif compr[0] == "tbz2": prep.append("tar xjf " + arch + " -C " + extract) elif compr[0] == "zip": prep.append("unzip " + arch + " -d " + extract) elif compr[0] == "rar": prep.append("unrar x " + arch + " " + extract) elif compr[0] == "7z": prep.append("7z x " + arch + " -o " + extract) else: raise SystemExit("Internal error: Unknown compression \ method: " + compr[0] + "." + compr[1]) prep.execute() self.prep.append(str(prep)) def copy_dir(self, path, ex_dir): """ Copies directory tree and adds command to prep macro """ prep = Command("cp -rf " + path + " " + ex_dir) prep.execute() self.prep.append(str(prep)) def process(self, ext_dir): i = 0 direc = "" for path in Path(ext_dir).iterdir(): i += 1 direc = str(path) if i < 2: if isdir(direc): Command('mv ' + direc + '/* ' + ext_dir + 'rmdir ' + direc) def load_sources(self, source_path, extraction_dir): """Extracts archive to extraction_dir and adds a flag for %prep section to create root directory if necessary. If argument is a directory, copy the directory to desired location. May raise IOError """ logging.debug('load_sources({}, {}) called' .format(str(source_path), str(extraction_dir))) path = str(source_path) extraction_dir = str(extraction_dir) if isfile(path): compression = self.get_compression_method(path) if not compression: raise IOError("Input source archive '{}' is incompatible!" .format(path)) self.extract(path, extraction_dir, compression) elif isdir(path): self.copy_dir(path, extraction_dir) else: raise IOError("Input source archive/directory '{}' doesn't exists!" .format(path)) self.process(extraction_dir) return self.prep @staticmethod def create_archive(path, output_dir): """ Creates archive from folder """ name = str(path) + ".tar.gz" if isdir(str(output_dir)) or \ isfile(str(output_dir)): Command("tar czf " + name + " " + str(output_dir)).execute() return name else: raise IOError("File/directory was not found!") @staticmethod def get_compression_method(name): """ determine the compression method used for a tar file. """ arch_t = re.match(r".+?\.([^.]+)(?:\.([^.]+)|)$", name) if not arch_t.group(1) in ["", "tar", "zip", "rar", "7z", "tgz", "tbz2"] \ and not arch_t.group(2) in ["gz", "xz", "lz", "bz2", "Z", "lzma"]: return None return (arch_t.group(1), arch_t.group(2))
def patched(self, project_dir, spec, sack): if (project_dir / "configure").is_file(): logging.debug("configure found") build = Command() build.append("./configure") build.append("make") spec.build = build spec.install = Command('make install DESTDIR="$RPM_BUILD_ROOT"') elif (project_dir / "configure.ac").is_file() and (project_dir / "Makefile.am").is_file(): logging.debug("configure.ac and Makefile.am found") spec.BuildRequires.add("autoconf") spec.BuildRequires.add("automake") spec.BuildRequires.add("libtool") f = (project_dir / "configure.ac").open() regex = re.compile(r"PKG_CHECK_MODULES\s*\(.*?,\s*(.*?)\s*?[,\)]", re.DOTALL) deps = _extract_dependencies(regex, f) for dep in deps: spec.BuildRequires.add(dep) build = Command() if (project_dir / "autogen.sh").is_file(): logging.debug("autogen.sh found") build.append("./autogen.sh") else: build.append("autoreconf --install --force") build.append("./configure") build.append("make") spec.build = build spec.install = Command('make install DESTDIR="$RPM_BUILD_ROOT"') elif (project_dir / "configure.ac").is_file(): logging.warning("configure.ac found, Makefile.am missing") elif (project_dir / "Makefile.am").is_file(): logging.warning("Makefile.am found, configure.ac missing")