Compare commits

...

17 commits
0.0.1 ... main

Author SHA1 Message Date
sukanka
0786f10510 fix archiving lilac.yaml for bioc 2023-04-28 22:25:42 +08:00
Kuoi
f8506f1c45
add: archiso bioarch patch 2023-03-05 03:20:09 +08:00
sukanka
f259b54e42 add error handler for get_web_bioc_ver 2023-02-25 15:21:18 +08:00
sukanka
5ad361cf8b fix description for optdepends 2023-02-24 22:38:07 +08:00
Kuoi
0815062bfa
20230209: fix 2023-02-09 13:09:49 +08:00
sukanka
3fc1b2c00a use | in lilac.yaml for multiple lines 2023-02-03 20:29:45 +08:00
sukanka
2cae84fe0b use lilac to get optdepends 2023-01-08 10:59:04 +08:00
sukanka
c05084518c support precise archived bioc version 2022-11-26 19:34:21 +08:00
sukanka
5b9e7fabd2 fix bug:
fix archive url and keep optionally required system libs
2022-11-26 13:47:36 +08:00
sukanka
ba0c7a1ad5 change arch if needscompilation changes 2022-11-26 12:32:17 +08:00
sukanka
f114ec8574 support auto unarchive cran pkgs 2022-11-26 10:07:30 +08:00
sukanka
0da0d2662a dbmanager: update log 2022-11-26 00:24:21 +08:00
sukanka
0f4a7014c4 fix bugs 2022-11-25 23:20:58 +08:00
sukanka
9726e5e042 fix dbmanager: remove old CRAN before update 2022-11-25 09:39:32 +08:00
sukanka
e283d884ac fix auto-archive 2022-11-25 09:31:36 +08:00
sukanka
49b30347bd fix depends updater 2022-11-17 23:51:37 +08:00
sukanka
dc693571ca add compare option 2022-11-17 23:41:05 +08:00
6 changed files with 1383 additions and 95 deletions

View file

@ -28,7 +28,7 @@ def search_pkgbuild_for_pkgname(
m = re_package.match(l) m = re_package.match(l)
if m: if m:
if m.group(1): if m.group(1):
ret.add(m.group(1).strip())) ret.add(m.group(1).strip())
else: else:
ret.add(pkgbuild.parent.name) ret.add(pkgbuild.parent.name)
except FileNotFoundError: except FileNotFoundError:

1093
iso/bioarch-iso.patch Normal file

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,39 @@ import datetime
from dateutil.parser import parse as parsedate from dateutil.parser import parse as parsedate
import re import re
EXCLUDED_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"
}
Base = declarative_base() Base = declarative_base()
@ -36,6 +69,9 @@ class PkgMeta(Base):
self.bioc_ver = bioc_ver self.bioc_ver = bioc_ver
self.bioc_category = bioc_category self.bioc_category = bioc_category
def __repr__(self) -> str:
return f"Name: {self.name},\nDesc: {self.desc},\nRepo: {self.repo},\nVersion: {self.bioc_ver},\nCategory: {self.bioc_category}"
def from_str(data, bioc_ver, bioc_cat): def from_str(data, bioc_ver, bioc_cat):
''' '''
@ -70,15 +106,13 @@ def get_bioc_versions(bioc_mirror="https://bioconductor.org") -> list[str]:
return bioc_versions return bioc_versions
def get_package_meta(url, mtime=None,): def get_package_meta(url, mtime=None, compare=False):
''' '''
get package metadata from Bioconductor and CRAN. get package metadata from Bioconductor and CRAN.
url: the url to be downloaded, e.g. https://bioconductor.org/packages/3.16/bioc/src/contrib/PACKAGES url: the url to be downloaded, e.g. https://bioconductor.org/packages/3.16/bioc/src/contrib/PACKAGES
mtime: the last modified time of the local file. if remote is older than mtime, ignore it. mtime: the last modified time of the local file. if remote is older than mtime, ignore it.
''' '''
if not remote_is_newer(url, mtime): if compare and not remote_is_newer(url, mtime):
logging.info(
f"Local Package List for is newer than remote, skip.")
return None return None
meta = requests.get(url) meta = requests.get(url)
if meta.status_code != requests.codes.ok: if meta.status_code != requests.codes.ok:
@ -108,6 +142,15 @@ def remote_is_newer(url, mtime) -> bool:
return url_date > file_time.astimezone() return url_date > file_time.astimezone()
def remove_all_cran_pkg(engine):
'''
remove all CRAN packages from database.
'''
session = Session(engine)
session.query(PkgMeta).filter_by(repo='CRAN').delete()
session.commit()
def update_DB(engine, min_ver=None, first_run=False, mtime=None, def update_DB(engine, min_ver=None, first_run=False, mtime=None,
bioc_mirror="https://bioconductor.org", cran_mirror="https://cran.r-project.org"): bioc_mirror="https://bioconductor.org", cran_mirror="https://cran.r-project.org"):
''' '''
@ -120,29 +163,18 @@ def update_DB(engine, min_ver=None, first_run=False, mtime=None,
cran_mirror: the CRAN mirror to use. cran_mirror: the CRAN mirror to use.
''' '''
bioc_vers = get_bioc_versions(bioc_mirror) bioc_vers = get_bioc_versions(bioc_mirror)
bioc_vers.sort(reverse=True) bioc_vers.sort()
if min_ver: if min_ver:
min_ver = version.parse(min_ver) min_ver = version.parse(min_ver)
else: else:
if first_run: if first_run:
min_ver = bioc_vers[-1] min_ver = bioc_vers[0]
else: else:
min_ver = bioc_vers[1] min_ver = bioc_vers[-2]
min_ver = max(min_ver, version.parse("1.8"))
with Session(engine) as session: with Session(engine) as session:
# CRAN
url = f"{cran_mirror}/src/contrib/PACKAGES"
logging.info("Downloading CRAN Package List")
f = get_package_meta(url, mtime)
if f:
descs = f.split('\n\n')
pkgmetas = map(lambda x: from_str(x, None, None), descs)
# insert or skip
for pkgmeta in pkgmetas:
add_or_skip(session, PkgMeta, pkgmeta)
# BIOC # BIOC
for ver in bioc_vers: for ver in bioc_vers:
if ver < min_ver: if ver < min_ver:
@ -160,7 +192,21 @@ def update_DB(engine, min_ver=None, first_run=False, mtime=None,
# insert or skip # insert or skip
for pkgmeta in pkgmetas: for pkgmeta in pkgmetas:
add_or_skip(session, PkgMeta, pkgmeta) add_or_update(session, PkgMeta, pkgmeta)
# CRAN
logging.info("Removing old package list for CRAN")
remove_all_cran_pkg(engine)
url = f"{cran_mirror}/src/contrib/PACKAGES"
logging.info("Downloading CRAN Package List")
f = get_package_meta(url, mtime)
if f:
descs = f.split('\n\n')
pkgmetas = map(lambda x: from_str(x, None, None), descs)
# insert or skip
for pkgmeta in pkgmetas:
# we already deleted all CRAN packages, so we can just add them.
add_or_update(session, PkgMeta, pkgmeta)
def add_or_skip(session, table, pkgmeta): def add_or_skip(session, table, pkgmeta):
@ -174,6 +220,26 @@ def add_or_skip(session, table, pkgmeta):
session.commit() session.commit()
def add_or_update(session, table, pkgmeta):
def getmd5sum(desc):
return re.search(r"MD5sum: ([a-z0-9]+)\n", desc).group(1)
if not pkgmeta:
return
if session.get(table, pkgmeta.name):
pkg = session.query(table).filter_by(
name=pkgmeta.name).first()
if pkg.repo == 'CRAN' and getmd5sum(pkg.desc) != getmd5sum(pkgmeta.desc) and not (pkg.name in EXCLUDED_PKGS):
logging.warning(
f"Overwritting package: {pkg.name}\n old meta :{pkg}\n new meta: {pkgmeta} \n")
pkg.desc = pkgmeta.desc
pkg.repo = pkgmeta.repo
pkg.bioc_ver = pkgmeta.bioc_ver
pkg.bioc_category = pkgmeta.bioc_category
else:
session.add(pkgmeta)
session.commit()
if __name__ == '__main__': if __name__ == '__main__':
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logging.getLogger('sqlalchemy').setLevel(logging.ERROR) logging.getLogger('sqlalchemy').setLevel(logging.ERROR)
@ -192,6 +258,8 @@ if __name__ == '__main__':
'--bioc_min_ver', help="The minimum version of Bioconductor supported, must be greater than 3.0", default=None) '--bioc_min_ver', help="The minimum version of Bioconductor supported, must be greater than 3.0", default=None)
parser.add_argument('-f', parser.add_argument('-f',
'--first_run', help="If this is the first run, the database will be created", action='store_true') '--first_run', help="If this is the first run, the database will be created", action='store_true')
parser.add_argument(
'--compare', help="Compare mtime of database and remote, if database is newer, skip remote (This can be buggy)", action='store_true')
args = parser.parse_args() args = parser.parse_args()
if not args: if not args:

View file

@ -8,44 +8,31 @@ import logging
from lilac2 import api as lilac from lilac2 import api as lilac
import argparse import argparse
import os import os
import shutil
import tempfile
import filecmp
import yaml import yaml
from typing import Optional from typing import Optional
import sqlite3 import sqlite3
from dbmanager import get_bioc_versions from dbmanager import get_bioc_versions, EXCLUDED_PKGS
from pkg_archiver import archive_pkg_yaml, archive_pkg_pkgbuild from pkg_archiver import archive_pkg_yaml, archive_pkg_pkgbuild, unarchive_cran
import re
import requests
EXCLUDED_PKGS = { # use | in lilac.yaml
"base",
"boot",
"class", def str_presenter(dumper, data):
"cluster", """configures yaml for dumping multiline strings
"codetools", Ref: https://stackoverflow.com/questions/8640959/how-can-i-control-what-scalar-form-pyyaml-uses-for-my-data"""
"compiler", if data.count('\n') > 0: # check for multiline string
"datasets", return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
"foreign", return dumper.represent_scalar('tag:yaml.org,2002:str', data)
"graphics",
"grDevices",
"grid", yaml.add_representer(str, str_presenter)
"KernSmooth", yaml.representer.SafeRepresenter.add_representer(
"lattice", str, str_presenter) # to use with safe_dum
"MASS",
"Matrix",
"methods",
"mgcv",
"nlme",
"nnet",
"parallel",
"rpart",
"spatial",
"splines",
"stats",
"stats4",
"survival",
"tcltk",
"tools",
"utils",
"R"
}
class PkgInfo: class PkgInfo:
@ -79,6 +66,7 @@ class PkgInfo:
self.depends_changed = False self.depends_changed = False
self.optdepends_changed = False self.optdepends_changed = False
self.desc = None
if self.bioc_versions == []: if self.bioc_versions == []:
self.bioc_versions = get_bioc_versions(self.bioc_meta_mirror) self.bioc_versions = get_bioc_versions(self.bioc_meta_mirror)
@ -129,18 +117,20 @@ class PkgInfo:
desc, self.bioc_ver = descall desc, self.bioc_ver = descall
self.bioc_ver = version.parse( self.bioc_ver = version.parse(
self.bioc_ver) if self.bioc_ver else None self.bioc_ver) if self.bioc_ver else None
self.desc = desc
return desc return desc
else: else:
return None return None
def is_archived(self) -> bool: def is_archived(self, release_ver) -> bool:
''' '''
Check if the package is archived in CRAN or BIOC Check if the package is archived in CRAN or BIOC
release_ver: current release of BIOC, should be a Version e.g., "3.16"
''' '''
if not self.desc: # not in database, archived in CRAN if not self.desc: # not in database, archived in CRAN
return True return True
# not in the latest BIOC version, archived in BIOC # not in the latest BIOC version, archived in BIOC
elif self.bioc_ver and self.bioc_ver != max(self.bioc_versions): elif self.bioc_ver and self.bioc_ver < release_ver:
return True return True
return False return False
@ -215,14 +205,12 @@ class PkgInfo:
if not self.new_optdepends: if not self.new_optdepends:
self.optdepends_changed = bool(self.optdepends) self.optdepends_changed = bool(self.optdepends)
return return
system_opt_reqs = [
x for x in self.optdepends if not x.startswith('r-')]
system_opt_reqs.sort()
# keep explanation of optdepends # keep explanation of optdepends
if any(map(lambda x: ':' in x, self.optdepends)): if any(map(lambda x: ':' in x, self.optdepends)):
self.new_optdepends = [ opt_dict = lilac.obtain_optdepends(parse_dict=True)
x+': ' for x in self.new_optdepends if ':' not in x]
opt_dict = {pkg.strip(): desc.strip() for (pkg, desc) in
(item.split(':', 1) for item in self.optdepends)}
if sorted(self.new_optdepends) != sorted(opt_dict.keys()): if sorted(self.new_optdepends) != sorted(opt_dict.keys()):
self.optdepends_changed = True self.optdepends_changed = True
for i in range(len(self.new_optdepends)): for i in range(len(self.new_optdepends)):
@ -232,6 +220,7 @@ class PkgInfo:
else: else:
if sorted(self.new_optdepends) != sorted(self.optdepends): if sorted(self.new_optdepends) != sorted(self.optdepends):
self.optdepends_changed = True self.optdepends_changed = True
self.new_optdepends = system_opt_reqs+self.new_optdepends
def update_pkgbuild(self) -> list[str]: def update_pkgbuild(self) -> list[str]:
''' '''
@ -248,22 +237,12 @@ class PkgInfo:
for i, line in enumerate(lines): for i, line in enumerate(lines):
if line.strip().startswith("depends"): if line.strip().startswith("depends"):
depends_interval[0] = i depends_interval[0] = i
elif line.strip().startswith("optdepends"):
optdepends_interval[0] = i
if depends_interval[0] > -1 and depends_interval[1] == -1: if depends_interval[0] > -1 and depends_interval[1] == -1:
if ')' in line: if line.strip().endswith(")"):
# end depends # end depends
depends_interval[1] = i depends_interval[1] = i
if optdepends_interval[0] > -1 and optdepends_interval[1] == -1: break
if ')' in line:
# end optdepends
optdepends_interval[1] = i
if not (depends_interval[1] < optdepends_interval[0] or optdepends_interval[1] < depends_interval[0]):
logging.error(
"depends and optdepends overlap, please fix it manually")
return
if self.depends_changed: if self.depends_changed:
for i in range(depends_interval[0], depends_interval[1]): for i in range(depends_interval[0], depends_interval[1]):
lines[i] = '' lines[i] = ''
@ -271,10 +250,20 @@ class PkgInfo:
['depends=(', '\n'.join([' ' + _ for _ in self.new_depends]), ')\n']) ['depends=(', '\n'.join([' ' + _ for _ in self.new_depends]), ')\n'])
# new lines for new optdepends # new lines for new optdepends
new_optdepends_line = ""
for i, line in enumerate(lines):
if line.strip().startswith("optdepends"):
optdepends_interval[0] = i
if optdepends_interval[0] > -1 and optdepends_interval[1] == -1:
if line.strip().endswith(")"):
# end optdepends
optdepends_interval[1] = i
break
if self.new_optdepends: if self.new_optdepends:
new_optdepends_line = '\n'.join( new_optdepends_line = '\n'.join(
['optdepends=(', '\n'.join( ['optdepends=(', '\n'.join(
[' ' + _ for _ in self.new_optdepends]), ')\n']) [' ' + f"'{x}'" if ":" in x else ' '+x for x in self.new_optdepends]), ')\n'])
if self.optdepends_changed: if self.optdepends_changed:
# no old, but has new # no old, but has new
if optdepends_interval[0] == -1: if optdepends_interval[0] == -1:
@ -284,16 +273,34 @@ class PkgInfo:
optdepends_interval[1] = depends_interval[1]+1 optdepends_interval[1] = depends_interval[1]+1
# has old, # has old,
for i in range(optdepends_interval[0], optdepends_interval[1]): else:
lines[i] = '' for i in range(optdepends_interval[0], optdepends_interval[1]):
if self.new_optdepends: lines[i] = ''
lines[optdepends_interval[1]] = new_optdepends_line lines[optdepends_interval[1]] = ""
if self.new_optdepends:
lines[optdepends_interval[1]] = new_optdepends_line
logging.info(f"Writing new PKGBUILD for {self.pkgname}") logging.info(f"Writing new PKGBUILD for {self.pkgname}")
with open("PKGBUILD", "w") as f: with open("PKGBUILD", "w") as f:
f.writelines(lines) f.writelines(lines)
change_arch(self.desc)
return self.added_depends return self.added_depends
def get_web_bioc_version(self) -> version.Version:
'''
get bioc version from BIOC website, usually newer than the one in BIOC metadata
'''
if self.bioc_ver is None or self.bioc_ver == max(self.bioc_versions):
return self.bioc_ver
for ver in self.bioc_versions:
if ver > self.bioc_ver:
url = f"{self.bioc_meta_mirror}/packages/{ver}/{self.pkgname}"
r = requests.get(url)
if r.status_code == 200:
if not 'packages-removed-with-bioconductor' in r.text:
return ver
return self.bioc_ver
def update_yaml(self, yaml_file='lilac.yaml'): def update_yaml(self, yaml_file='lilac.yaml'):
''' '''
update the `repo_depends` part of pkg, repo_depends will be sorted (systemlibs first, then r-pkgs) update the `repo_depends` part of pkg, repo_depends will be sorted (systemlibs first, then r-pkgs)
@ -311,11 +318,48 @@ class PkgInfo:
if new_deps: if new_deps:
docs['repo_depends'] = new_deps docs['repo_depends'] = new_deps
with open(yaml_file, 'w') as f: with open(yaml_file, 'w') as f:
yaml.dump(docs, f, sort_keys=False) stream = yaml.dump(docs, sort_keys=False,
default_flow_style=False, indent=2)
f.write(stream)
def create_temporary_copy(path):
'''
create temporary copy of path, remember to manually delete it.
'''
tmp = tempfile.NamedTemporaryFile(delete=False)
shutil.copy2(path, tmp.name)
return tmp.name
def change_arch(desc: str):
'''
change `arch` to `any` if NeedsCompilation is No, and change it to x86_64 if it is Yes
'''
# change any to x86_64 in PKGBUILD or vice versa
need_compile = re.search("NeedsCompilation: (.*)", desc)
if not need_compile:
return
need_compile = need_compile.group(1)
with open("PKGBUILD", "r") as f:
lines = f.readlines()
started = False
for i, line in enumerate(lines):
if line.strip().startswith("arch"):
started = True
if started:
if need_compile.lower() == 'no':
lines[i] = line.replace('x86_64', 'any')
elif need_compile.lower() == 'yes':
lines[i] = line.replace('any', 'x86_64')
if started and line.strip().endswith(')'):
break
with open("PKGBUILD", "w") as f:
f.writelines(lines)
def update_depends_by_file(file, bioarch_path="BioArchLinux", db="sqlite.db", def update_depends_by_file(file, bioarch_path="BioArchLinux", db="sqlite.db",
auto_archive=False, auto_archive=False, auto_unarchive=True,
bioc_min_ver="3.0", bioc_meta_mirror="https://bioconductor.org", output_file="added_depends.txt"): bioc_min_ver="3.0", bioc_meta_mirror="https://bioconductor.org", output_file="added_depends.txt"):
''' '''
Update depends of packages listed in `file`, one package name per line, CRAN style(e.g. `Rcpp`) and pkgname style (`r-rcpp`) are both supported. Update depends of packages listed in `file`, one package name per line, CRAN style(e.g. `Rcpp`) and pkgname style (`r-rcpp`) are both supported.
@ -324,11 +368,13 @@ def update_depends_by_file(file, bioarch_path="BioArchLinux", db="sqlite.db",
bioarch_path: path to BioArchLinux bioarch_path: path to BioArchLinux
db: path to the database to be read db: path to the database to be read
auto_archive: whether to archive the package if it is not in CRAN or the latest BIOC auto_archive: whether to archive the package if it is not in CRAN or the latest BIOC
auto_unarchive: whether to unarchive the archived package if it is in CRAN.
bioc_min_ver: minimum version of Bioconductor to be supported. bioc_min_ver: minimum version of Bioconductor to be supported.
bioc_meta_mirror: The server used to get all version numbers of BIOC bioc_meta_mirror: The server used to get all version numbers of BIOC
output_file: file to write the added depends to. output_file: file to write the added depends to.
''' '''
bioc_versions = get_bioc_versions(bioc_meta_mirror) bioc_versions = get_bioc_versions(bioc_meta_mirror)
MAX_BIOC_VERSION = max(bioc_versions)
current_dir = os.getcwd() current_dir = os.getcwd()
# where the name are _pkgname (May have upper letters) or pkgname (r-xxx) # where the name are _pkgname (May have upper letters) or pkgname (r-xxx)
conn = sqlite3.connect(db) conn = sqlite3.connect(db)
@ -336,20 +382,43 @@ def update_depends_by_file(file, bioarch_path="BioArchLinux", db="sqlite.db",
added_deps = [] added_deps = []
with open(file, "r") as f: with open(file, "r") as f:
for pkgname in f: for pkgname in f:
logging.debug(f"Dealing with {pkgname}")
pkgname = pkgname.strip() pkgname = pkgname.strip()
if not pkgname.strip().startswith("r-"): if not pkgname.strip().startswith("r-"):
pkgname = "r-"+pkgname.lower() pkgname = "r-"+pkgname.lower()
logging.info(f"Updating {pkgname}")
os.chdir(f"{bioarch_path}/{pkgname}") os.chdir(f"{bioarch_path}/{pkgname}")
temp_pkgbuild = create_temporary_copy("PKGBUILD")
temp_lilac = create_temporary_copy("lilac.yaml")
pkginfo = PkgInfo(bioc_min_version=bioc_min_ver, pkginfo = PkgInfo(bioc_min_version=bioc_min_ver,
bioc_meta_mirror=bioc_meta_mirror, bioc_versions=bioc_versions) bioc_meta_mirror=bioc_meta_mirror, bioc_versions=bioc_versions)
pkginfo.build_body(cursor) pkginfo.build_body(cursor)
pkginfo.update_pkgbuild() pkginfo.update_pkgbuild()
pkginfo.update_yaml() pkginfo.update_yaml()
if auto_archive and pkginfo.is_archived(): if auto_archive and pkginfo.is_archived(MAX_BIOC_VERSION):
archive_pkg_yaml(bioconductor_version=pkginfo.bioc_ver) temp_bioc_ver = pkginfo.bioc_ver
archive_pkg_pkgbuild(bioconductor_version=pkginfo.bioc_ver) if pkginfo.bioc_ver != None and pkginfo.bioc_ver < MAX_BIOC_VERSION:
lilac.update_pkgrel() try:
temp_bioc_ver = pkginfo.get_web_bioc_version()
except Exception as e:
logging.error(
f"Failed to getting web bioc version for {pkgname} due to {e}")
temp_bioc_ver = None
if temp_bioc_ver == None or temp_bioc_ver < MAX_BIOC_VERSION:
archive_pkg_yaml(bioconductor_version=temp_bioc_ver)
archive_pkg_pkgbuild(bioconductor_version=temp_bioc_ver)
# if PKGBUILD changed, bump pkgrel
if auto_unarchive and pkginfo.desc:
unarchive_cran()
if not filecmp.cmp(temp_pkgbuild, "PKGBUILD"):
lilac.update_pkgrel()
logging.info(f"Updating {pkgname}")
else:
# else revert changes to lilac.yaml
shutil.copy2(temp_lilac, "lilac.yaml")
logging.debug(f"No changes to {pkgname}")
os.remove(temp_pkgbuild)
os.remove(temp_lilac)
if pkginfo.added_depends: if pkginfo.added_depends:
added_deps += pkginfo.added_depends added_deps += pkginfo.added_depends
os.chdir(current_dir) os.chdir(current_dir)
@ -378,11 +447,15 @@ if __name__ == '__main__':
'-o', '--output', help='The file to save newly added depends name', default="added_depends.txt") '-o', '--output', help='The file to save newly added depends name', default="added_depends.txt")
parser.add_argument( parser.add_argument(
'-a', '--auto-archive', help='Automatically archive pkgs that are not in CRAN or the latest BIOC release', action='store_true') '-a', '--auto-archive', help='Automatically archive pkgs that are not in CRAN or the latest BIOC release', action='store_true')
parser.add_argument(
'--no-auto-unarchive', help='DO NOT Automatically unarchive pkgs that are now in CRAN', action='store_false')
args = parser.parse_args() args = parser.parse_args()
if args.file: if args.file:
update_depends_by_file(args.file, args.bioarch_path, args.db, update_depends_by_file(args.file, args.bioarch_path, args.db,
args.bioc_min_ver, bioc_meta_mirror=args.bioc_meta_mirror, output_file=args.output, auto_archive=args.auto_archive) output_file=args.output,
bioc_min_ver=args.bioc_min_ver, bioc_meta_mirror=args.bioc_meta_mirror,
auto_archive=args.auto_archive, auto_unarchive=args.no_auto_unarchive)
else: else:
parser.print_help() parser.print_help()

View file

@ -7,6 +7,7 @@ import os
import yaml import yaml
import argparse import argparse
from lilac2.api import update_pkgrel from lilac2.api import update_pkgrel
import re
def archive_pkg_by_file_list(file, bioarch_path="BioArchLinux", biconductor_version=3.15, step=1): def archive_pkg_by_file_list(file, bioarch_path="BioArchLinux", biconductor_version=3.15, step=1):
@ -40,21 +41,30 @@ def archive_pkg_yaml(bioconductor_version=3.15, yaml_file="lilac.yaml"):
with open(yaml_file, "r") as f: with open(yaml_file, "r") as f:
docs = yaml.load(f, Loader=yaml.FullLoader) docs = yaml.load(f, Loader=yaml.FullLoader)
url_idx = -1 url_idx = -1
url = None
for i in range(len(docs['update_on'])): for i in range(len(docs['update_on'])):
if "url" in docs['update_on'][i].keys(): if "url" in docs['update_on'][i].keys():
url = docs['update_on'][i]['url'] url = docs['update_on'][i]['url']
url_idx = i url_idx = i
break break
pkg = url.rstrip('/').split('/')[-1] if not url:
return
pkg = url.rstrip('/')
pkg = re.split('/|=', pkg)[-1]
archive_url = None
# CRAN ARCHIVE # CRAN ARCHIVE
if 'cran.r-project.org' in url: if 'cran.r-project.org' in url:
archive_url = f"https://cran.r-project.org/src/contrib/Archive/{pkg}" archive_url = f"https://cran.r-project.org/src/contrib/Archive/{pkg}"
# Bioconductor ARCHIVE # Bioconductor ARCHIVE
elif 'bioconductor.org' in url: elif 'bioconductor.org' in url:
archive_url = f"https://bioconductor.org/packages/{bioconductor_version}/{pkg}" # https://bioconductor.org/packages/AffyCompatible
# to
docs['update_on'][url_idx]['url'] = archive_url # https://bioconductor.org/packages/3.16/AffyCompatible
archive_url = url.replace(
'packages', f"packages/{bioconductor_version}")
if archive_url:
docs['update_on'][url_idx]['url'] = archive_url
with open(yaml_file, 'w') as f: with open(yaml_file, 'w') as f:
yaml.dump(docs, f, sort_keys=False) yaml.dump(docs, f, sort_keys=False)
@ -70,7 +80,7 @@ def archive_pkg_pkgbuild(bioconductor_version=3.15, _pkgname="_pkgname"):
flag = False flag = False
for i in range(len(lines)): for i in range(len(lines)):
if lines[i].startswith("url=") and '//bioconductor.org' in lines[i]: if lines[i].startswith("url=") and '//bioconductor.org' in lines[i] and not re.search("packages/[\d.]+", lines[i]):
lines[i] = lines[i].replace( lines[i] = lines[i].replace(
"packages/", f"packages/{bioconductor_version}/") "packages/", f"packages/{bioconductor_version}/")
changed = True changed = True
@ -84,8 +94,8 @@ def archive_pkg_pkgbuild(bioconductor_version=3.15, _pkgname="_pkgname"):
# to # to
# https://cran.r-project.org/src/contrib/Archive/${_pkgname}/${_pkgname}_${pkgver}.tar.gz # https://cran.r-project.org/src/contrib/Archive/${_pkgname}/${_pkgname}_${pkgver}.tar.gz
new_line = lines[i].replace( new_line = lines[i].replace(
"src/contrib", r"src/contrib/Archive/${" + _pkgname + '}') "src/contrib", "src/contrib/Archive/${_pkgname}")
elif '//bioconductor.org' in lines[i]: elif '//bioconductor.org' in lines[i] and bioconductor_version != None:
# https://bioconductor.org/packages/release/bioc/src/contrib/${_pkgname}_${_pkgver}.tar.gz # https://bioconductor.org/packages/release/bioc/src/contrib/${_pkgname}_${_pkgver}.tar.gz
# to # to
# https://bioconductor.org/packages/3.14/bioc/src/contrib/ABAEnrichment_1.24.0.tar.gz # https://bioconductor.org/packages/3.14/bioc/src/contrib/ABAEnrichment_1.24.0.tar.gz
@ -101,6 +111,47 @@ def archive_pkg_pkgbuild(bioconductor_version=3.15, _pkgname="_pkgname"):
return changed return changed
def unarchive_cran():
unarchive_cran_pkgbuild()
unarchive_cran_yaml()
def unarchive_cran_pkgbuild():
with open("PKGBUILD", "r") as f:
lines = f.readlines()
for i in range(len(lines)):
if lines[i].startswith("source="):
if "src/contrib/Archive" in lines[i]:
lines[i] = lines[i].replace(
"src/contrib/Archive/${_pkgname}", "src/contrib")
with open("PKGBUILD", "w") as f:
f.writelines(lines)
def unarchive_cran_yaml():
with open("lilac.yaml", "r") as f:
docs = yaml.load(f, Loader=yaml.FullLoader)
url_idx = -1
url = None
for i in range(len(docs['update_on'])):
if "url" in docs['update_on'][i].keys():
url = docs['update_on'][i]['url']
url_idx = i
break
if not url:
return
pkg = url.rstrip('/')
pkg = re.split('/|=', pkg)[-1]
archive_url = None
# CRAN ARCHIVE
if 'cran.r-project.org' in url:
archive_url = f"https://cran.r-project.org/package={pkg}"
if archive_url:
docs['update_on'][url_idx]['url'] = archive_url
with open("lilac.yaml", 'w') as f:
yaml.dump(docs, f, sort_keys=False)
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(

View file

@ -12,3 +12,6 @@ For usage, run with argument `-h`.
- [x] `depends_updater` supports archiving PKGs automatically. - [x] `depends_updater` supports archiving PKGs automatically.
- [ ] generate PKGBUILD for missing dependencies `depends_updater` - [ ] generate PKGBUILD for missing dependencies `depends_updater`
- [x] merge `sync_meta_data` into `dbmanager` - [x] merge `sync_meta_data` into `dbmanager`
- [x] merge `pkg_archiver` into `dbmanager`
- [x] support unarchiving CRAN pkgs automatically in `pkg_archiver`
- [ ] correct `arch` for pkgs.