complete vcs support

This commit is contained in:
Evgenii Alekseev 2021-03-08 12:58:51 +03:00
parent 0531df3688
commit 6f67641f4c
5 changed files with 58 additions and 15 deletions

View File

@ -68,7 +68,7 @@ def sync(args: argparse.Namespace) -> None:
def update(args: argparse.Namespace) -> None: def update(args: argparse.Namespace) -> None:
app = _get_app(args) app = _get_app(args)
log_fn = lambda line: print(line) if args.dry_run else app.logger.info(line) log_fn = lambda line: print(line) if args.dry_run else app.logger.info(line)
packages = app.get_updates(args.no_aur, args.no_manual, log_fn) packages = app.get_updates(args.no_aur, args.no_manual, args.no_vcs, log_fn)
if args.dry_run: if args.dry_run:
return return
app.update(packages) app.update(packages)
@ -88,7 +88,7 @@ if __name__ == '__main__':
add_parser.set_defaults(fn=add) add_parser.set_defaults(fn=add)
check_parser = subparsers.add_parser('check', description='check for updates') check_parser = subparsers.add_parser('check', description='check for updates')
check_parser.set_defaults(fn=update, no_aur=False, no_manual=True, dry_run=False) check_parser.set_defaults(fn=update, no_aur=False, no_manual=True, no_vcs=False, dry_run=True)
rebuild_parser = subparsers.add_parser('rebuild', description='rebuild whole repository') rebuild_parser = subparsers.add_parser('rebuild', description='rebuild whole repository')
rebuild_parser.set_defaults(fn=rebuild) rebuild_parser.set_defaults(fn=rebuild)
@ -109,6 +109,7 @@ if __name__ == '__main__':
update_parser.add_argument('--dry-run', help='just perform check for updates, same as check command', action='store_true') update_parser.add_argument('--dry-run', help='just perform check for updates, same as check command', action='store_true')
update_parser.add_argument('--no-aur', help='do not check for AUR updates', action='store_true') update_parser.add_argument('--no-aur', help='do not check for AUR updates', action='store_true')
update_parser.add_argument('--no-manual', help='do not include manual updates', action='store_true') update_parser.add_argument('--no-manual', help='do not include manual updates', action='store_true')
update_parser.add_argument('--no-vcs', help='do not check VCS packages', action='store_true')
update_parser.set_defaults(fn=update) update_parser.set_defaults(fn=update)
args = parser.parse_args() args = parser.parse_args()

View File

@ -41,12 +41,13 @@ class Application:
self.report() self.report()
self.sync() self.sync()
def get_updates(self, no_aur: bool, no_manual: bool, log_fn: Callable[[str], None]) -> List[Package]: def get_updates(self, no_aur: bool, no_manual: bool, no_vcs: bool,
log_fn: Callable[[str], None]) -> List[Package]:
updates = [] updates = []
checked: List[str] = [] checked: List[str] = []
if not no_aur: if not no_aur:
updates.extend(self.repository.updates_aur(checked)) updates.extend(self.repository.updates_aur(no_vcs, checked))
if not no_manual: if not no_manual:
updates.extend(self.repository.updates_manual(checked)) updates.extend(self.repository.updates_manual(checked))
@ -58,8 +59,7 @@ class Application:
def add(self, names: List[str]) -> None: def add(self, names: List[str]) -> None:
def add_manual(name: str) -> None: def add_manual(name: str) -> None:
package = Package.load(name, self.config.get('aur', 'url')) package = Package.load(name, self.config.get('aur', 'url'))
task = Task(package, self.architecture, self.config, self.repository.paths) Task.fetch(os.path.join(self.repository.paths.manual, package.name), package.url)
task.fetch(os.path.join(self.repository.paths.manual, package.name))
def add_archive(src: str) -> None: def add_archive(src: str) -> None:
dst = os.path.join(self.repository.paths.packages, os.path.basename(src)) dst = os.path.join(self.repository.paths.packages, os.path.basename(src))

View File

@ -48,6 +48,11 @@ class Task:
def git_path(self) -> str: def git_path(self) -> str:
return os.path.join(self.paths.sources, self.package.name) return os.path.join(self.paths.sources, self.package.name)
@staticmethod
def fetch(local: str, remote: str) -> None:
shutil.rmtree(local, ignore_errors=True) # remove in case if file exists
check_output('git', 'clone', remote, local, exception=None)
def build(self) -> List[str]: def build(self) -> List[str]:
cmd = [self.build_command, '-r', self.paths.chroot] cmd = [self.build_command, '-r', self.paths.chroot]
cmd.extend(self.archbuild_flags) cmd.extend(self.archbuild_flags)
@ -66,7 +71,6 @@ class Task:
exception=BuildFailed(self.package.name), exception=BuildFailed(self.package.name),
cwd=self.git_path).splitlines() cwd=self.git_path).splitlines()
def fetch(self, path: Optional[str] = None) -> None: def clone(self, path: Optional[str] = None) -> None:
git_path = path or self.git_path git_path = path or self.git_path
shutil.rmtree(git_path, ignore_errors=True) # remote in case if file exists return Task.fetch(git_path, self.package.url)
check_output('git', 'clone', self.package.url, git_path, exception=None)

View File

@ -80,7 +80,7 @@ class Repository:
def process_build(self, updates: List[Package]) -> List[str]: def process_build(self, updates: List[Package]) -> List[str]:
def build_single(package: Package) -> None: def build_single(package: Package) -> None:
task = Task(package, self.architecture, self.config, self.paths) task = Task(package, self.architecture, self.config, self.paths)
task.fetch() task.clone()
built = task.build() built = task.build()
for src in built: for src in built:
dst = os.path.join(self.paths.packages, os.path.basename(src)) dst = os.path.join(self.paths.packages, os.path.basename(src))
@ -140,7 +140,7 @@ class Repository:
return self.wrapper.repo_path return self.wrapper.repo_path
def updates_aur(self, checked: List[str]) -> List[Package]: def updates_aur(self, no_vcs: bool, checked: List[str]) -> List[Package]:
result: List[Package] = [] result: List[Package] = []
ignore_list = self.config.get_list( ignore_list = self.config.get_list(
self.config.get_section_name('build', self.architecture), 'ignore_packages') self.config.get_section_name('build', self.architecture), 'ignore_packages')
@ -159,6 +159,8 @@ class Repository:
continue continue
if local.name in ignore_list: if local.name in ignore_list:
continue continue
if local.is_vcs and no_vcs:
continue
if local.is_outdated(remote): if local.is_outdated(remote):
result.append(remote) result.append(remote)

View File

@ -19,8 +19,11 @@
# #
from __future__ import annotations from __future__ import annotations
import shutil
import aur import aur
import os import os
import tempfile
from configparser import RawConfigParser from configparser import RawConfigParser
from dataclasses import dataclass from dataclasses import dataclass
@ -36,16 +39,48 @@ class Package:
name: str name: str
version: str version: str
url: str url: str
remote: bool
@property
def is_vcs(self) -> bool:
return self.name.endswith('-bzr') \
or self.name.endswith('-csv')\
or self.name.endswith('-darcs')\
or self.name.endswith('-git')\
or self.name.endswith('-hg')\
or self.name.endswith('-svn')
# additional method to handle vcs versions
def actual_version(self) -> str:
if not self.is_vcs:
return self.version
from ahriman.core.build_tools.task import Task
clone_dir = tempfile.mkdtemp()
try:
Task.fetch(clone_dir, self.url)
# update pkgver first
check_output('makepkg', '--nodeps', '--noprepare', '--nobuild',
exception=None, cwd=clone_dir)
# generate new .SRCINFO and put it to parser
src_info_source = check_output('makepkg', '--printsrcinfo',
exception=None, cwd=clone_dir)
src_info, errors = parse_srcinfo(src_info_source)
if errors:
raise InvalidPackageInfo(errors)
return f'{src_info["pkgver"]}-{src_info["pkgrel"]}'
finally:
shutil.rmtree(clone_dir, ignore_errors=True)
@classmethod @classmethod
def from_archive(cls: Type[Package], path: str, aur_url: str) -> Package: def from_archive(cls: Type[Package], path: str, aur_url: str) -> Package:
name, version = check_output('expac', '-p', '%e %v', path, exception=None).split() name, version = check_output('expac', '-p', '%e %v', path, exception=None).split()
return cls(name, version, f'{aur_url}/{name}.git') return cls(name, version, f'{aur_url}/{name}.git', False)
@classmethod @classmethod
def from_aur(cls: Type[Package], name: str, aur_url: str)-> Package: def from_aur(cls: Type[Package], name: str, aur_url: str)-> Package:
package = aur.info(name) package = aur.info(name)
return cls(package.package_base, package.version, f'{aur_url}/{package.package_base}.git') return cls(package.package_base, package.version, f'{aur_url}/{package.package_base}.git', True)
@classmethod @classmethod
def from_build(cls: Type[Package], path: str) -> Package: def from_build(cls: Type[Package], path: str) -> Package:
@ -58,7 +93,7 @@ class Package:
raise InvalidPackageInfo(errors) raise InvalidPackageInfo(errors)
return cls(src_info['pkgbase'], f'{src_info["pkgver"]}-{src_info["pkgrel"]}', return cls(src_info['pkgbase'], f'{src_info["pkgver"]}-{src_info["pkgrel"]}',
git_config.get('remote "origin"', 'url')) git_config.get('remote "origin"', 'url'), False)
@classmethod @classmethod
def load(cls: Type[Package], path: str, aur_url: str) -> Package: def load(cls: Type[Package], path: str, aur_url: str) -> Package:
@ -76,5 +111,6 @@ class Package:
raise InvalidPackageInfo(str(e)) raise InvalidPackageInfo(str(e))
def is_outdated(self, remote: Package) -> bool: def is_outdated(self, remote: Package) -> bool:
result = check_output('vercmp', self.version, remote.version, exception=None) remote_version = remote.actual_version() # either normal version or updated VCS
result = check_output('vercmp', self.version, remote_version, exception=None)
return True if int(result) < 0 else False return True if int(result) < 0 else False