forked from platformio/platformio-core
Added support for “scripts” in package manifest // Resolve #485
This commit is contained in:
1 parent
d8be12dcdd
commit
8de5db4b48
9 files changed
+108
-11
No files matched your search
@@ -102,6 +102,8 @@ class PackageManagerInstallMixin(object):
|
||||
% (spec.humanize(), util.get_systype())
|
||||
)
|
||||
|
||||
self.call_pkg_script(pkg, "postinstall")
|
||||
|
||||
self.log.info(
|
||||
click.style(
|
||||
"{name}@{version} has been installed!".format(**pkg.metadata.as_dict()),
|
||||
|
||||
@@ -40,6 +40,8 @@ class PackageManagerUninstallMixin(object):
|
||||
% (click.style(pkg.metadata.name, fg="cyan"), pkg.metadata.version)
|
||||
)
|
||||
|
||||
self.call_pkg_script(pkg, "preuninstall")
|
||||
|
||||
# firstly, remove dependencies
|
||||
if not skip_dependencies:
|
||||
self.uninstall_dependencies(pkg)
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
import click
|
||||
import semantic_version
|
||||
|
||||
from platformio import util
|
||||
from platformio import fs, util
|
||||
from platformio.commands import PlatformioCLI
|
||||
from platformio.compat import ci_strings_are_equal
|
||||
from platformio.package.exception import ManifestException, MissingPackageManifestError
|
||||
@@ -37,6 +38,7 @@ from platformio.package.meta import (
|
||||
PackageSpec,
|
||||
PackageType,
|
||||
)
|
||||
from platformio.proc import get_pythonexe_path
|
||||
from platformio.project.helpers import get_project_cache_dir
|
||||
|
||||
|
||||
@@ -302,3 +304,31 @@ class BasePackageManager( # pylint: disable=too-many-public-methods,too-many-in
|
||||
name=dependency.get("name"),
|
||||
requirements=dependency.get("version"),
|
||||
)
|
||||
|
||||
def call_pkg_script(self, pkg, event):
|
||||
manifest = None
|
||||
try:
|
||||
manifest = self.load_manifest(pkg)
|
||||
except MissingPackageManifestError:
|
||||
pass
|
||||
scripts = (manifest or {}).get("scripts")
|
||||
if not scripts or not isinstance(scripts, dict):
|
||||
return
|
||||
cmd = scripts.get(event)
|
||||
if not cmd:
|
||||
return
|
||||
shell = False
|
||||
if not isinstance(cmd, list):
|
||||
shell = True
|
||||
cmd = [cmd]
|
||||
os.environ["PIO_PYTHON_EXE"] = get_pythonexe_path()
|
||||
with fs.cd(pkg.path):
|
||||
if os.path.isfile(cmd[0]) and cmd[0].endswith(".py"):
|
||||
cmd = [os.environ["PIO_PYTHON_EXE"]] + cmd
|
||||
subprocess.run(
|
||||
" ".join(cmd) if shell else cmd,
|
||||
cwd=pkg.path,
|
||||
shell=shell,
|
||||
env=os.environ,
|
||||
check=True,
|
||||
)
|
||||
@@ -152,6 +152,21 @@ class ExampleSchema(StrictSchema):
|
||||
files = StrictListField(fields.Str, required=True)
|
||||
|
||||
|
||||
# Fields
|
||||
|
||||
|
||||
class ScriptField(fields.Field):
|
||||
def _deserialize(self, value, attr, data, **kwargs):
|
||||
if isinstance(value, (str, list)):
|
||||
return value
|
||||
raise ValidationError(
|
||||
"Script value must be a command (string) or list of arguments"
|
||||
)
|
||||
|
||||
|
||||
# Scheme
|
||||
|
||||
|
||||
class ManifestSchema(BaseSchema):
|
||||
# Required fields
|
||||
name = fields.Str(
|
||||
@@ -173,6 +188,10 @@ class ManifestSchema(BaseSchema):
|
||||
license = fields.Str(validate=validate.Length(min=1, max=255))
|
||||
repository = fields.Nested(RepositorySchema)
|
||||
dependencies = fields.Nested(DependencySchema, many=True)
|
||||
scripts = fields.Dict(
|
||||
keys=fields.Str(validate=validate.OneOf(["postinstall", "preuninstall"])),
|
||||
values=ScriptField(),
|
||||
)
|
||||
|
||||
# library.json
|
||||
export = fields.Nested(ExportSchema)
|
||||
|
||||
Reference in new issue
Block a user