first commit

This commit is contained in:
Butui Hu 2021-05-30 21:45:37 +08:00
commit 70ce0e93f9
4 changed files with 687 additions and 0 deletions

View file

@ -0,0 +1,614 @@
import configparser
import os
import os.path as osp
import tarfile
import requests
import yaml
class PKGBUILDGenerator(object):
def __init__(
self,
cran_mirror="https://cran.r-project.org",
bioconductor_mirror="https://bioconductor.org",
cran_packages_file=None,
bioconductor_packages_file1=None,
bioconductor_packages_file2=None
):
"""PKGBUILDGenerator class
param: cran_mirror, CRAN mirror
param: bioconductor_mirror, Bioconductor mirror
param: cran_packages_file, pre-downloaded PACKAGES file from https://cran.r-project.org/src/contrib/PACKAGES
param: bioconductor_packages_file1, pre-downloaded PACKAGES file from https://bioconductor.org/packages/release/bioc/src/contrib/PACKAGES
param: bioconductor_packages_file1, pre-downloaded PACKAGES file from https://bioconductor.org/packages/release/data/annotation/src/contrib/PACKAGES
"""
self.cran_mirror = cran_mirror
self.bioconductor_mirror = bioconductor_mirror
self.repos = ["cran", "bioconductor", "github"]
# cache all pkg metadata in CRAN
if cran_packages_file:
with open(cran_packages_file, 'r') as f:
self.cran_descs = f.read().split('\n\n')
else:
r_cran = requests.get(
f"{cran_mirror}/src/contrib/PACKAGES")
if r_cran.status_code == requests.codes.ok:
self.cran_descs = r_cran.text.split('\n\n')
else:
raise RuntimeError(
f"Failed to get CRAN descriptions due to: {r_cran.status_code}: {r_cran.reason}")
# cache all pkg metadata in Bioconductor
if bioconductor_packages_file1 and bioconductor_packages_file2:
with open(bioconductor_packages_file1, 'r') as f1, open(bioconductor_packages_file2, 'r') as f2:
self.bioconductor_descs = [
f1.read().split('\n\n'),
f2.read().split('\n\n')
]
else:
bioconductor_descs = []
for url in [f"{self.bioconductor_mirror}/packages/release/bioc/src/contrib/PACKAGES",
f"{self.bioconductor_mirror}/packages/release/data/annotation/src/contrib/PACKAGES"
]:
r = requests.get(url)
if r.status_code == requests.codes.ok:
bioconductor_descs.append(r.text.split('\n\n'))
else:
bioconductor_descs.append([])
x = set([len(_) for _ in bioconductor_descs])
if len(x) == 1 and list(x)[0] == 0:
raise RuntimeError(
f"Failed to get Bioconductor descriptions ")
self.bioconductor_descs = bioconductor_descs
self.exclude_pkgs = {
"base",
"boot",
"class",
"cluster",
"codetools",
"compiler",
"datasets",
"foreign",
"graphics",
"grDevices",
"grid",
"KernSmooth",
"lattice",
"MASS",
"Matrix",
"methods",
"mgcv",
"nlme",
"nnet",
"parallel",
"rpart",
"spatial",
"splines",
"stats",
"stats4",
"survival",
"tcltk",
"tools",
"utils",
"R"
}
self.arch_licenses = [
"AGPL",
"AGPL3",
"APACHE",
"Apache",
"Artistic2.0",
"Boost",
"CCPL",
"CDDL",
"CPL",
"EPL",
"FDL",
"FDL1.2",
"FDL1.3",
"GPL",
"GPL2",
"GPL3",
"LGPL",
"LGPL2.1",
"LGPL3",
"LPPL",
"MPL",
"MPL2",
"PHP",
"PSF",
"PerlArtistic",
"RUBY",
"Unlicense",
"W3C",
"ZPL"
]
def get_bioconductor_ver(self, bio_name, return_idx=False):
""" get pkg version from Bioconductor
args:
bio_name: pkg name in Bioconductor, case sensitive
return_idx: return idx of self.bio_descs
return: pkg version in Bioconductor
raise: RuntimeError if not found
"""
config = configparser.ConfigParser()
for idx, descs in enumerate(self.bioconductor_descs):
for _ in descs:
if _.startswith(f"Package: {bio_name}\n"):
config.read_string(f"[{bio_name}]\n" + _)
if return_idx:
return config[bio_name]["version"], idx
else:
return config[bio_name]["version"]
raise RuntimeError(f"{bio_name} not found in Bioconductor")
def get_cran_ver(self, cran_name):
""" get pkg version from CRAN
param: cran_name: pkg name in CRAN, case sensitive
return: pkg version in CRAN
raise: RuntimeError if not found
"""
config = configparser.ConfigParser()
for _ in self.cran_descs:
if _.startswith(f"Package: {cran_name}\n"):
config.read_string(f"[{cran_name}]\n" + _)
break
if cran_name not in config:
raise RuntimeError(f"{cran_name} not found in CRAN")
return config[cran_name]["version"]
def get_github_ver(self, github_owner, github_repo):
"""get rpkgname version from github
param: github_owner: github repo owner
param: github_repo: github repo name, this is also the rpkgname
return: version
raise: RuntimeError if not found
for example, https://github.com/ManuelHentschel/vscDebugger
github_owner=ManuelHentschel
github_repo=vscDebugger
"""
# currently, we only check for release, not git tags
release_url = f"https://api.github.com/repos/{github_owner}/{github_repo}/releases"
r = requests.get(release_url)
if r.status_code == requests.codes.ok:
if r.json():
return r.json()[0]["name"]
else:
raise RuntimeError(
f"could not find version in https://github.com/{github_owner}/{github_repo} due to {r.status_code}: {r.reason}")
def isInCran(self, cran_name):
"""
return True if `cran_name` is found in CRAN
"""
for _ in self.cran_descs:
if _.startswith(f"Package: {cran_name}\n"):
return True
return False
def parse_description(self, rpkgname, repo="cran", clean=True):
"""
parse DESCRIPTION file of `rpkgname`
args:
rpkgname: pkgname in R (CRAN, Bioconductor, Github), for github, rpkgname should be github_owner/github_repo
repo: repo that pkgname is in, CRAN, Bioconductor, github
clean: delete files if True
"""
if repo not in self.repos:
raise RuntimeError(f"Only these repos is supported: {self.repos}")
result = {
"repo": repo,
"rpkgname": rpkgname,
"rpkgver": None,
"title": None,
"arch": "any",
"r_depends": [],
"depends": ["r"],
"r_optdepends": [],
"optdepends": [],
"systemrequirements": None,
"license": None,
"license_filename": None,
"source": None,
"project_url": None
}
if repo == "bioconductor":
rpkgver, idx = self.get_bioconductor_ver(rpkgname, return_idx=True)
if idx == 0:
url = f"{self.bioconductor_mirror}/packages/release/bioc/src/contrib/{rpkgname}_{rpkgver}.tar.gz"
source = "https://bioconductor.org/packages/release/bioc/src/contrib/${_pkgname}_${_pkgver}.tar.gz"
elif idx == 1:
url = f"{self.bioconductor_mirror}/packages/release/data/annotation/src/contrib/{rpkgname}_{rpkgver}.tar.gz"
source = "https://bioconductor.org/packages/release/data/annotation/src/contrib/${_pkgname}_${_pkgver}.tar.gz"
result["project_url"] = 'https://bioconductor.org/packages/${_pkgname}'
elif repo == "cran":
rpkgver = self.get_cran_ver(rpkgname)
url = f"{self.cran_mirror}/src/contrib/{rpkgname}_{rpkgver}.tar.gz"
source = "https://cran.r-project.org/src/contrib/${_pkgname}_${_pkgver}.tar.gz"
result["project_url"] = 'https://cran.r-project.org/package=${_pkgname}'
elif repo == "github":
github_owner, github_repo = rpkgname.strip('/').split('/')
result["rpkgname"] = github_repo
result["github_owner"] = github_owner
result["github_repo"] = github_repo
result["project_url"] = f"https://github.com/{github_owner}/{github_repo}"
github_rpkgver = self.get_github_ver(github_owner, github_repo)
rpkgver = github_rpkgver.lstrip('v')
url = f"https://github.com/{github_owner}/{github_repo}/releases/download/{github_rpkgver}/{github_repo}_{rpkgver}.tar.gz"
if github_rpkgver.startswith('v'):
source = f"https://github.com/{github_owner}/{github_repo}/releases/download/v${{pkgver}}/${{_pkgname}}_${{_pkgver}}.tar.gz"
else:
source = f"https://github.com/{github_owner}/{github_repo}/releases/download/${{pkgver}}/${{_pkgname}}_${{_pkgver}}.tar.gz"
result["source"] = source
result["rpkgver"] = rpkgver
config = configparser.ConfigParser()
# meta db data in self.descs is not complete, still need to fetch desc for specific rpkgname
r = requests.get(url, allow_redirects=True)
if repo == "github":
tarfilename = f"{github_repo}_{rpkgver}.tar.gz"
desc_filename = f"{github_repo}/DESCRIPTION"
else:
tarfilename = f"{rpkgname}_{rpkgver}.tar.gz"
desc_filename = f"{rpkgname}/DESCRIPTION"
if r.status_code == requests.codes.ok:
with open(tarfilename, "wb") as f:
f.write(r.content)
else:
raise RuntimeError(
f"Failed to get source tarball {rpkgname}-{rpkgver}.tar.gz due to: {r.reason}")
with tarfile.open(tarfilename) as f:
f.extract(desc_filename)
with open(desc_filename, "r") as f:
config.read_string(f"[{rpkgname}]\n" + f.read())
if clean:
os.remove(tarfilename)
os.remove(desc_filename)
os.removedirs(osp.dirname(desc_filename))
if "title" in config[rpkgname]:
result["title"] = config[rpkgname]["title"].replace(
'\n', ' ').strip()
if "needscompilation" in config[rpkgname]:
if config[rpkgname]["needscompilation"] == "yes":
result["arch"] = "x86_64"
r_deps = []
if "imports" in config[rpkgname]:
r_deps += config[rpkgname]["imports"].split(',')
if "depends" in config[rpkgname]:
r_deps += config[rpkgname]["depends"].split(',')
if "linkingto" in config[rpkgname]:
r_deps += config[rpkgname]["linkingto"].split(',')
r_deps = [_.split('(')[0].strip() for _ in r_deps]
r_deps = list(set(r_deps) - self.exclude_pkgs)
if '' in r_deps:
r_deps.remove('')
result["r_depends"] = sorted(r_deps)
result["depends"] += [f"r-{_.lower()}" for _ in result["r_depends"]]
result["depends"] = sorted(result["depends"])
r_optdeps = []
if "suggests" in config[rpkgname]:
r_optdeps += config[rpkgname]["suggests"].strip().split(',')
if "enhances" in config[rpkgname]:
r_optdeps += config[rpkgname]["enhances"].strip().split(',')
r_optdeps = [_.split('(')[0].strip() for _ in r_optdeps]
if '' in r_optdeps:
r_optdeps.remove('')
result["r_optdepends"] = sorted(r_optdeps)
result["optdepends"] = sorted(
[f"r-{_.lower()}" for _ in result['r_optdepends']])
if "systemrequirements" in config[rpkgname]:
result["systemrequirements"] = config[rpkgname]["systemrequirements"].replace(
'\n', '').strip()
# deal with license
if "LGPL" in config[rpkgname]["license"] or config[rpkgname]["license"] == "GNU Lesser General Public License":
result["license"] = "LGPL"
elif "AGPL" in config[rpkgname]["license"] or config[rpkgname]["license"] == "GNU Affero General Public License":
result["license"] = "AGPL"
elif "GNU General Public License" in config[rpkgname]["license"] or "GPL" in config[rpkgname]["license"]:
result["license"] = "GPL"
elif "Apache" in config[rpkgname]["license"]:
result["license"] = "Apache"
elif "BSD" in config[rpkgname]["license"]:
result["license"] = "BSD"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "Artistic" in config[rpkgname]["license"]:
result["license"] = "Artistic2.0"
elif "CC BY" in config[rpkgname]["license"] or config[rpkgname]["license"] == "Creative Commons Attribution 4.0 International License":
result["license"] = "CCPL:by-nc-sa"
elif config[rpkgname]["license"] in ["Mozilla Public License 1.1",
"MPL",
"MPL-1.1"]:
result["license"] = "MPL"
elif config[rpkgname]["license"] in [
"Mozilla Public License 2.0",
"Mozilla Public License Version 2.0",
"MPL (>= 2)",
"MPL (== 2.0)",
"MPL (>= 2.0)",
"MPL-2.0",
"MPL-2.0 | file LICENSE",
"MPL (>= 2) | file LICENSE"
]:
result["license"] = "MPL2"
elif "CPL" in config[rpkgname]["license"] or config[rpkgname]["license"] == "Common Public License Version 1.0":
result["license"] = "CPL"
elif "MIT" in config[rpkgname]["license"]:
result["license"] = "MIT"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "EPL" in config[rpkgname]["license"]:
result["license"] = "EPL"
elif "CeCILL" in config[rpkgname]["license"]:
result["license"] = "CeCILL"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "EUPL" in config[rpkgname]["license"]:
result["license"] = "EUPL"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "ACM" in config[rpkgname]["license"]:
result["license"] = "ACM"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "BSL" in config[rpkgname]["license"]:
result["license"] = "BSL"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "CC0" in config[rpkgname]["license"]:
result["license"] = "CC0"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "Lucent Public License" in config[rpkgname]["license"]:
result["license"] = "Lucent Public License"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
elif "Unlimited" in config[rpkgname]["license"]:
result["license"] = "Unlimited"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
else:
result["license"] = "custom"
if "file LICENSE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENSE"
if "file LICENCE" in config[rpkgname]["license"]:
result["license_filename"] = "LICENCE"
return result
def write_lilac_yaml(self, filename, desc_dict):
url = desc_dict["project_url"].replace(
'${_pkgname}', desc_dict["rpkgname"])
yaml_dict = {
"maintainers": [
{"github": desc_dict["maintainer_github"]}
],
"build_prefix": "extra-x86_64",
"update_on": [
{
"source": "regex",
"regex": f'{desc_dict["rpkgname"]}_([\\d._-]+).tar.gz',
"url": url
}
]
}
if desc_dict["repo"] == "github":
yaml_dict["update_on"] = [{
"source": "github",
"github": f'{desc_dict["github_owner"]}/{desc_dict["rpkgname"]}',
"use_latest_release": True}]
repo_depends = desc_dict["depends"]
repo_depends.remove("r")
if repo_depends:
yaml_dict["repo_depends"] = repo_depends
with open(filename, "w", newline='\n') as f:
yaml.safe_dump(yaml_dict, f)
# run prettier to make pretty yaml
os.system(f'prettier -w {filename}')
def write_lilac_py(self, filename, desc_dict):
# currently, we do not generate `lilac.py` for R package from github
if desc_dict["repo"] != "github":
import_line = '\n'.join([
"#!/usr/bin/env python3",
"from lilaclib import *\n"
])
pre_build_line = '\n'.join([
"def pre_build():",
" for line in edit_file('PKGBUILD'):",
" if line.startswith('_pkgver='):",
" line = f'_pkgver={_G.newver}'",
" print(line)",
" update_pkgver_and_pkgrel(_G.newver.replace(':', '.').replace('-', '.'))\n"
])
post_build_line = '\n'.join([
"def post_build():",
" git_pkgbuild_commit()\n"
])
file_content = '\n'.join([
import_line,
pre_build_line,
post_build_line
])
with open(filename, "w", newline='\n') as f:
f.write(file_content)
def write_pkgbuild(self, filename, desc_dict):
"""
generate the PKGBUILD file based on information parsed from DESCRIPTION file
args:
filename: the PKGBUILD file path
desc_dict: dict contains information parsed from DESCRIPTION file
"""
depends = '\n'.join([
'depends=(',
'\n'.join([' ' + _ for _ in desc_dict["depends"]]),
')'
])
optdepends = None
if desc_dict["optdepends"]:
optdepends = '\n'.join([
'optdepends=(',
'\n'.join([' ' + _ for _ in desc_dict["optdepends"]]),
')'
])
build_func = '\n'.join([
'build() {',
' R CMD INSTALL ${_pkgname}_${_pkgver}.tar.gz -l "${srcdir}"',
'}'
])
if desc_dict["license_filename"]:
package_func = '\n'.join([
'package() {',
' install -dm0755 "${pkgdir}/usr/lib/R/library"',
' cp -a --no-preserve=ownership "${_pkgname}" "${pkgdir}/usr/lib/R/library"',
f' install -Dm644 "${{_pkgname}}/{desc_dict["license_filename"]}" -t "${{pkgdir}}/usr/share/licenses/${{pkgname}}"',
'}'
])
else:
package_func = '\n'.join([
'package() {',
' install -dm0755 "${pkgdir}/usr/lib/R/library"',
' cp -a --no-preserve=ownership "${_pkgname}" "${pkgdir}/usr/lib/R/library"',
'}'
])
# constuct each line of PKGBUILD file
systemrequirements_line = None
if desc_dict["systemrequirements"]:
systemrequirements_line = f'# system requirements: {desc_dict["systemrequirements"]}'
maintainer_line = f'# Maintainer: {desc_dict["maintainer"]} <{desc_dict["email"]}>\n'
_pkgname_line = f'_pkgname={desc_dict["rpkgname"]}'
_pkgver_line = f'_pkgver={desc_dict["rpkgver"]}'
pkgname_line = 'pkgname=r-${_pkgname,,}'
pkgver_line = 'pkgver=${_pkgver//[:-]/.}'
pkgrel_line = 'pkgrel=1'
pkgdesc_line = f"pkgdesc='{desc_dict['title']}'"
if "'" in desc_dict["title"]:
pkgdesc_line = f'pkgdesc="{desc_dict["title"]}"'
arch_line = f"arch=('{desc_dict['arch']}')"
url_line = f'url="{desc_dict["project_url"]}"'
license_line = f"license=('{desc_dict['license']}')"
depends_line = depends
optdepends_line = optdepends
source_line = f'source=("{desc_dict["source"]}")'
checksums_line = "sha256sums=('a')\n"
build_line = build_func + '\n'
package_line = package_func
end_line = '# vim:set ts=2 sw=2 et:\n'
pkgbuild_lines = []
if systemrequirements_line:
pkgbuild_lines.append(systemrequirements_line)
pkgbuild_lines += [
maintainer_line,
_pkgname_line,
_pkgver_line,
pkgname_line,
pkgver_line,
pkgrel_line,
pkgdesc_line,
arch_line,
url_line,
license_line,
depends_line
]
if optdepends_line:
pkgbuild_lines.append(optdepends_line)
pkgbuild_lines += [
source_line,
checksums_line,
build_line,
package_line,
end_line
]
pkgbuild_content = '\n'.join(pkgbuild_lines)
with open(filename, 'w', newline='\n') as f:
f.write(pkgbuild_content)
def generate_pkgbuild(
self,
rpkgname,
maintainer_github,
skip=False,
recursive=False,
maintainer=None,
email=None,
verbose=False,
updpkgsums=False,
repo="cran",
clean=True,
destdir='.'
):
if repo == "github":
pkgname = f"r-{rpkgname.strip('/').split('/')[-1].lower()}"
else:
pkgname = f"r-{rpkgname.lower()}"
if verbose:
print(f"generating PKGBUILD for pkg: {rpkgname}")
pkgbuild_filename = f"{osp.join(destdir, pkgname)}/PKGBUILD"
lilac_yaml_filename = f"{osp.join(destdir, pkgname)}/lilac.yaml"
lilac_py_filename = f"{osp.join(destdir, pkgname)}/lilac.py"
if skip and osp.exists(pkgbuild_filename):
if verbose:
print(
f"skip PKGBUILD generation of pkg: {pkgname} as it exists")
return
desc_dict = self.parse_description(rpkgname, repo, clean)
desc_dict["maintainer"] = maintainer
desc_dict["email"] = email
desc_dict["maintainer_github"] = maintainer_github
os.makedirs(osp.join(destdir, pkgname), exist_ok=True)
self.write_pkgbuild(pkgbuild_filename, desc_dict)
self.write_lilac_yaml(lilac_yaml_filename, desc_dict)
self.write_lilac_py(lilac_py_filename, desc_dict)
if updpkgsums:
if verbose:
print("updating source checksums")
os.system(f"updpkgsums {pkgbuild_filename}")
if recursive:
for rpkgname_dep in desc_dict["r_depends"]:
# for pkg dep not from cran repo, check if it's in CRAN
# we can not know if the pkg in cran in recursive mode
# so we check it here
# for pkg from github, we assume that it's deps are not from github anymore
if self.isInCran(rpkgname_dep):
repo = "cran"
else:
repo = "bioconductor"
self.generate_pkgbuild(
rpkgname_dep,
maintainer_github,
skip=skip,
recursive=recursive,
maintainer=maintainer,
email=email,
verbose=verbose,
updpkgsums=updpkgsums,
repo=repo,
destdir=destdir,
clean=clean
)

View file

14
README.md Normal file
View file

@ -0,0 +1,14 @@
Simple script to generate `PKGBUILD` for building R pkgs in ArchLinux
## Usage
Run `python generate_pkgbuild_for_r.py --help` for detail.
## Features
* support for R packages from [CRAN](https://cran.r-project.org)
* support for R packages from [Bioconductor](https://bioconductor.org)
* recursively generate `PKGBUILD` for R packages and its depends
* generate `lilac.yaml` and `lilac.py` for building in [ArchLinux CN repo](https://github.com/archlinuxcn/repo)
* and more...

59
generate_pkgbuild_for_r.py Executable file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env python3
import argparse
from PKGBUILDGenerator.PKGBUILDGenerator import PKGBUILDGenerator
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument("--rpkgnames", type=str, nargs='+',
help="r pkgnames in CRAN or Bioconductor")
parser.add_argument("--repo", type=str, choices=["cran", "bioconductor", "github"], default="cran",
help="repo to use, default: cran")
parser.add_argument("--destdir", default='.',
help="destdir, default: .")
parser.add_argument("--maintainer", type=str,
help="maintainer in PKGBUILD")
parser.add_argument("--email", type=str,
help="email of maintainer in PKGBUILD")
parser.add_argument("--clean", action="store_true",
help="clean temporaly files")
parser.add_argument("--recursive", action="store_true",
help="create also the PKGBUILD for deps")
parser.add_argument("--verbose", action="store_true",
help="be verbose")
parser.add_argument("--skip", action="store_true",
help="skip PKGBUILD generator if the PKGBUILD exists")
parser.add_argument("--updpkgsums", action="store_true",
help="run updatepkgsums to update source checksums")
parser.add_argument("--cran-mirror", type=str, default="https://mirrors.ustc.edu.cn/CRAN",
help="CRAN mirror, default: https://mirrors.ustc.edu.cn/CRAN")
parser.add_argument("--bioconductor-mirror", type=str, default="https://mirrors.ustc.edu.cn/bioc/",
help="Bioconductor mirror, default: https://mirrors.ustc.edu.cn/bioc/")
parser.add_argument("--maintainer-github", type=str,
help="github username of PKGBUILD maintainer, only used in `lilac.yaml`")
return parser.parse_args()
if __name__ == '__main__':
args = get_args()
gen = PKGBUILDGenerator(
cran_mirror=args.cran_mirror,
bioconductor_mirror=args.bioconductor_mirror
)
for rpkgname in args.rpkgnames:
gen.generate_pkgbuild(
rpkgname=rpkgname,
maintainer_github=args.maintainer_github,
maintainer=args.maintainer,
email=args.email,
recursive=args.recursive,
verbose=args.verbose,
updpkgsums=args.updpkgsums,
repo=args.repo,
skip=args.skip,
destdir=args.destdir,
clean=args.clean
)
print("Done")