Implement custom "rmtree"; resolve issue with Windows and .git

This commit is contained in:
Ivan Kravets
2016-08-05 18:43:20 +03:00
parent c64354ebcc
commit db267513ca
6 changed files with 29 additions and 24 deletions

View File

@ -14,7 +14,7 @@
import sys import sys
VERSION = (3, 0, "0.dev20") VERSION = (3, 0, "0.dev21")
__version__ = ".".join([str(s) for s in VERSION]) __version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio" __title__ = "platformio"

View File

@ -12,16 +12,15 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import stat
from glob import glob from glob import glob
from os import chmod, getenv, makedirs, remove from os import getenv, makedirs, remove
from os.path import abspath, basename, expanduser, isdir, isfile, join from os.path import abspath, basename, expanduser, isdir, isfile, join
from shutil import copyfile, copytree, rmtree from shutil import copyfile, copytree
from tempfile import mkdtemp from tempfile import mkdtemp
import click import click
from platformio import app from platformio import app, util
from platformio.commands.init import cli as cmd_init from platformio.commands.init import cli as cmd_init
from platformio.commands.init import validate_boards from platformio.commands.init import validate_boards
from platformio.commands.run import cli as cmd_run from platformio.commands.run import cli as cmd_run
@ -119,14 +118,11 @@ def cli(ctx, # pylint: disable=R0913
ctx.invoke(cmd_run, project_dir=build_dir, verbose=verbose) ctx.invoke(cmd_run, project_dir=build_dir, verbose=verbose)
finally: finally:
if not keep_build_dir: if not keep_build_dir:
rmtree( util.rmtree_(build_dir)
build_dir,
onerror=lambda action, name, exc: (chmod(name, stat.S_IWRITE),
remove(name)))
def _clean_dir(dirpath): def _clean_dir(dirpath):
rmtree(dirpath) util.rmtree_(dirpath)
makedirs(dirpath) makedirs(dirpath)
@ -165,7 +161,7 @@ def _exclude_contents(dst_dir, patterns):
for path in contents: for path in contents:
path = abspath(path) path = abspath(path)
if isdir(path): if isdir(path):
rmtree(path) util.rmtree_(path)
elif isfile(path): elif isfile(path):
remove(path) remove(path)

View File

@ -16,7 +16,6 @@ from datetime import datetime
from hashlib import sha1 from hashlib import sha1
from os import getcwd, makedirs, walk from os import getcwd, makedirs, walk
from os.path import getmtime, isdir, isfile, join from os.path import getmtime, isdir, isfile, join
from shutil import rmtree
from time import time from time import time
import click import click
@ -234,14 +233,14 @@ def _clean_pioenvs_dir(pioenvs_dir):
if (isdir(pioenvs_dir) and if (isdir(pioenvs_dir) and
getmtime(join(util.get_project_dir(), "platformio.ini")) > getmtime(join(util.get_project_dir(), "platformio.ini")) >
getmtime(pioenvs_dir)): getmtime(pioenvs_dir)):
rmtree(pioenvs_dir) util.rmtree_(pioenvs_dir)
# check project structure # check project structure
if isdir(pioenvs_dir) and isfile(structhash_file): if isdir(pioenvs_dir) and isfile(structhash_file):
with open(structhash_file) as f: with open(structhash_file) as f:
if f.read() == proj_hash: if f.read() == proj_hash:
return return
rmtree(pioenvs_dir) util.rmtree_(pioenvs_dir)
if not isdir(pioenvs_dir): if not isdir(pioenvs_dir):
makedirs(pioenvs_dir) makedirs(pioenvs_dir)

View File

@ -15,7 +15,7 @@
import json import json
import os import os
from os.path import basename, dirname, isdir, isfile, islink, join from os.path import basename, dirname, isdir, isfile, islink, join
from shutil import copyfile, copytree, rmtree from shutil import copyfile, copytree
from tempfile import mkdtemp from tempfile import mkdtemp
import click import click
@ -159,7 +159,7 @@ class PkgInstallerMixin(object):
copytree(item_path, join(pkg_dir, item), symlinks=True) copytree(item_path, join(pkg_dir, item), symlinks=True)
# remove not used contents # remove not used contents
while True: while True:
rmtree(root) util.rmtree_(root)
root = dirname(root) root = dirname(root)
if root == pkg_dir: if root == pkg_dir:
break break
@ -205,7 +205,7 @@ class PkgInstallerMixin(object):
if isfile(url): if isfile(url):
self.unpack(url, tmp_dir) self.unpack(url, tmp_dir)
else: else:
rmtree(tmp_dir) util.rmtree_(tmp_dir)
copytree(url, tmp_dir) copytree(url, tmp_dir)
elif url.startswith(("http://", "https://")): elif url.startswith(("http://", "https://")):
dlpath = self.download(url, tmp_dir, sha1) dlpath = self.download(url, tmp_dir, sha1)
@ -228,7 +228,7 @@ class PkgInstallerMixin(object):
pkg_dir = self._install_from_tmp_dir(tmp_dir, requirements) pkg_dir = self._install_from_tmp_dir(tmp_dir, requirements)
finally: finally:
if isdir(tmp_dir): if isdir(tmp_dir):
rmtree(tmp_dir) util.rmtree_(tmp_dir)
return pkg_dir return pkg_dir
def _install_from_tmp_dir(self, tmp_dir, requirements=None): def _install_from_tmp_dir(self, tmp_dir, requirements=None):
@ -267,7 +267,7 @@ class PkgInstallerMixin(object):
# remove previous/not-satisfied package # remove previous/not-satisfied package
if isdir(pkg_dir): if isdir(pkg_dir):
rmtree(pkg_dir) util.rmtree_(pkg_dir)
os.rename(tmp_dir, pkg_dir) os.rename(tmp_dir, pkg_dir)
assert isdir(pkg_dir) assert isdir(pkg_dir)
return pkg_dir return pkg_dir
@ -478,7 +478,7 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
if islink(installed_dir): if islink(installed_dir):
os.unlink(installed_dir) os.unlink(installed_dir)
else: else:
rmtree(installed_dir) util.rmtree_(installed_dir)
click.echo("[%s]" % click.style("OK", fg="green")) click.echo("[%s]" % click.style("OK", fg="green"))

View File

@ -17,12 +17,14 @@ import functools
import json import json
import os import os
import re import re
import stat
import subprocess import subprocess
import sys import sys
from glob import glob from glob import glob
from os.path import (abspath, basename, dirname, expanduser, isdir, isfile, from os.path import (abspath, basename, dirname, expanduser, isdir, isfile,
join, splitdrive) join, splitdrive)
from platform import system, uname from platform import system, uname
from shutil import rmtree
from threading import Thread from threading import Thread
from platformio import __apiip__, __apiurl__, __version__, exception from platformio import __apiip__, __apiurl__, __version__, exception
@ -454,3 +456,12 @@ def where_is_program(program, envpath=None):
def pepver_to_semver(pepver): def pepver_to_semver(pepver):
return re.sub(r"(\.\d+)\.?(dev|a|b|rc|post)", r"\1-\2", pepver, 1) return re.sub(r"(\.\d+)\.?(dev|a|b|rc|post)", r"\1-\2", pepver, 1)
def rmtree_(path):
def _onerror(_, name, __):
os.chmod(name, stat.S_IWRITE)
os.remove(name)
return rmtree(path, onerror=_onerror)

View File

@ -15,11 +15,10 @@
from glob import glob from glob import glob
from os import listdir, walk from os import listdir, walk
from os.path import dirname, getsize, isdir, isfile, join, normpath from os.path import dirname, getsize, isdir, isfile, join, normpath
from shutil import rmtree
import pytest import pytest
from platformio.util import exec_command from platformio import util
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
@ -38,9 +37,9 @@ def pytest_generate_tests(metafunc):
@pytest.mark.examples @pytest.mark.examples
def test_run(platformio_setup, pioproject_dir): def test_run(platformio_setup, pioproject_dir):
if isdir(join(pioproject_dir, ".pioenvs")): if isdir(join(pioproject_dir, ".pioenvs")):
rmtree(join(pioproject_dir, ".pioenvs")) util.rmtree_(join(pioproject_dir, ".pioenvs"))
result = exec_command( result = util.exec_command(
["platformio", "--force", "run", "--project-dir", pioproject_dir] ["platformio", "--force", "run", "--project-dir", pioproject_dir]
) )
if result['returncode'] != 0: if result['returncode'] != 0: