diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index 8b3dfde0..4f5f303b 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -137,9 +137,16 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser: """ parser = root.add_parser("package-add", aliases=["add"], help="add package", description="add package", epilog="This subcommand should be used for new package addition. It also supports flag " - "--now in case if you would like to build the package immediately.", + "--now in case if you would like to build the package immediately. " + "You can add new package from one of supported sources: " + "1) if it is already built package you can specify the path to the archive; " + "2) you can also add built packages from the directory (e.g. during the migration " + "from another repository source); " + "3) it is also possible to add package from local PKGBUILD, but in this case it " + "will be ignored during the next automatic updates; " + "4) and finally you can add package from AUR.", formatter_class=_formatter) - parser.add_argument("package", help="package base/name or archive path", nargs="+") + parser.add_argument("package", help="package base/name or path to local files", nargs="+") parser.add_argument("-n", "--now", help="run update function after", action="store_true") parser.add_argument("-s", "--source", help="package source", type=PackageSource, choices=PackageSource, default=PackageSource.Auto) diff --git a/src/ahriman/application/application.py b/src/ahriman/application/application.py index cbc11c58..84e7a702 100644 --- a/src/ahriman/application/application.py +++ b/src/ahriman/application/application.py @@ -224,13 +224,22 @@ class Application: get packages which were not found in AUR :return: unknown package list """ - packages = [] - for base in self.repository.packages(): + def has_aur(package_base: str, aur_url: str) -> bool: try: - _ = Package.from_aur(base.base, base.aur_url) + _ = Package.from_aur(package_base, aur_url) except Exception: - packages.append(base) - return packages + return False + return True + + def has_local(package_base: str) -> bool: + cache_dir = self.repository.paths.cache_for(package_base) + return cache_dir.is_dir() and not Sources.branches(cache_dir) + + return [ + package + for package in self.repository.packages() + if not has_aur(package.base, package.aur_url) and not has_local(package.base) + ] def update(self, updates: Iterable[Package]) -> None: """ diff --git a/tests/ahriman/application/test_application.py b/tests/ahriman/application/test_application.py index f830673c..9b0e66f5 100644 --- a/tests/ahriman/application/test_application.py +++ b/tests/ahriman/application/test_application.py @@ -314,23 +314,37 @@ def test_sync(application: Application, mocker: MockerFixture) -> None: executor_mock.assert_called_once() -def test_unknown(application: Application, package_ahriman: Package, mocker: MockerFixture) -> None: +def test_unknown_no_aur(application: Application, package_ahriman: Package, mocker: MockerFixture) -> None: """ - must return list of packages missing in aur + must return empty list in case if there is locally stored PKGBUILD """ mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman]) mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception()) + mocker.patch("pathlib.Path.is_dir", return_value=True) + mocker.patch("ahriman.core.build_tools.sources.Sources.branches", return_value=[]) + + assert not application.unknown() + + +def test_unknown_no_aur_no_local(application: Application, package_ahriman: Package, mocker: MockerFixture) -> None: + """ + must return list of packages missing in aur and in local storage + """ + mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman]) + mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception()) + mocker.patch("pathlib.Path.is_dir", return_value=False) packages = application.unknown() assert packages == [package_ahriman] -def test_unknown_empty(application: Application, package_ahriman: Package, mocker: MockerFixture) -> None: +def test_unknown_no_local(application: Application, package_ahriman: Package, mocker: MockerFixture) -> None: """ - must return list of packages missing in aur + must return empty list in case if there is package in AUR """ mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman]) mocker.patch("ahriman.models.package.Package.from_aur") + mocker.patch("pathlib.Path.is_dir", return_value=False) assert not application.unknown()