def test_replace_macro_with_spec(self): spec = Spec.from_file(os.path.join(CURRENT_DIR, "llvm.spec")) assert ( replace_macros(spec.sources[0], spec) == "http://llvm.org/releases/3.8.0/llvm-3.8.0.src.tar.xz" ) assert replace_macros(spec.sources[1], spec) == "llvm-config.h"
def test_replace_macro_twice(self) -> None: spec = Spec.from_file(os.path.join(CURRENT_DIR, "jsrdbg.spec")) # pylint: disable=line-too-long assert ( replace_macros(spec.sources[0], spec) == "https://github.com/swojtasiak/jsrdbg/archive/26f9f2b27c04b4aec9cd67baaf9a0a206bbbd5c7.tar.gz#/jsrdbg-26f9f2b27c04b4aec9cd67baaf9a0a206bbbd5c7.tar.gz" )
def download_source_url(gt_api, pkg, spec, o_ver, n_ver): """ Download source file from Source or Source0 URL """ spec_path = get_spec_path(gt_api, pkg) source_str = subprocess.check_output(["spectool -S {}".format(spec_path)], shell=True).decode("utf-8") if source_str: source = source_str.split('\n')[0].split(' ')[1] else: if spec.sources_dict: source = replace_macros(spec.sources[0], spec) else: print("WARNING: No source url in specfile.") return None source = source.replace(o_ver, n_ver) if re.match(r"%{.*?}", source): print( "WARNING: Extra macros in source url which failed to be expanded.") return None if source.startswith("http") or source.startswith("ftp"): return download_helper(source) print("WARNING: Source url is invalid in specfile.") return None
def create_bitbake_include(spec, specfn): bbincludefn = specfn.replace('.spec', '-centos.inc') bbincludefile = open(bbincludefn, 'w') if bbincludefile: tmp = 'FILESEXTRAPATHS_prepend := \"${THISDIR}/centos:\"\n' bbincludefile.writelines(tmp) for source in spec.sources: tmp = replace_macros(source, spec) if '%' not in tmp: tmp = tmp.split('#') tmp = 'CENTOS_SRC = \"' + tmp[0] + '\" \n\n' bbincludefile.writelines(tmp) break bbincludefile.writelines('CENTOS_PATCHES = \" \\\n') for patch in spec.patches: tmp = '\t file://' + patch + ' \\\n' bbincludefile.writelines(tmp) bbincludefile.writelines('\t\"\n') bbincludefile.close()
def test_replace_unknown_macro(self) -> None: """Ensure that string that do not have a definition in the spec file are left intact.""" spec = Spec.from_file( os.path.join(CURRENT_DIR, "perl-Array-Compare.spec")) s = "%{foobar}" assert s == replace_macros(s, spec=spec)
def test_replace_macro_with_negative_conditional(self) -> None: spec = Spec.from_file(os.path.join(CURRENT_DIR, "git.spec")) assert (replace_macros( "https://www.kernel.org/pub/software/scm/git/%{?rcrev:testing/}%{name}-%{version}%{?rcrev}.tar.xz", spec, ) == "https://www.kernel.org/pub/software/scm/git/git-2.15.1.tar.xz")
def test_replace_macro_that_is_tag_name(self) -> None: """Test that we are able to replace macros which are in the tag list. See issue https://github.com/bkircher/python-rpm-spec/issues/33. """ spec = Spec.from_string(r""" %global myversion 1.2.3 Version: %{myversion} """) assert replace_macros(spec.version, spec) == "1.2.3" spec = Spec.from_string(r""" %global version 1.2.3 Version: %{version} """) assert replace_macros(spec.version, spec) == "1.2.3"
def getSpecMeta(fname): spec = Spec.from_file(fname) meta = {} meta['Name'] = replace_macros(spec.name, spec) meta['Version'] = replace_macros(spec.version, spec) meta['Release'] = replace_macros(spec.release, spec) keys = ['Distribution'] for k in keys: meta[k] = None with open(fname, 'r') as sfile: for line in sfile.readlines(): line = line.split(':') k = line[0].strip() if k in keys: meta[k] = line[1].strip() return meta
def test_replace_user_defined_macro(self) -> None: spec = Spec.from_string(""" Name: foo Version: 2 %define var bar """) s = "%{name}/%{version}/%{var}" assert replace_macros(s, spec) == "foo/2/bar"
def test_replace_user_defined_macro(self): spec = Spec.from_string(""" Name: foo Version: 2 %define var bar """) s = '%{name}/%{version}/%{var}' assert 'foo/2/bar' == replace_macros(s, spec)
def test_replace_macro_with_leading_exclamation_point(self): spec = Spec.from_string(""" Name: git Version: 2.15.1 """) assert 'https://www.kernel.org/pub/software/scm/git/testing/git-2.15.1.tar.xz' \ == replace_macros( 'https://www.kernel.org/pub/software/scm/git/%{!stable:testing/}%{name}-%{version}.tar.xz', spec)
def test_replace_macro_with_positive_conditional(self): spec = Spec.from_string(""" Name: git Version: 2.15.1 %define rcrev .rc0 """) assert 'https://www.kernel.org/pub/software/scm/git/testing/git-2.15.1.rc0.tar.xz' \ == replace_macros( 'https://www.kernel.org/pub/software/scm/git/%{?rcrev:testing/}%{name}-%{version}%{?rcrev}.tar.xz', spec)
def __manual_operate(gt_api, op_args): """ Manual operation of this module """ spec_string = gt_api.get_spec(op_args.repo_pkg, op_args.branch) if not spec_string: print( "WARNING: Spec of {pkg} can't be found on the {br} branch.".format( pkg=op_args.repo_pkg, br=op_args.branch)) sys.exit(1) spec_file = Spec.from_string(spec_string) cur_version = replace_macros(spec_file.version, spec_file) branch_info = gt_api.get_branch_info(op_args.branch) if not branch_info: sys.exit(1) if op_args.fork_then_clone: fork_clone_repo(gt_api, op_args.repo_pkg, op_args.branch) if op_args.download or op_args.create_spec or op_args.push_create_pr_issue: if not op_args.new_version: print("Please specify the upgraded version of the {}".format( op_args.repo_pkg)) sys.exit(1) if not update_ver_check(op_args.repo_pkg, cur_version, op_args.new_version): sys.exit(1) if op_args.download: if not download_src(gt_api, op_args.repo_pkg, spec_file, cur_version, op_args.new_version): sys.exit(1) if op_args.create_spec: create_spec(gt_api, op_args.repo_pkg, cur_version, op_args.new_version) if op_args.build_pkg and not build_pkg(op_args.repo_pkg, op_args.branch, branch_info["obs_prj"]): sys.exit(1) if op_args.check_rpm_abi: check_result = check_rpm_abi(op_args.repo_pkg) if op_args.push_create_pr_issue: values = make_values(op_args.repo_pkg, cur_version, op_args.new_version, op_args.branch, check_result) push_create_pr_issue(gt_api, values)
def auto_update_pkg(gt_api, u_pkg, u_branch, u_ver=None): """ Auto upgrade based on given branch for single package """ print( "\n------------------------Updating {}------------------------".format( u_pkg)) spec_str = gt_api.get_spec(u_pkg, u_branch) if not spec_str: print( "WARNING: Spec of {pkg} can't be found on the {br} branch.".format( pkg=u_pkg, br=u_branch)) return pkg_spec = Spec.from_string(spec_str) pkg_ver = replace_macros(pkg_spec.version, pkg_spec) branch_info = gt_api.get_branch_info(u_branch) if not branch_info: sys.exit(1) if not u_ver: pkg_tags = oa_upgradable.get_ver_tags(gt_api, u_pkg) if not pkg_tags: print("WARNING: Can't get {} version list, stop upgrade.".format( u_pkg)) return ver_rec = version_recommend.VersionRecommend(pkg_tags, pkg_ver, 0) if not ver_rec: print("WARNING: Can't get {} recommend version, stop upgrade.". format(u_pkg)) return pkg_type = package_type.PackageType(u_pkg) if pkg_type.pkg_type == "core": print("WARNING: {} is core package, if need upgrade, please specify "\ "upgarde version for it.".format(u_pkg)) return if pkg_type.pkg_type == "app": u_ver = ver_rec.latest_version else: if branch_info["recommend_type"] == "master": u_ver = ver_rec.latest_version else: u_ver = ver_rec.maintain_version print("version_recommen u_ver is :{}".format(u_ver)) if update_ver_check(u_pkg, pkg_ver, u_ver): fork_clone_repo(gt_api, u_pkg, u_branch) if not download_src(gt_api, u_pkg, pkg_spec, pkg_ver, u_ver): return create_spec(gt_api, u_pkg, pkg_ver, u_ver) if not build_pkg(u_pkg, u_branch, branch_info["obs_prj"]): return check_rest = check_rpm_abi(u_pkg) values = make_values(u_pkg, pkg_ver, u_ver, u_branch, check_rest) push_create_pr_issue(gt_api, values)
def create_spec(gt_api, repo, o_ver, n_ver): """ Create new spec file for upgraded package """ spec_path = get_spec_path(gt_api, repo) with open(spec_path, "r") as spec_file: spec_str = spec_file.read() pkg_spec = Spec.from_string(spec_str) if len(pkg_spec.patches) >= 1: patch_match = match_patches.patches_match(gt_api, repo, o_ver, n_ver) os.rename(spec_path, "{}.old".format(spec_path)) file_spec = open(spec_path, "w") in_changelog = False patch_num_list = [] patch_dict = {} for line in spec_str.splitlines(): if line.startswith("Release:"): file_spec.write(re.sub(r"\d+", "1", line) + "\n") continue if line.startswith("Source:") or line.startswith("Source0:"): file_spec.write(line.replace(o_ver, n_ver) + "\n") continue if line.startswith("Patch") and patch_match: patch_dict["line"] = replace_macros(line, pkg_spec) patch_dict["pre_name"] = patch_dict["line"].split(":", 1)[1].strip() if patch_dict["pre_name"] in patch_match: patch_dict["pre_tag"] = patch_dict["line"].split(":", 1)[0].strip() patch_dict["pre_num"] = re.findall(r"\d+\.?\d*", patch_dict["pre_tag"]) patch_num_list.append(patch_dict["pre_num"]) continue if line.startswith("%patch") and patch_match: if patch_num_list: patch_dict["ply_tag"] = line.split(" ", 1)[0].strip() patch_dict["ply_num"] = re.findall(r"\d+\.?\d*", patch_dict["ply_tag"]) if patch_dict["ply_num"] in patch_num_list: continue if not in_changelog: line = line.replace(o_ver, n_ver) file_spec.write(line + "\n") if line.startswith("%changelog"): in_changelog = True cur_date = datetime.date.today() file_spec.write(cur_date.strftime("* %a %b %d %Y SimpleUpdate Robot <*****@*****.**>"\ " - {ver}-1\n").format(ver=n_ver)) file_spec.write("- Upgrade to version {ver}\n".format(ver=n_ver)) file_spec.write("\n") file_spec.close() os.chdir(os.pardir)
def test_replace_macro_with_negative_conditional(self): spec = Spec.from_file(os.path.join(CURRENT_DIR, 'git.spec')) assert 'https://www.kernel.org/pub/software/scm/git/git-2.15.1.tar.xz' \ == replace_macros( 'https://www.kernel.org/pub/software/scm/git/%{?rcrev:testing/}%{name}-%{version}%{?rcrev}.tar.xz', spec)
def check_pkg(pkg, branch, check_file, lock): """ Check source url of single package """ try: user_gitee = gitee.Gitee() except NameError: sys.exit(1) check_file.writelines( "\n-----------------------Checking {}-----------------------".format( pkg)) lock.acquire() spec_str = user_gitee.get_spec(pkg, branch) lock.acquire() if not spec_str: check_file.writelines( "WARNING: Spec of {repo} can't be found on {br}".format(repo=pkg, br=branch)) return False repo_spec = Spec.from_string(spec_str) if repo_spec.sources_dict: source = replace_macros(repo_spec.sources[0], repo_spec) else: title = "Source url can't be found in spec on {br}".format(br=branch) check_file.writelines("WARNING: {content}".format(content=title)) create_issue(user_gitee, pkg, title, BODY_SOURCE) return False if re.search(r"%{.*?}", source): title = "Source url can't be parsed with extra macros in spec on {}.".format( branch) check_file.writelines("WARNING: {content}".format(content=title)) create_issue(user_gitee, pkg, title, BODY_SOURCE) return False if source.startswith("http") or source.startswith("ftp"): file_name = os.path.basename(source) down_cnt = 0 lock.acquire() while down_cnt < 2: down_cnt += 1 if not subprocess.call([ "timeout 15m wget -c {url} -O {name}".format( url=source, name=file_name) ], shell=True): break lock.release() title = "Source url may be wrong in spec on {br}.".format(br=branch) if os.path.exists(file_name): if subprocess.call(["tar -tvf {} &>/dev/null".format(file_name)], shell=True): check_file.writelines( "WARNING: {content}".format(content=title)) create_issue(user_gitee, pkg, title, BODY_SOURCE) result = False else: check_file.writelines("Check successfully.") result = True subprocess.call(["rm -rf {}".format(file_name)], shell=True) else: check_file.writelines("WARNING: {content}".format(content=title)) create_issue(user_gitee, pkg, title, BODY_SOURCE) result = False return result title = "Source url is invalid in spec on {br}.".format(br=branch) check_file.writelines("WARNING: {content}".format(content=title)) create_issue(user_gitee, pkg, title, BODY_SOURCE) return False
def test_replace_macro_int_type_val(self): spec = Spec.from_file(os.path.join(CURRENT_DIR, 'perl-Array-Compare.spec')) result = replace_macros('%{epoch}', spec) assert isinstance(result, str)
def main_process(push, default, repo): """ Main process of the functionality """ print("Checking", repo) try: user_gitee = gitee.Gitee() except NameError: sys.exit(1) spec_string = user_gitee.get_spec(repo) if not spec_string: print("WARNING: Spec of {pkg} can't be found on master".format(pkg=repo)) return None spec_file = Spec.from_string(spec_string) cur_version = replace_macros(spec_file.version, spec_file) if cur_version.startswith('v') or cur_version.startswith('V'): cur_version = cur_version[1:] print("Current version is", cur_version) pkg_tags = get_ver_tags(user_gitee, repo, cwd_path=default) print("known release tags:", pkg_tags) if not pkg_tags: return None if cur_version not in pkg_tags: print("WARNING: Current {ver} doesn't exist in upstream." \ "Please double check.".format(ver=cur_version)) ver_rec = version_recommend.VersionRecommend(pkg_tags, cur_version, 0) print("Latest version is", ver_rec.latest_version) print("Maintain version is", ver_rec.maintain_version) need_push_issue = True if cur_version != ver_rec.latest_version: if push: issues = user_gitee.get_issues(repo) for issue in issues: if "Upgrade to latest release" in issue["title"]: need_push_issue = False ages = datetime.now() - user_gitee.get_gitee_datetime(issue["created_at"]) if ages.days <= 30: print("Advise has been issues only %d days ago" % ages.days) print("Give developers more time to handle it.") break user_gitee.post_issue_comment(repo, issue["number"], NEW_COMMENT.format( repo=repo, days=ages.days)) break if need_push_issue: tile = """Upgrade to latest release [{repo}: {cur_ver} -> {ver}]""".format(repo=repo, ver=ver_rec.latest_version, cur_ver=cur_version) body = """Dear {repo} maintainer: We found the latest version of {repo} is {ver}, while the current version in openEuler mainline is {cur_ver}. Please consider upgrading. Yours openEuler Advisor. If you think this is not proper issue, Please visit https://gitee.com/openeuler/openEuler-Advisor. Issues and feedbacks are welcome.""".format(repo=repo, ver=ver_rec.latest_version, cur_ver=cur_version) user_gitee.post_issue(repo, tile, body) return [repo, cur_version, ver_rec.latest_version]
def test_replace_macro_without_spec_raises(self) -> None: """Ensure that caller passes a spec file.""" with pytest.raises(AssertionError): replace_macros("something something", spec=None)
def test_replace_unknown_macro(self): s = '%{foobar}' assert s == replace_macros(s, spec=None)
def test_replace_macro_twice(self): spec = Spec.from_file(os.path.join(CURRENT_DIR, 'jsrdbg.spec')) assert 'https://github.com/swojtasiak/jsrdbg/archive/26f9f2b27c04b4aec9cd67baaf9a0a206bbbd5c7.tar.gz#/jsrdbg-26f9f2b27c04b4aec9cd67baaf9a0a206bbbd5c7.tar.gz' \ == replace_macros(spec.sources[0], spec)
def test_replace_without_spec(self): s = 'http://llvm.org/releases/%{version}/%{name}-%{version}.src.tar.xz' assert s == replace_macros(s, spec=None)
from pyrpm.spec import Spec, replace_macros spec = Spec.from_file('llvm.spec') print(spec.version) # 3.8.0 print(spec.sources[0] ) # http://llvm.org/releases/%{version}/%{name}-%{version}.src.tar.xz print(replace_macros( spec.sources[0], spec)) # http://llvm.org/releases/3.8.0/llvm-3.8.0.src.tar.xz for package in spec.packages: print( f'{package.name}: {package.summary if hasattr(package, "summary") else spec.summary}' ) # llvm: The Low Level Virtual Machine # llvm-devel: Libraries and header files for LLVM # llvm-doc: Documentation for LLVM # llvm-libs: LLVM shared libraries # llvm-static: LLVM static libraries