forked from platformio/platformio-core
Validate package manifest when packing archive or publishing a package
This commit is contained in:
11
HISTORY.rst
11
HISTORY.rst
@ -34,6 +34,7 @@ PlatformIO Core 5
|
|||||||
* Show package details
|
* Show package details
|
||||||
* Check for conflicting names in the PlatformIO Trusted Registry
|
* Check for conflicting names in the PlatformIO Trusted Registry
|
||||||
* Check for duplicates and used version
|
* Check for duplicates and used version
|
||||||
|
* Validate package manifest
|
||||||
|
|
||||||
- Added a new option ``--non-interactive`` to `pio package publish <https://docs.platformio.org/page/core/userguide/package/cmd_publish.html>`__ command
|
- Added a new option ``--non-interactive`` to `pio package publish <https://docs.platformio.org/page/core/userguide/package/cmd_publish.html>`__ command
|
||||||
|
|
||||||
@ -235,24 +236,24 @@ Please check `Migration guide from 4.x to 5.0 <https://docs.platformio.org/page/
|
|||||||
PlatformIO Core 4
|
PlatformIO Core 4
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
See `PlatformIO Core 4.0 history <https://docs.platformio.org/en/v4.3.4/core/history.html#platformio-core-4>`__.
|
See `PlatformIO Core 4.0 history <https://github.com/platformio/platformio-core/blob/v4.3.4/HISTORY.rst>`__.
|
||||||
|
|
||||||
PlatformIO Core 3
|
PlatformIO Core 3
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
See `PlatformIO Core 3.0 history <https://docs.platformio.org/en/v4.3.4/core/history.html#platformio-core-3>`__.
|
See `PlatformIO Core 3.0 history <https://github.com/platformio/platformio-core/blob/v3.6.7/HISTORY.rst>`__.
|
||||||
|
|
||||||
PlatformIO Core 2
|
PlatformIO Core 2
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
See `PlatformIO Core 2.0 history <https://docs.platformio.org/en/v4.3.4/core/history.html#platformio-core-2>`__.
|
See `PlatformIO Core 2.0 history <https://github.com/platformio/platformio-core/blob/v2.11.2/HISTORY.rst>`__.
|
||||||
|
|
||||||
PlatformIO Core 1
|
PlatformIO Core 1
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
See `PlatformIO Core 1.0 history <https://docs.platformio.org/en/v4.3.4/core/history.html#platformio-core-1>`__.
|
See `PlatformIO Core 1.0 history <https://github.com/platformio/platformio-core/blob/v1.5.0/HISTORY.rst>`__.
|
||||||
|
|
||||||
PlatformIO Core Preview
|
PlatformIO Core Preview
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
See `PlatformIO Core Preview history <https://docs.platformio.org/en/v4.3.4/core/history.html#platformio-core-preview>`__.
|
See `PlatformIO Core Preview history <https://github.com/platformio/platformio-core/blob/v0.10.2/HISTORY.rst>`__.
|
||||||
|
@ -24,6 +24,7 @@ from platformio.clients.account import AccountClient
|
|||||||
from platformio.clients.registry import RegistryClient
|
from platformio.clients.registry import RegistryClient
|
||||||
from platformio.exception import UserSideException
|
from platformio.exception import UserSideException
|
||||||
from platformio.package.manifest.parser import ManifestParserFactory
|
from platformio.package.manifest.parser import ManifestParserFactory
|
||||||
|
from platformio.package.manifest.schema import ManifestSchema, ManifestValidationError
|
||||||
from platformio.package.meta import PackageSpec, PackageType
|
from platformio.package.meta import PackageSpec, PackageType
|
||||||
from platformio.package.pack import PackagePacker
|
from platformio.package.pack import PackagePacker
|
||||||
from platformio.package.unpack import FileUnpacker, TARArchiver
|
from platformio.package.unpack import FileUnpacker, TARArchiver
|
||||||
@ -39,6 +40,45 @@ def validate_datetime(ctx, param, value): # pylint: disable=unused-argument
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def load_manifest_from_archive(path):
|
||||||
|
return ManifestSchema().load_manifest(
|
||||||
|
ManifestParserFactory.new_from_archive(path).as_dict()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_package_duplicates(
|
||||||
|
owner, type, name, version
|
||||||
|
): # pylint: disable=redefined-builtin
|
||||||
|
items = (
|
||||||
|
RegistryClient()
|
||||||
|
.list_packages(filters=dict(types=[type], names=[name]))
|
||||||
|
.get("items")
|
||||||
|
)
|
||||||
|
if not items:
|
||||||
|
return True
|
||||||
|
# duplicated version by owner
|
||||||
|
if any(
|
||||||
|
item["owner"]["username"] == owner and item["version"]["name"] == version
|
||||||
|
for item in items
|
||||||
|
):
|
||||||
|
raise UserSideException(
|
||||||
|
"The package `%s/%s@%s` is already published in the registry"
|
||||||
|
% (owner, name, version)
|
||||||
|
)
|
||||||
|
other_owners = [
|
||||||
|
item["owner"]["username"]
|
||||||
|
for item in items
|
||||||
|
if item["owner"]["username"] != owner
|
||||||
|
]
|
||||||
|
if other_owners:
|
||||||
|
click.secho(
|
||||||
|
"\nWarning! A package with the name `%s` is already published by the next "
|
||||||
|
"owners: %s\n" % (name, ", ".join(other_owners)),
|
||||||
|
fg="yellow",
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
@click.group("package", short_help="Package manager")
|
@click.group("package", short_help="Package manager")
|
||||||
def cli():
|
def cli():
|
||||||
pass
|
pass
|
||||||
@ -57,6 +97,12 @@ def cli():
|
|||||||
def package_pack(package, output):
|
def package_pack(package, output):
|
||||||
p = PackagePacker(package)
|
p = PackagePacker(package)
|
||||||
archive_path = p.pack(output)
|
archive_path = p.pack(output)
|
||||||
|
# validate manifest
|
||||||
|
try:
|
||||||
|
load_manifest_from_archive(archive_path)
|
||||||
|
except ManifestValidationError as e:
|
||||||
|
os.remove(archive_path)
|
||||||
|
raise e
|
||||||
click.secho('Wrote a tarball to "%s"' % archive_path, fg="green")
|
click.secho('Wrote a tarball to "%s"' % archive_path, fg="green")
|
||||||
|
|
||||||
|
|
||||||
@ -107,7 +153,7 @@ def package_publish( # pylint: disable=too-many-arguments, too-many-locals
|
|||||||
archive_path = p.pack()
|
archive_path = p.pack()
|
||||||
|
|
||||||
type_ = PackageType.from_archive(archive_path)
|
type_ = PackageType.from_archive(archive_path)
|
||||||
manifest = ManifestParserFactory.new_from_archive(archive_path).as_dict()
|
manifest = load_manifest_from_archive(archive_path)
|
||||||
name = manifest.get("name")
|
name = manifest.get("name")
|
||||||
version = manifest.get("version")
|
version = manifest.get("version")
|
||||||
data = [
|
data = [
|
||||||
@ -119,7 +165,7 @@ def package_publish( # pylint: disable=too-many-arguments, too-many-locals
|
|||||||
click.echo(tabulate(data, tablefmt="plain"))
|
click.echo(tabulate(data, tablefmt="plain"))
|
||||||
|
|
||||||
# look for duplicates
|
# look for duplicates
|
||||||
_check_duplicates(owner, type_, name, version)
|
check_package_duplicates(owner, type_, name, version)
|
||||||
|
|
||||||
if not non_interactive:
|
if not non_interactive:
|
||||||
click.confirm(
|
click.confirm(
|
||||||
@ -142,37 +188,6 @@ def package_publish( # pylint: disable=too-many-arguments, too-many-locals
|
|||||||
click.secho(response.get("message"), fg="green")
|
click.secho(response.get("message"), fg="green")
|
||||||
|
|
||||||
|
|
||||||
def _check_duplicates(owner, type, name, version): # pylint: disable=redefined-builtin
|
|
||||||
items = (
|
|
||||||
RegistryClient()
|
|
||||||
.list_packages(filters=dict(types=[type], names=[name]))
|
|
||||||
.get("items")
|
|
||||||
)
|
|
||||||
if not items:
|
|
||||||
return True
|
|
||||||
# duplicated version by owner
|
|
||||||
if any(
|
|
||||||
item["owner"]["username"] == owner and item["version"]["name"] == version
|
|
||||||
for item in items
|
|
||||||
):
|
|
||||||
raise UserSideException(
|
|
||||||
"The package `%s/%s@%s` is already published in the registry"
|
|
||||||
% (owner, name, version)
|
|
||||||
)
|
|
||||||
other_owners = [
|
|
||||||
item["owner"]["username"]
|
|
||||||
for item in items
|
|
||||||
if item["owner"]["username"] != owner
|
|
||||||
]
|
|
||||||
if other_owners:
|
|
||||||
click.secho(
|
|
||||||
"\nWarning! A package with the name `%s` is already published by the next "
|
|
||||||
"owners: `%s`\n" % (name, ", ".join(other_owners)),
|
|
||||||
fg="yellow",
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command("unpublish", short_help="Remove a pushed package from the registry")
|
@cli.command("unpublish", short_help="Remove a pushed package from the registry")
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"package", required=True, metavar="[<organization>/]<pkgname>[@<version>]"
|
"package", required=True, metavar="[<organization>/]<pkgname>[@<version>]"
|
||||||
|
Reference in New Issue
Block a user