Skip to content

Commit

Permalink
CRUD for FreeBSD, Pacman and RPM
Browse files Browse the repository at this point in the history
  • Loading branch information
gershnik committed Jun 8, 2024
1 parent 6ed4bf1 commit 412c562
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## Unreleased

### Added
- CRUD for all repo-related objects

### Fixed
- PgpSigner now respects home directory parameter

## [0.7] - 2024-06-05

### Changed
Expand Down
22 changes: 19 additions & 3 deletions src/repopulator/freebsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,30 @@ def add_package(self, path: Path) -> FreeBSDPackage:
for existing in self.__packages:
if existing.repo_filename == package.repo_filename:
raise ValueError("duplicate package filename")
def package_key(p: FreeBSDPackage): return (p.name, p.version_key)
idx = lower_bound(self.__packages, package, lambda x, y: package_key(x) < package_key(y))
if idx < len(self.__packages) and package_key(self.__packages[idx]) == package_key(package):
idx = lower_bound(self.__packages, package, lambda x, y: self._package_key(x) < self._package_key(y))
if idx < len(self.__packages) and self._package_key(self.__packages[idx]) == self._package_key(package):
raise ValueError('Duplicate package')
self.__packages.insert(idx, package)

return package

def del_package(self, package: FreeBSDPackage):
"""Removes a package from this repository
It is not an error to pass a package that is not in a repository to this function.
It will be ignored in such case.
Args:
package: the package to remove
"""
idx = lower_bound(self.__packages, package, lambda x, y: self._package_key(x) < self._package_key(y))
if idx < len(self.__packages) and self.__packages[idx] is package:
del self.__packages[idx]

@staticmethod
def _package_key(package: FreeBSDPackage):
return (package.name, package.version_key)

@property
def packages(self) -> Sequence[FreeBSDPackage]:
"""Packages in the repository"""
Expand Down
16 changes: 16 additions & 0 deletions src/repopulator/pacman.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ def add_package(self, path: Path) -> PacmanPackage:
arch_packages.insert(idx, package)
return package

def del_package(self, package: PacmanPackage):
"""Removes a package from this repository
It is not an error to pass a package that is not in a repository to this function.
It will be ignored in such case.
Args:
package: the package to remove
"""
arch_packages = self.__packages.get(package.arch, [])
idx = lower_bound(arch_packages, package, lambda x, y: x.name < y.name)
if idx < len(arch_packages) and arch_packages[idx] is package:
del arch_packages[idx]
if not arch_packages:
del self.__packages[package.arch]

@property
def name(self):
"""Repository name"""
Expand Down
23 changes: 20 additions & 3 deletions src/repopulator/rpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,13 +518,30 @@ def add_package(self, path: Path) -> RpmPackage:
for existing in self.__packages:
if existing.pkgid == package.pkgid:
raise ValueError("duplicate package id")
def package_key(p: RpmPackage): return (p.name, p.version_key, p.arch)
idx = lower_bound(self.__packages, package, lambda x, y: package_key(x) < package_key(y))
if idx < len(self.__packages) and package_key(self.__packages[idx]) == package_key(package):

idx = lower_bound(self.__packages, package, lambda x, y: self._package_key(x) < self._package_key(y))
if idx < len(self.__packages) and self._package_key(self.__packages[idx]) == self._package_key(package):
raise ValueError('Duplicate package')
self.__packages.insert(idx, package)
return package

def del_package(self, package: RpmPackage):
"""Removes a package from this repository
It is not an error to pass a package that is not in a repository to this function.
It will be ignored in such case.
Args:
package: the package to remove
"""
idx = lower_bound(self.__packages, package, lambda x, y: self._package_key(x) < self._package_key(y))
if idx < len(self.__packages) and self.__packages[idx] is package:
del self.__packages[idx]

@staticmethod
def _package_key(p: RpmPackage):
return (p.name, p.version_key, p.arch)

@property
def packages(self) -> Sequence[RpmPackage]:
"""Packages in the repository"""
Expand Down
1 change: 1 addition & 0 deletions tests/expected/tests/test_freebsd.py.test_two/data/data
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"groups":[],"packages":[{"name":"gnustep-app","origin":"x11/gnustep-app","version":"2.0.0_20","comment":"Metaport for GNUstep applications","maintainer":"[email protected]","www":"UNKNOWN","abi":"FreeBSD:13:*","arch":"freebsd:13:*","prefix":"/usr/local","sum":"d81010b5e634f2ee50db94a99aee5defd36fe98e3b87205f4b3cef80769b6e52","flatsize":243,"path":"All/gnustep-app-2.0.0_20.pkg","repopath":"All/gnustep-app-2.0.0_20.pkg","pkgsize":2272,"desc":"Collection of GNUstep software.","annotations":{"build_timestamp":"2024-02-17T12:24:10+0000","ports_top_git_hash":"b3e528239","ports_top_checkout_unclean":"no","port_git_hash":"756e18783","port_checkout_unclean":"no","built_by":"poudriere-git-3.4.1"}},{"name":"zsm","origin":"sysutils/zsm","version":"0.4.0","comment":"ZFS Snapshot Manager","maintainer":"[email protected]","www":"https://zsm.rtfd.io/","abi":"FreeBSD:13:*","arch":"freebsd:13:*","prefix":"/usr/local","sum":"1334369fa5e1f5f409567b41c16426d3bafa158f085949ee0cda945de45f3cc4","flatsize":42813,"path":"All/zsm-0.4.0.pkg","repopath":"All/zsm-0.4.0.pkg","pkgsize":12848,"desc":"A console program that manages ZFS snapshots.\n\n- Manage multiple sets of rolling snapshots.\n- Configure a custom schedule via the config file.\n- Run in background by adding it to crontab.","annotations":{"build_timestamp":"2024-02-18T06:03:55+0000","ports_top_git_hash":"b3e528239","ports_top_checkout_unclean":"no","port_git_hash":"756e18783","port_checkout_unclean":"no","built_by":"poudriere-git-3.4.1"}}]}
7 changes: 7 additions & 0 deletions tests/expected/tests/test_freebsd.py.test_two/meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version = 2;
packing_format = "txz";
manifests = "packagesite.yaml";
data = "data";
filesite = "filesite.yaml";
manifests_archive = "packagesite";
filesite_archive = "filesite";
7 changes: 7 additions & 0 deletions tests/expected/tests/test_freebsd.py.test_two/meta.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version = 2;
packing_format = "txz";
manifests = "packagesite.yaml";
data = "data";
filesite = "filesite.yaml";
manifests_archive = "packagesite";
filesite_archive = "filesite";
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"name":"gnustep-app","origin":"x11/gnustep-app","version":"2.0.0_20","comment":"Metaport for GNUstep applications","maintainer":"[email protected]","www":"UNKNOWN","abi":"FreeBSD:13:*","arch":"freebsd:13:*","prefix":"/usr/local","flatsize":243,"licenselogic":"single","licenses":["NA"],"desc":"Collection of GNUstep software.","deps":{"aclock":{"origin":"x11-clocks/aclock","version":"0.4.0_10"},"addresses":{"origin":"mail/addresses","version":"0.4.8_9"},"addresses-goodies":{"origin":"mail/addresses-goodies","version":"0.4.8_10"},"affiche":{"origin":"deskutils/affiche","version":"0.6.0_12"},"appwrapper":{"origin":"deskutils/appwrapper","version":"0.1_12"},"batmon":{"origin":"sysutils/batmon","version":"0.8_6"},"biococoa":{"origin":"biology/biococoa","version":"2.2.2_8"},"camerakit":{"origin":"graphics/camerakit","version":"0.0.1_15"},"cartotheque":{"origin":"deskutils/cartotheque","version":"0.1_12"},"cddb-bundle":{"origin":"audio/cddb-bundle","version":"0.2_12"},"cenon":{"origin":"graphics/cenon","version":"4.0.2_6,1"},"duncan":{"origin":"textproc/duncan","version":"0.4_1"},"easydiff":{"origin":"textproc/easydiff","version":"0.4.0_10"},"edenmath":{"origin":"math/edenmath","version":"1.1.1_12"},"expense":{"origin":"finance/expense","version":"0.1_12"},"fortunate":{"origin":"games/fortunate","version":"3.1_11"},"fortytwo":{"origin":"graphics/fortytwo","version":"0.2.0_13"},"fortytwo-bdb":{"origin":"databases/fortytwo-bdb","version":"0.2.1_12"},"fortytwo-encore":{"origin":"devel/fortytwo-encore","version":"0.3.1_10"},"gmastermind":{"origin":"games/gmastermind","version":"0.6_9"},"gmines":{"origin":"games/gmines","version":"0.2_9"},"gnumail":{"origin":"mail/gnumail","version":"1.4.0_1"},"gnustep-back":{"origin":"x11-toolkits/gnustep-back","version":"0.28.0_3"},"gnustep-base":{"origin":"lang/gnustep-base","version":"1.29.0_1"},"gnustep-cdplayer":{"origin":"audio/gnustep-cdplayer","version":"0.5.1_10"},"gnustep-ftp":{"origin":"ftp/gnustep-ftp","version":"0.6_2"},"gnustep-gui":{"origin":"x11-toolkits/gnustep-gui","version":"0.28.0_8"},"gnustep-ladder":{"origin":"games/gnustep-ladder","version":"1.0_11"},"gnustep-preview":{"origin":"graphics/preview","version":"0.8.5_12"},"gnustep-sudoku":{"origin":"games/gnustep-sudoku","version":"0.7_9"},"gnustep-wrapper":{"origin":"deskutils/gnustep-wrapper","version":"0.1.0_11"},"gorm":{"origin":"devel/gorm","version":"1.2.23_5"},"grubik":{"origin":"games/grubik","version":"0.1_11"},"gscheme":{"origin":"lang/gscheme","version":"0.6_10"},"gshisen":{"origin":"games/gshisen","version":"1.3.0_9"},"gskrab":{"origin":"x11/gskrab","version":"0.0.1_12"},"gspdf":{"origin":"print/gspdf","version":"0.5_12"},"gtamsanalyzer":{"origin":"science/gtamsanalyzer","version":"0.42_12"},"gworkspace":{"origin":"deskutils/gworkspace","version":"1.0.0_1"},"gworkspace-gwmetadata":{"origin":"deskutils/gworkspace-gwmetadata","version":"1.0.0_1"},"helpviewer":{"origin":"deskutils/helpviewer","version":"0.3_12"},"highlighterkit":{"origin":"devel/highlighterkit","version":"0.1_11"},"imageviewer":{"origin":"graphics/imageviewer","version":"0.6.3_12"},"innerspace":{"origin":"x11/innerspace","version":"0.2.0_11"},"ja-jishyo":{"origin":"japanese/jishyo","version":"0.1_13"},"jigsaw":{"origin":"games/jigsaw","version":"0.8_9"},"lapispuzzle":{"origin":"games/lapispuzzle","version":"1.2_9"},"laternamagica":{"origin":"graphics/laternamagica","version":"0.5_5"},"latex-service":{"origin":"textproc/latex-service","version":"0.1_11"},"localize":{"origin":"textproc/localize","version":"0.0.1_12"},"lusernet":{"origin":"news/lusernet","version":"0.4.2_12"},"mpdcon":{"origin":"audio/mpdcon","version":"1.5.1_12"},"nextgo":{"origin":"games/nextgo","version":"3.0_11"},"paje":{"origin":"science/paje","version":"1.97_12"},"pantomime":{"origin":"mail/pantomime","version":"1.4.0"},"pikopixel":{"origin":"graphics/pikopixel","version":"1.0.b10_2,1"},"pixen":{"origin":"graphics/pixen","version":"0.1_11"},"plopfolio":{"origin":"deskutils/plopfolio","version":"0.1.0_12"},"poe":{"origin":"multimedia/poe","version":"0.5.1_15"},"price":{"origin":"graphics/price","version":"1.3.0_8"},"remotedesk":{"origin":"net/remotedesk","version":"0.1_11"},"simpleagenda":{"origin":"deskutils/simpleagenda","version":"0.43_13"},"systempreferences":{"origin":"deskutils/systempreferences","version":"1.2.0_9"},"terminal.app":{"origin":"x11/terminal.app","version":"0.9.9_5"},"timemon":{"origin":"sysutils/timemon","version":"4.2_6"},"toolboxkit":{"origin":"deskutils/toolboxkit","version":"0.8_11"},"waiho":{"origin":"ftp/waiho","version":"0.2_12"},"wizardkit":{"origin":"devel/wizardkit","version":"0.1_11"},"zillion":{"origin":"net/zillion","version":"0.1_13"},"zipper":{"origin":"archivers/zipper","version":"1.5_9"}},"categories":["x11","gnustep"],"annotations":{"build_timestamp":"2024-02-17T12:24:10+0000","ports_top_git_hash":"b3e528239","ports_top_checkout_unclean":"no","port_git_hash":"756e18783","port_checkout_unclean":"no","built_by":"poudriere-git-3.4.1"},"messages":[{"message":"===> NOTICE:\n\nThe gnustep-app port currently does not have a maintainer. As a result, it is\nmore likely to have unresolved issues, not be up-to-date, or even be removed in\nthe future. To volunteer to maintain this port, please create an issue at:\n\nhttps://bugs.freebsd.org/bugzilla\n\nMore information about port maintainership is available at:\n\nhttps://docs.freebsd.org/en/articles/contributing/#ports-contributing"}]}
{"name":"zsm","origin":"sysutils/zsm","version":"0.4.0","comment":"ZFS Snapshot Manager","maintainer":"[email protected]","www":"https://zsm.rtfd.io/","abi":"FreeBSD:13:*","arch":"freebsd:13:*","prefix":"/usr/local","flatsize":42813,"licenselogic":"single","licenses":["BSD2CLAUSE"],"desc":"A console program that manages ZFS snapshots.\n\n- Manage multiple sets of rolling snapshots.\n- Configure a custom schedule via the config file.\n- Run in background by adding it to crontab.","deps":{"py39-click":{"origin":"devel/py-click","version":"8.1.7"},"py39-marshmallow":{"origin":"devel/py-marshmallow","version":"3.20.1"},"py39-pid":{"origin":"devel/py-pid","version":"3.0.4"},"py39-setuptools":{"origin":"devel/py-setuptools","version":"63.1.0_1"},"py39-yaml":{"origin":"devel/py-yaml","version":"6.0.1"},"python39":{"origin":"lang/python39","version":"3.9.18"}},"categories":["sysutils","python"],"annotations":{"build_timestamp":"2024-02-18T06:03:55+0000","ports_top_git_hash":"b3e528239","ports_top_checkout_unclean":"no","port_git_hash":"756e18783","port_checkout_unclean":"no","built_by":"poudriere-git-3.4.1"}}
Binary file not shown.
Binary file not shown.
50 changes: 50 additions & 0 deletions tests/test_freebsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,53 @@ def test_one(binaries_path, output_path, expected_path, pki_signer, fixed_dateti
compare_files(output_path / 'meta', expected_path / 'meta', should_populate)
compare_files(output_path / 'data/data', expected_path / 'data/data', should_populate)
compare_files(output_path / 'packagesite/packagesite.yaml', expected_path / 'packagesite/packagesite.yaml', should_populate)


@pytest.mark.download(
'https://pkg.freebsd.org/FreeBSD:13:amd64/release_3/All/zsm-0.4.0.pkg',
'https://pkg.freebsd.org/FreeBSD:13:amd64/release_3/All/gnustep-app-2.0.0_20.pkg'
)
def test_two(binaries_path, output_path, expected_path, pki_signer, fixed_datetime, should_populate):
repo = FreeBSDRepo()
repo.add_package(binaries_path / 'zsm-0.4.0.pkg')
package = repo.add_package(binaries_path / 'gnustep-app-2.0.0_20.pkg')
assert package.name == 'gnustep-app'
assert package.arch == 'freebsd:13:*'
assert package.version_str == '2.0.0_20'
assert package.version_key == VersionKey(2, 0, 0, 20)
assert package.src_path == binaries_path / 'gnustep-app-2.0.0_20.pkg'
assert package.repo_filename == 'gnustep-app-2.0.0_20.pkg'
repo.export(output_path, pki_signer, fixed_datetime, keep_expanded=True)
compare_files(output_path / 'All/gnustep-app-2.0.0_20.pkg', binaries_path / 'gnustep-app-2.0.0_20.pkg')
compare_files(output_path / 'All/zsm-0.4.0.pkg', binaries_path / 'zsm-0.4.0.pkg')
compare_files(output_path / 'meta.conf', expected_path / 'meta.conf', should_populate)
compare_files(output_path / 'meta', expected_path / 'meta', should_populate)
compare_files(output_path / 'data/data', expected_path / 'data/data', should_populate)
compare_files(output_path / 'packagesite/packagesite.yaml', expected_path / 'packagesite/packagesite.yaml', should_populate)

@pytest.mark.download(
'https://pkg.freebsd.org/FreeBSD:13:amd64/release_3/All/zsm-0.4.0.pkg',
'https://pkg.freebsd.org/FreeBSD:13:amd64/release_3/All/gnustep-app-2.0.0_20.pkg',
'https://pkg.freebsd.org/FreeBSD:13:amd64/release_3/All/gnurobots-1.2.0_17.pkg'
)
def test_crud(binaries_path):
repo = FreeBSDRepo()

package = repo.add_package(binaries_path / 'zsm-0.4.0.pkg')
repo.del_package(package)
assert [x for x in repo.packages] == []
repo.del_package(package) # should succeed
package1 = repo.add_package(binaries_path / 'zsm-0.4.0.pkg')
package2 = repo.add_package(binaries_path / 'gnustep-app-2.0.0_20.pkg')
repo.del_package(package1)
assert [x for x in repo.packages] == [package2]

package1 = repo.add_package(binaries_path / 'zsm-0.4.0.pkg')
package3 = repo.add_package(binaries_path / 'gnurobots-1.2.0_17.pkg')

repo.del_package(package3)
assert [x for x in repo.packages] == [package2, package1]

repo.del_package(package2)
assert [x for x in repo.packages] == [package1]

Loading

0 comments on commit 412c562

Please sign in to comment.