Closed uschi2000 closed 2 years ago
Take a look please, @anancarv
According to https://www.jfrog.com/confluence/display/JFROG/Repository+Configuration+JSON, 'Cargo' is not a supported package type for virtual repositories. As it stands, I suspect this would result in an HTTP-level error. Do you think that's OK?
According to https://www.jfrog.com/confluence/display/JFROG/Repository+Configuration+JSON, 'Cargo' is not a supported package type for virtual repositories. As it stands, I suspect this would result in an HTTP-level error. Do you think that's OK?
Hi @uschi2000 , sorry for the late answer. As you highlighted it above, this implementation will lead to errors for virtual repositories. To overcome it, you have multiple solutions:
First, within the create and update repository methods, after having verified the type of the repository instance (VirtualRepository in your case), if the repository PackageTypeEnum is cargo raise an error.
Second, in the models/repository.py
create a new VirtualRepoPackageTypeEnum
that will inherit from the old one BasePackageTypeEnum
. Then, VirtualRepoPackageTypeEnum will be used for creating virtual repositories and the other for local and remote.
I have a preference for the second solution
I don't think we can subclass enums: https://docs.python.org/3/library/enum.html#restricted-enum-subclassing
So the next-best thing would be sth like:
class BasePackageTypeEnum(str, Enum):
"""Enumerates the package types that all repository types support."""
# Keep these in sync with ExtendedPackageTypeEnum
maven = "maven"
gradle = "gradle"
ivy = "ivy"
sbt = "sbt"
helm = "helm"
cocoapods = "cocoapods"
opkg = "opkg"
rpm = "rpm"
nuget = "nuget"
cran = "cran"
gems = "gems"
npm = "npm"
bower = "bower"
debian = "debian"
pypi = "pypi"
docker = "docker"
yum = "yum"
vcs = "vcs"
composer = "composer"
go = "go"
p2 = "p2"
chef = "chef"
puppet = "puppet"
generic = "generic"
conan = "conan"
alpine = "alpine"
gitlfs = "gitlfs"
vagrant = "vagrant"
conda = "conda"
class ExtendedPackageTypeEnum(str, Enum):
"""Enumerates the additional package types supported by some repository types."""
# Keep these in sync with BasePackageTypeEnum
maven = "maven"
gradle = "gradle"
ivy = "ivy"
sbt = "sbt"
helm = "helm"
cocoapods = "cocoapods"
opkg = "opkg"
rpm = "rpm"
nuget = "nuget"
cran = "cran"
gems = "gems"
npm = "npm"
bower = "bower"
debian = "debian"
pypi = "pypi"
docker = "docker"
yum = "yum"
vcs = "vcs"
composer = "composer"
go = "go"
p2 = "p2"
chef = "chef"
puppet = "puppet"
generic = "generic"
conan = "conan"
alpine = "alpine"
gitlfs = "gitlfs"
vagrant = "vagrant"
conda = "conda"
# Additional package types below
cargo = "cargo"
Alternatively, we could turn each of these enum variants into a class and then define a new type as
BasePackageType = Union[MavenPackageType, ..., CondaPackageType]
ExtendedPackageType = Union[MavenPackageType, ..., CondaPackageType, CargoPackageType]
Or, back to the drawing board, we can make this a runtime rather than compile-time concern.
What do you think, @anancarv ?
Ping, @anancarv . Any opinions on this?
Hi @uschi2000 ,
After having thought about it, I think we can accept your first contribution. Indeed, adding new enums will increase the code duplication and it can be hard to maintain afterwards. I'll just need to check what http error is thrown by the user trying to create a Cargo
virtualRepository to see if it's understandable by the user making the request
Sounds good, @anancarv . I'll run this against a real artifactory instance to check what the error is.
I tested on our SaaS Artifactory instance, and... no error is returned from the API :sweat_smile: With the following code
art = Artifactory("https://artifactory.example", ("username", "api key"))
repo = VirtualRepository(key="test-nymous-cargo", packageType=PackageTypeEnum.cargo)
print(repo)
print(art.repositories.create_repo(repo))
The code doesn't error, the API is happy, the repository is created and visible in the "Virtual repositories" list... But if you try to click on it to edit its configuration the UI goes "Nope, error 500".
https://user-images.githubusercontent.com/4216559/147482035-674544d9-e92b-4f2e-89bb-3b005c748687.mp4
(And as a side note, the UI to create a virtual repository confirms that Cargo is not supported, as it is not listed.)
And regarding the issue of not being able to subclass enums, I have a (breaking) suggestion: how about using Literals? The IDE support is a bit poorer (I think Pycharm and VSCode don't autocomplete supported values when you call the function), but Literals are still typed and can be composed. See this simplified example:
from typing import Literal, Union
BasePackageType = Literal["maven", "gradle", "debian", "helm", "generic"]
class VirtualRepository:
packageType: BasePackageType = "generic"
class LocalRepository:
packageType: Union[BasePackageType, Literal["cargo"]] = "generic"
reveal_type(VirtualRepository.packageType)
# Revealed type is "Union[Literal['maven'], Literal['gradle'], Literal['debian'], Literal['helm'], Literal['generic']]"
reveal_type(LocalRepository.packageType)
# Revealed type is "Union[Literal['maven'], Literal['gradle'], Literal['debian'], Literal['helm'], Literal['generic'], Literal['cargo']]"
Using Literal is a great feature, but will be a breaking change as you said. We can keep it as a future improvement of the package. For now, let's just accept the PR as it is.
Cheers @anancarv . Could you also carve a release please?
Description
Add support for creating Cargo repositories
Type of change
Please delete options that are not relevant.
How has it been tested ?
Checklist: