mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 10:07:14 +02:00
Install development platform from local dir and VCS(git, hg, svn) // Issue #479
This commit is contained in:
@ -196,6 +196,31 @@ General options
|
||||
|
||||
:ref:`platforms` name.
|
||||
|
||||
PlatformIO allows to use specific platform versions using
|
||||
`Semantic Versioning <http://semver.org>`_ (X.Y.Z=MAJOR.MINOR.PATCH).
|
||||
Version specifications can take any of the following forms:
|
||||
|
||||
* ``0.1.2``: an exact version number. Use only this exact version
|
||||
* ``^0.1.2``: any compatible version (exact version for ``0.x.x`` versions
|
||||
* ``~0.1.2``: any version with the same major and minor versions, and an
|
||||
equal or greater patch version
|
||||
* ``>0.1.2``: any version greater than ``0.1.2``. ``>=``, ``<``, and ``<=``
|
||||
are also possible
|
||||
* ``>0.1.0,!=0.2.0,<0.3.0``: any version greater than ``0.1.0``, not equal to
|
||||
``0.2.0`` and less than ``0.3.0``
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[env:the_latest_version]
|
||||
platform = atmelavr
|
||||
|
||||
[env:specific_major_version]
|
||||
platform = atmelavr@^0.1.2
|
||||
|
||||
[env:specific_major_and_minor_version]
|
||||
platform = atmelavr@~0.1.2
|
||||
|
||||
.. _projectconf_env_framework:
|
||||
|
||||
|
@ -22,22 +22,90 @@ Usage
|
||||
.. code-block:: bash
|
||||
|
||||
# install platform by name
|
||||
platformio platform install [OPTIONS] [PLATFORMS]
|
||||
platformio platform install [OPTIONS] PLATFORM
|
||||
|
||||
# install platform from local directory
|
||||
platformio platform install [OPTIONS] [file:///local/path/to/platform/dir]
|
||||
# install specific platform version using Semantic Versioning
|
||||
platformio platform install [OPTIONS] PLATFORM@X.Y.Z
|
||||
|
||||
# install platform using URL
|
||||
platformio platform install [OPTIONS] URL
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Install development :ref:`platforms` and dependent packages.
|
||||
Install :ref:`platforms` and dependent packages.
|
||||
|
||||
There are several predefined aliases for packages, such as:
|
||||
|
||||
* ``framework``
|
||||
* ``toolchain``
|
||||
* ``uploader``
|
||||
|
||||
Local
|
||||
~~~~~
|
||||
|
||||
PlatformIO supports installing development platform from local directory. Here
|
||||
is supported form:
|
||||
|
||||
* file:///local/path/to/the/platform/dir
|
||||
|
||||
VCS
|
||||
~~~
|
||||
|
||||
PlatformIO supports installing from Git, Mercurial and Subversion, and detects
|
||||
the type of VCS using url prefixes: "git+", "hg+", or "svn+".
|
||||
|
||||
PlatformIO requires a working VCS command on your path: git, hg or svn.
|
||||
|
||||
Git
|
||||
^^^
|
||||
|
||||
The supported schemes are: ``git``, ``git+https`` and ``git+ssh``. Here are
|
||||
the supported forms:
|
||||
|
||||
* https://github.com/platformio/platform-NAME.git
|
||||
* git+git://git.server.org/my-platform
|
||||
* git+https://git.server.org/my-platform
|
||||
* git+ssh://git.server.org/my-platform
|
||||
|
||||
Passing branch names, a commit hash or a tag name is possible like so:
|
||||
|
||||
* https://github.com/platformio/platform-name.git#master
|
||||
* git+git://git.server.org/my-platform#master
|
||||
* git+https://git.server.org/my-platform#v1.0
|
||||
* git+ssh://git.server.org/my-platform#7846d8ad52f983f2f2887bdc0f073fe9755a806d
|
||||
|
||||
Mercurial
|
||||
^^^^^^^^^
|
||||
|
||||
The supported schemes are: ``hg+http``, ``hg+https`` and ``hg+ssh``. Here are
|
||||
the supported forms:
|
||||
|
||||
* hg+hg://hg.server.org/my-platform
|
||||
* hg+https://hg.server.org/my-platform
|
||||
* hg+ssh://hg.server.org/my-platform
|
||||
|
||||
Passing branch names, a commit hash or a tag name is possible like so:
|
||||
|
||||
* hg+hg://hg.server.org/my-platform#master
|
||||
* hg+https://hg.server.org/my-platform#v1.0
|
||||
* hg+ssh://hg.server.org/my-platform#4cfe2fa00668
|
||||
|
||||
Subversion
|
||||
^^^^^^^^^^
|
||||
|
||||
The supported schemes are: ``svn``, ``svn+svn``, ``svn+http``, ``svn+https``
|
||||
and ``svn+ssh``. Here are the supported forms:
|
||||
|
||||
* svn+svn://svn.server.org/my-platform
|
||||
* svn+https://svn.server.org/my-platform
|
||||
* svn+ssh://svn.server.org/my-platform
|
||||
|
||||
You can also give specific revisions to an SVN URL, like so:
|
||||
|
||||
* svn+svn://svn.server.org/my-platform#13
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
@ -62,30 +130,68 @@ Skip default packages
|
||||
Examples
|
||||
--------
|
||||
|
||||
1. Install :ref:`platform_timsp430` with default packages
|
||||
1. Install :ref:`platform_atmelavr` with default packages
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ platformio platform install timsp430
|
||||
Installing toolchain-timsp430 package:
|
||||
$ platformio platform install atmelavr
|
||||
Installing platform atmelavr @ latest:
|
||||
Downloading...
|
||||
Unpacking [####################################] 100%
|
||||
Installing package tool-scons @ >=2.3.0,<2.6.0:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
Installing tool-mspdebug package:
|
||||
Installing package toolchain-atmelavr @ ~1.40801.0:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
Installing framework-energiamsp430 package:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
The platform 'timsp430' has been successfully installed!
|
||||
The platform 'atmelavr' has been successfully installed!
|
||||
The rest of packages will be installed automatically depending on your build environment.
|
||||
|
||||
|
||||
2. Install :ref:`platform_timsp430` with ``uploader`` utility only and skip
|
||||
2. Install :ref:`platform_atmelavr` with ``uploader`` utility only and skip
|
||||
default packages
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ platformio platform install timsp430 --skip-default-package --with-package=uploader
|
||||
Installing tool-mspdebug package:
|
||||
$ platformio platform install atmelavr --skip-default-package --with-package=uploader
|
||||
Installing platform atmelavr @ latest:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
The platform 'timsp430' has been successfully installed!
|
||||
Installing package tool-micronucleus @ ~1.200.0:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
Installing package tool-avrdude @ >=1.60001.0,<1.60101.0:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
The platform 'atmelavr' has been successfully installed!
|
||||
The rest of packages will be installed automatically depending on your build environment.
|
||||
|
||||
3. Install the latest development :ref:`platform_atmelavr` from Git repository
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ platformio platform install https://github.com/platformio/platform-atmelavr.git
|
||||
Installing platform https://github.com/platformio/platform-atmelavr.git @ latest:
|
||||
git version 2.7.4 (Apple Git-66)
|
||||
Cloning into '/Users/ikravets/.platformio/platforms/installing-XMIsAE-package'...
|
||||
remote: Counting objects: 172, done.
|
||||
remote: Compressing objects: 100% (51/51), done.
|
||||
remote: Total 172 (delta 109), reused 168 (delta 109), pack-reused 0
|
||||
Receiving objects: 100% (172/172), 38.18 KiB | 0 bytes/s, done.
|
||||
Resolving deltas: 100% (109/109), done.
|
||||
Checking connectivity... done.
|
||||
Submodule 'examples/arduino-external-libs/lib/OneWire' (https://github.com/PaulStoffregen/OneWire.git) registered for path 'examples/arduino-external-libs/lib/OneWire'
|
||||
Cloning into 'examples/arduino-external-libs/lib/OneWire'...
|
||||
remote: Counting objects: 87, done.
|
||||
remote: Total 87 (delta 0), reused 0 (delta 0), pack-reused 87
|
||||
Unpacking objects: 100% (87/87), done.
|
||||
Checking connectivity... done.
|
||||
Submodule path 'examples/arduino-external-libs/lib/OneWire': checked out '57c18c6de80c13429275f70875c7c341f1719201'
|
||||
Installing package tool-scons @ >=2.3.0,<2.6.0:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
Installing package toolchain-atmelavr @ ~1.40801.0:
|
||||
Downloading [####################################] 100%
|
||||
Unpacking [####################################] 100%
|
||||
The platform 'https://github.com/platformio/platform-atmelavr.git' has been successfully installed!
|
||||
The rest of packages will be installed automatically depending on your build environment.
|
||||
|
@ -23,6 +23,9 @@ Usage
|
||||
|
||||
platformio platform uninstall PLATFORM
|
||||
|
||||
# uninstall specific platform version using Semantic Versioning
|
||||
platformio platform uninstall PLATFORM@X.Y.Z
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
@ -35,8 +38,8 @@ Examples
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ platformio platform uninstall timsp430
|
||||
Uninstalling toolchain-timsp430 package: [OK]
|
||||
Uninstalling tool-mspdebug package: [OK]
|
||||
Uninstalling framework-energiamsp430 package: [OK]
|
||||
The platform 'timsp430' has been successfully uninstalled!
|
||||
$ platformio platform uninstall atmelavr
|
||||
Uninstalling platform atmelavr @ latest: [OK]
|
||||
Uninstalling package tool-scons @ 2.5.0: [OK]
|
||||
Uninstalling package toolchain-atmelavr @ 1.40801.0: [OK]
|
||||
The platform 'atmelavr' has been successfully uninstalled!
|
||||
|
@ -46,75 +46,53 @@ Examples
|
||||
.. code-block:: bash
|
||||
|
||||
$ platformio platform update
|
||||
|
||||
Platform atmelavr
|
||||
Platform atmelavr @ 0.0.0
|
||||
--------
|
||||
Updating toolchain-atmelavr package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating tool-avrdude package:
|
||||
Versions: Current=2, Latest=2 [Up-to-date]
|
||||
Updating framework-arduinoavr package:
|
||||
Versions: Current=12, Latest=12 [Up-to-date]
|
||||
Updating tool-micronucleus package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating platform atmelavr @ latest:
|
||||
Versions: Current=0.0.0, Latest=0.0.0 [Up-to-date]
|
||||
Updating package framework-arduinoavr @ ~1.10608.0:
|
||||
Versions: Current=1.10608.0, Latest=1.10608.0 [Up-to-date]
|
||||
Updating package toolchain-atmelavr @ ~1.40801.0:
|
||||
Versions: Current=1.40801.0, Latest=1.40801.0 [Up-to-date]
|
||||
Updating package framework-simba @ ~1.500.0:
|
||||
Versions: Current=1.500.0, Latest=1.500.0 [Up-to-date]
|
||||
Updating package tool-scons @ >=2.3.0,<2.6.0:
|
||||
Versions: Current=2.5.0, Latest=2.5.0 [Up-to-date]
|
||||
|
||||
Platform atmelsam
|
||||
Platform atmelsam @ 0.0.0
|
||||
--------
|
||||
Updating framework-arduinosam package:
|
||||
Versions: Current=3, Latest=3 [Up-to-date]
|
||||
Updating ldscripts package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating toolchain-gccarmnoneeabi package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating tool-bossac package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating platform atmelsam @ latest:
|
||||
Versions: Current=0.0.0, Latest=0.0.0 [Up-to-date]
|
||||
Updating package toolchain-gccarmnoneeabi @ >=1.40803.0,<1.40805.0:
|
||||
Versions: Current=1.40804.0, Latest=1.40804.0 [Up-to-date]
|
||||
Updating package framework-arduinosam @ ~1.10607.0:
|
||||
Versions: Current=1.10607.0, Latest=1.10607.0 [Up-to-date]
|
||||
Updating package framework-simba @ ~1.500.0:
|
||||
Versions: Current=1.500.0, Latest=1.500.0 [Up-to-date]
|
||||
Updating package framework-mbed @ ~1.117.0:
|
||||
Versions: Current=1.117.0, Latest=1.117.0 [Up-to-date]
|
||||
Updating package tool-scons @ >=2.3.0,<2.6.0:
|
||||
Versions: Current=2.5.0, Latest=2.5.0 [Up-to-date]
|
||||
Updating package tool-bossac @ ~1.10500.0:
|
||||
Versions: Current=1.10500.0, Latest=1.10500.0 [Up-to-date]
|
||||
|
||||
Platform stm32
|
||||
Platform espressif @ 0.0.0
|
||||
--------
|
||||
Updating toolchain-gccarmnoneeabi package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating tool-stlink package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating framework-spl package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating framework-cmsis package:
|
||||
Versions: Current=2, Latest=2 [Up-to-date]
|
||||
Updating framework-opencm3 package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating ldscripts package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating platform espressif @ latest:
|
||||
Versions: Current=0.0.0, Latest=0.0.0 [Up-to-date]
|
||||
Updating package tool-scons @ >=2.3.0,<2.6.0:
|
||||
Versions: Current=2.5.0, Latest=2.5.0 [Up-to-date]
|
||||
Updating package toolchain-xtensa @ ~1.40802.0:
|
||||
Versions: Current=1.40802.0, Latest=1.40802.0 [Up-to-date]
|
||||
Updating package framework-simba @ ~1.500.0:
|
||||
Versions: Current=1.500.0, Latest=1.500.0 [Up-to-date]
|
||||
Updating package tool-esptool @ ~1.408.0:
|
||||
Versions: Current=1.408.0, Latest=1.408.0 [Up-to-date]
|
||||
Updating package tool-mkspiffs @ ~1.102.0:
|
||||
Versions: Current=1.102.0, Latest=1.102.0 [Up-to-date]
|
||||
Updating package framework-arduinoespressif @ ~1.20200.0:
|
||||
Versions: Current=1.20200.0, Latest=1.20200.0 [Up-to-date]
|
||||
Updating package sdk-esp8266 @ ~1.10502.0:
|
||||
Versions: Current=1.10502.0, Latest=1.10502.0 [Up-to-date]
|
||||
|
||||
Platform teensy
|
||||
--------
|
||||
Updating toolchain-atmelavr package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating ldscripts package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating framework-arduinoteensy package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating toolchain-gccarmnoneeabi package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating tool-teensy package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
|
||||
Platform timsp430
|
||||
--------
|
||||
Updating toolchain-timsp430 package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating tool-mspdebug package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating framework-energiamsp430 package:
|
||||
Versions: Current=2, Latest=2 [Up-to-date]
|
||||
|
||||
Platform titiva
|
||||
--------
|
||||
Updating ldscripts package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating toolchain-gccarmnoneeabi package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating tool-lm4flash package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating framework-opencm3 package:
|
||||
Versions: Current=1, Latest=1 [Up-to-date]
|
||||
Updating framework-energiativa package:
|
||||
Versions: Current=4, Latest=4 [Up-to-date]
|
||||
...
|
||||
|
@ -205,7 +205,8 @@ class EnvironmentProcessor(object):
|
||||
try:
|
||||
p = PlatformFactory.newPlatform(platform, version)
|
||||
except exception.UnknownPlatform:
|
||||
self.cmd_ctx.invoke(cmd_platform_install, platforms=[platform])
|
||||
self.cmd_ctx.invoke(
|
||||
cmd_platform_install, platforms=[self.options['platform']])
|
||||
p = PlatformFactory.newPlatform(platform, version)
|
||||
|
||||
return p.run(build_vars, build_targets, self.verbose_level)
|
||||
|
@ -70,11 +70,6 @@ class UnknownPackage(PlatformioException):
|
||||
MESSAGE = "Detected unknown package '{0}'"
|
||||
|
||||
|
||||
class InvalidLocalPackage(PlatformioException):
|
||||
|
||||
MESSAGE = "Invalid local package '{0}'. Can not find manifest '{1}'"
|
||||
|
||||
|
||||
class UndefinedPackageVersion(PlatformioException):
|
||||
|
||||
MESSAGE = "Can not find package '{0}' with version requirements '{1}'"\
|
||||
|
@ -15,6 +15,7 @@
|
||||
import os
|
||||
from os.path import dirname, isdir, isfile, islink, join
|
||||
from shutil import copyfile, copytree, rmtree
|
||||
from tempfile import mkdtemp
|
||||
|
||||
import click
|
||||
import requests
|
||||
@ -23,6 +24,7 @@ import semantic_version
|
||||
from platformio import exception, telemetry, util
|
||||
from platformio.downloader import FileDownloader
|
||||
from platformio.unpacker import FileUnpacker
|
||||
from platformio.vcsclient import VCSClientFactory
|
||||
|
||||
|
||||
class PackageManager(object):
|
||||
@ -87,32 +89,6 @@ class PackageManager(object):
|
||||
"Could not find '%s' manifest file in the package" %
|
||||
self.manifest_name)
|
||||
|
||||
def make_pkg_dir(self, name, version):
|
||||
pkg_dir = join(self.package_dir, name)
|
||||
if isfile(join(pkg_dir, self.manifest_name)):
|
||||
manifest = util.load_json(
|
||||
join(pkg_dir, self.manifest_name))
|
||||
|
||||
cmp_result = semantic_version.compare(version, manifest['version'])
|
||||
if cmp_result == 1:
|
||||
# if main package version < new package, backup it
|
||||
print pkg_dir, join(
|
||||
self.package_dir, "%s@%s" % (name, manifest['version']))
|
||||
os.rename(pkg_dir, join(
|
||||
self.package_dir, "%s@%s" % (name, manifest['version'])))
|
||||
elif cmp_result == -1:
|
||||
pkg_dir = join(
|
||||
self.package_dir, "%s@%s" % (name, version))
|
||||
|
||||
# remove previous/not-satisfied package
|
||||
if isdir(pkg_dir):
|
||||
rmtree(pkg_dir)
|
||||
os.makedirs(pkg_dir)
|
||||
assert isdir(pkg_dir)
|
||||
|
||||
self.reset_cache()
|
||||
return pkg_dir
|
||||
|
||||
@staticmethod
|
||||
def max_satisfying_repo_version(versions, requirements=None):
|
||||
item = None
|
||||
@ -196,12 +172,11 @@ class PackageManager(object):
|
||||
return self.max_satisfying_version(
|
||||
name, requirements).get("_manifest_path")
|
||||
|
||||
manifest_path = None
|
||||
if name.startswith("file://"):
|
||||
manifest_path = self._install_from_local_dir(name[7:])
|
||||
if "://" in name:
|
||||
pkg_dir = self._install_from_url(name, requirements)
|
||||
else:
|
||||
manifest_path = self._install_from_piorepo(name, requirements)
|
||||
if not isfile(manifest_path):
|
||||
pkg_dir = self._install_from_piorepo(name, requirements)
|
||||
if not pkg_dir or not isfile(join(pkg_dir, self.manifest_name)):
|
||||
raise exception.PackageInstallError(
|
||||
name, requirements or "latest", util.get_systype())
|
||||
|
||||
@ -210,32 +185,23 @@ class PackageManager(object):
|
||||
telemetry.on_event(
|
||||
category="PackageManager", action="Install", label=name)
|
||||
|
||||
return manifest_path
|
||||
return join(pkg_dir, self.manifest_name)
|
||||
|
||||
def _install_from_piorepo(self, name, requirements):
|
||||
pkg_dir = None
|
||||
pkgdata = None
|
||||
versions = None
|
||||
for versions in PackageRepoIterator(name, self.repositories):
|
||||
dlpath = None
|
||||
pkgdata = self.max_satisfying_repo_version(versions, requirements)
|
||||
if not pkgdata:
|
||||
continue
|
||||
|
||||
pkg_dir = self.make_pkg_dir(name, pkgdata['version'])
|
||||
try:
|
||||
dlpath = self.download(
|
||||
pkgdata['url'], pkg_dir, pkgdata.get("sha1"))
|
||||
assert isfile(dlpath)
|
||||
self.unpack(dlpath, pkg_dir)
|
||||
self.check_structure(pkg_dir)
|
||||
pkg_dir = self._install_from_url(
|
||||
pkgdata['url'], requirements, pkgdata.get("sha1"))
|
||||
break
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
click.secho("Warning! Package Mirror: %s" % e, fg="yellow")
|
||||
click.secho("Looking for another mirror...", fg="yellow")
|
||||
finally:
|
||||
if dlpath and isfile(dlpath):
|
||||
os.remove(dlpath)
|
||||
|
||||
if versions is None:
|
||||
raise exception.UnknownPackage(name)
|
||||
@ -246,21 +212,64 @@ class PackageManager(object):
|
||||
else:
|
||||
raise exception.UndefinedPackageVersion(
|
||||
name, requirements or "latest", util.get_systype())
|
||||
return pkg_dir
|
||||
|
||||
return join(pkg_dir, self.manifest_name)
|
||||
def _install_from_url(self, url, requirements=None, sha1=None):
|
||||
pkg_dir = None
|
||||
tmp_dir = mkdtemp("-package", "installing-", self.package_dir)
|
||||
|
||||
def _install_from_local_dir(self, local_dir):
|
||||
if not isfile(join(local_dir, self.manifest_name)):
|
||||
raise exception.InvalidLocalPackage(
|
||||
local_dir, self.manifest_name)
|
||||
# Handle GitHub URL (https://github.com/user/repo.git)
|
||||
if url.endswith(".git") and not url.startswith("git"):
|
||||
url = "git+" + url
|
||||
|
||||
manifest = util.load_json(join(local_dir, self.manifest_name))
|
||||
assert set(["name", "version"]) <= set(manifest.keys())
|
||||
pkg_dir = self.make_pkg_dir(manifest['name'], manifest['version'])
|
||||
rmtree(pkg_dir)
|
||||
copytree(local_dir, pkg_dir, symlinks=True)
|
||||
try:
|
||||
if url.startswith("file://"):
|
||||
rmtree(tmp_dir)
|
||||
copytree(url[7:], tmp_dir)
|
||||
elif url.startswith(("http://", "https://", "ftp://")):
|
||||
dlpath = self.download(url, tmp_dir, sha1)
|
||||
assert isfile(dlpath)
|
||||
self.unpack(dlpath, tmp_dir)
|
||||
os.remove(dlpath)
|
||||
else:
|
||||
repo = VCSClientFactory.newClient(url)
|
||||
repo.export(tmp_dir)
|
||||
|
||||
return join(pkg_dir, self.manifest_name)
|
||||
self.check_structure(tmp_dir)
|
||||
pkg_dir = self._install_from_tmp_dir(tmp_dir, requirements)
|
||||
finally:
|
||||
if isdir(tmp_dir):
|
||||
rmtree(tmp_dir)
|
||||
return pkg_dir
|
||||
|
||||
def _install_from_tmp_dir(self, tmp_dir, requirements=None):
|
||||
tmpmanifest = util.load_json(join(tmp_dir, self.manifest_name))
|
||||
assert set(["name", "version"]) <= set(tmpmanifest.keys())
|
||||
name = tmpmanifest['name']
|
||||
|
||||
# package should satisfy requirements
|
||||
if requirements:
|
||||
assert semantic_version.match(requirements, tmpmanifest['version'])
|
||||
|
||||
pkg_dir = join(self.package_dir, name)
|
||||
if isfile(join(pkg_dir, self.manifest_name)):
|
||||
manifest = util.load_json(join(pkg_dir, self.manifest_name))
|
||||
cmp_result = semantic_version.compare(
|
||||
tmpmanifest['version'], manifest['version'])
|
||||
if cmp_result == 1:
|
||||
# if main package version < new package, backup it
|
||||
os.rename(pkg_dir, join(
|
||||
self.package_dir, "%s@%s" % (name, manifest['version'])))
|
||||
elif cmp_result == -1:
|
||||
pkg_dir = join(
|
||||
self.package_dir, "%s@%s" % (name, tmpmanifest['version']))
|
||||
|
||||
# remove previous/not-satisfied package
|
||||
if isdir(pkg_dir):
|
||||
rmtree(pkg_dir)
|
||||
os.rename(tmp_dir, pkg_dir)
|
||||
assert isdir(pkg_dir)
|
||||
return pkg_dir
|
||||
|
||||
def uninstall(self, name, requirements=None, trigger_event=True):
|
||||
click.echo("Uninstalling %s %s @ %s: \t" % (
|
||||
|
@ -44,25 +44,26 @@ class PlatformManager(PackageManager):
|
||||
name, requirements=None, with_packages=None,
|
||||
without_packages=None, skip_default_packages=False):
|
||||
manifest_path = PackageManager.install(self, name, requirements)
|
||||
PlatformFactory.newPlatform(
|
||||
manifest_path, requirements).install_packages(
|
||||
with_packages, without_packages, skip_default_packages)
|
||||
self.cleanup_packages()
|
||||
p = PlatformFactory.newPlatform(manifest_path, requirements)
|
||||
p.install_packages(
|
||||
with_packages, without_packages, skip_default_packages)
|
||||
self.cleanup_packages(p.packages.keys())
|
||||
return True
|
||||
|
||||
def uninstall(self, # pylint: disable=arguments-differ
|
||||
name, requirements=None):
|
||||
p = PlatformFactory.newPlatform(name, requirements)
|
||||
PackageManager.uninstall(self, name, requirements)
|
||||
self.cleanup_packages()
|
||||
self.cleanup_packages(p.packages.keys())
|
||||
return True
|
||||
|
||||
def update(self, # pylint: disable=arguments-differ
|
||||
name, requirements=None, only_packages=False):
|
||||
if not only_packages:
|
||||
PackageManager.update(self, name)
|
||||
PlatformFactory.newPlatform(
|
||||
name, requirements).update_packages()
|
||||
self.cleanup_packages()
|
||||
p = PlatformFactory.newPlatform(name, requirements)
|
||||
p.update_packages()
|
||||
self.cleanup_packages(p.packages.keys())
|
||||
return True
|
||||
|
||||
def is_outdated(self, name, requirements=None):
|
||||
@ -70,7 +71,7 @@ class PlatformManager(PackageManager):
|
||||
return (p.are_outdated_packages() or
|
||||
p.version != self.get_latest_repo_version(name, requirements))
|
||||
|
||||
def cleanup_packages(self):
|
||||
def cleanup_packages(self, names):
|
||||
self.reset_cache()
|
||||
deppkgs = {}
|
||||
for manifest in PlatformManager().get_installed():
|
||||
@ -83,9 +84,10 @@ class PlatformManager(PackageManager):
|
||||
|
||||
pm = PackageManager()
|
||||
for manifest in pm.get_installed():
|
||||
if manifest['name'] not in deppkgs:
|
||||
if manifest['name'] not in names:
|
||||
continue
|
||||
if manifest['version'] not in deppkgs[manifest['name']]:
|
||||
if (manifest['name'] not in deppkgs or
|
||||
manifest['version'] not in deppkgs[manifest['name']]):
|
||||
pm.uninstall(
|
||||
manifest['name'], manifest['version'], trigger_event=False)
|
||||
|
||||
|
97
platformio/vcsclient.py
Normal file
97
platformio/vcsclient.py
Normal file
@ -0,0 +1,97 @@
|
||||
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from platform import system
|
||||
from subprocess import check_call
|
||||
from sys import modules
|
||||
from urlparse import urlsplit, urlunsplit
|
||||
|
||||
from platformio.exception import PlatformioException
|
||||
|
||||
|
||||
class VCSClientFactory(object):
|
||||
|
||||
@staticmethod
|
||||
def newClient(url):
|
||||
scheme, netloc, path, query, fragment = urlsplit(url)
|
||||
type_ = scheme
|
||||
if "+" in type_:
|
||||
type_, scheme = type_.split("+", 1)
|
||||
url = urlunsplit((scheme, netloc, path, query, None))
|
||||
clsname = "%sClient" % type_.title()
|
||||
obj = getattr(modules[__name__], clsname)(url, fragment)
|
||||
assert isinstance(obj, VCSClientBase)
|
||||
return obj
|
||||
|
||||
|
||||
class VCSClientBase(object):
|
||||
|
||||
command = None
|
||||
|
||||
def __init__(self, url, branch=None):
|
||||
self.url = url
|
||||
self.branch = branch
|
||||
self.check_client()
|
||||
|
||||
def check_client(self):
|
||||
try:
|
||||
assert self.command
|
||||
assert self.run_cmd(["--version"]) == 0
|
||||
except (AssertionError, OSError):
|
||||
raise PlatformioException(
|
||||
"VCS: `%s` client is not installed in your system" %
|
||||
self.command)
|
||||
return True
|
||||
|
||||
def export(self, dst_dir):
|
||||
raise NotImplementedError
|
||||
|
||||
def run_cmd(self, args):
|
||||
return check_call([self.command] + args, shell=system() == "Windows")
|
||||
|
||||
|
||||
class GitClient(VCSClientBase):
|
||||
|
||||
command = "git"
|
||||
|
||||
def export(self, dst_dir):
|
||||
args = ["clone", "--recursive", "--depth", "1"]
|
||||
if self.branch:
|
||||
args.extend(["--branch", self.branch])
|
||||
args.extend([self.url, dst_dir])
|
||||
self.run_cmd(args)
|
||||
|
||||
|
||||
class HgClient(VCSClientBase):
|
||||
|
||||
command = "hg"
|
||||
|
||||
def export(self, dst_dir):
|
||||
args = ["clone"]
|
||||
if self.branch:
|
||||
args.extend(["--updaterev", self.branch])
|
||||
args.extend([self.url, dst_dir])
|
||||
self.run_cmd(args)
|
||||
|
||||
|
||||
class SvnClient(VCSClientBase):
|
||||
|
||||
command = "svn"
|
||||
|
||||
def export(self, dst_dir):
|
||||
args = ["export", "--force"]
|
||||
if self.branch:
|
||||
args.extend(["--revision", self.branch])
|
||||
args.extend([self.url, dst_dir])
|
||||
self.run_cmd(args)
|
Reference in New Issue
Block a user