Skip to content

Commit

Permalink
Remove naming conflict b/w dir names and package names
Browse files Browse the repository at this point in the history
  • Loading branch information
njgheorghita committed May 22, 2019
1 parent 1a999df commit 24bb48b
Show file tree
Hide file tree
Showing 36 changed files with 62 additions and 66 deletions.
2 changes: 1 addition & 1 deletion ethpm_cli/_utils/ipfs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ethpm.backends.ipfs import BaseIPFSBackend, InfuraIPFSBackend, LocalIPFSBackend


def get_ipfs_backend(ipfs: bool = None) -> BaseIPFSBackend:
def get_ipfs_backend(ipfs: bool = False) -> BaseIPFSBackend:
if ipfs:
return LocalIPFSBackend()
return InfuraIPFSBackend()
10 changes: 0 additions & 10 deletions ethpm_cli/_utils/terminal.py

This file was deleted.

6 changes: 5 additions & 1 deletion ethpm_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ class Config:
"""

def __init__(self, args: Namespace) -> None:
self.ipfs_backend = get_ipfs_backend(args.local_ipfs)
if "local_ipfs" in args:
self.ipfs_backend = get_ipfs_backend(args.local_ipfs)
else:
self.ipfs_backend = get_ipfs_backend()

if args.ethpm_dir is None:
self.ethpm_dir = Path.cwd() / ETHPM_DIR_NAME
if not self.ethpm_dir.is_dir():
Expand Down
7 changes: 5 additions & 2 deletions ethpm_cli/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

from ethpm_cli import CLI_ASSETS_DIR

ETHPM_DIR_NAME = "ethpm_packages"
ETHPM_ASSETS_DIR = "packages"
ETHPM_DIR_NAME = "_ethpm_packages"
IPFS_ASSETS_DIR = "ipfs"
LOCKFILE_NAME = "ethpm.lock"
SRC_DIR_NAME = "_src"


VERSION_RELEASE_ABI = json.loads((CLI_ASSETS_DIR / "1.0.1.json").read_text())[
"contract_types"
]["Log"]["abi"]
Expand Down
53 changes: 23 additions & 30 deletions ethpm_cli/install.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
from collections import namedtuple
import json
import logging
import os
from pathlib import Path
import shutil
import tempfile
from typing import Any, Dict, Iterable, Tuple
from typing import Any, Dict, Iterable, NamedTuple, Tuple

from eth_utils import to_dict, to_list, to_text
from eth_utils import to_dict, to_text, to_tuple
from eth_utils.toolz import assoc, dissoc
from ethpm.backends.ipfs import BaseIPFSBackend
from ethpm.utils.ipfs import is_ipfs_uri

from ethpm_cli._utils.terminal import get_terminal_width
from ethpm_cli.config import Config
from ethpm_cli.constants import ETHPM_DIR_NAME
from ethpm_cli.constants import ETHPM_DIR_NAME, LOCKFILE_NAME, SRC_DIR_NAME
from ethpm_cli.exceptions import InstallError
from ethpm_cli.package import Package
from ethpm_cli.validation import validate_parent_directory
Expand All @@ -38,19 +36,14 @@ def install_package(pkg: Package, config: Config) -> None:
dest_pkg_dir = config.ethpm_dir / pkg.alias
validate_parent_directory(config.ethpm_dir, dest_pkg_dir)
shutil.copytree(tmp_pkg_dir, dest_pkg_dir)
install_to_ethpm_lock(pkg, (config.ethpm_dir / "ethpm.lock"))
install_to_ethpm_lock(pkg, (config.ethpm_dir / LOCKFILE_NAME))


_InstalledPackageTree = namedtuple(
"InstalledPackageTree", "depth path manifest children content_hash"
)


class InstalledPackageTree(_InstalledPackageTree):
class InstalledPackageTree(NamedTuple):
depth: int
path: Path
manifest: Dict[str, Any]
children: Tuple["InstalledPackageTree", ...]
children: Tuple[Any, ...] # Expects InstalledPackageTree
content_hash: str

@property
Expand All @@ -64,23 +57,21 @@ def package_version(self) -> str:
@property
def format_for_display(self) -> str:
prefix = "- " * self.depth
columns = get_terminal_width()
main_info = f"{prefix}{self.package_name}=={self.package_version}..."
main_info = f"{prefix}{self.package_name}=={self.package_version}"
hash_info = f"({self.content_hash})"
diff = columns - len(main_info) - len(hash_info)
if self.children:
children = "\n" + "\n".join(
(child.format_for_display for child in self.children)
)
else:
children = ""
return f"{main_info}{'.' * diff}{hash_info}{children}"
return f"{main_info} --- {hash_info}{children}"


def list_installed_packages(config: Config) -> None:
installed_packages = [
get_installed_package_tree(base_dir)
for base_dir in config.ethpm_dir.glob("*/")
for base_dir in config.ethpm_dir.iterdir()
if base_dir.is_dir()
]
for pkg in sorted(installed_packages):
Expand All @@ -89,7 +80,7 @@ def list_installed_packages(config: Config) -> None:

def get_installed_package_tree(base_dir: Path, depth: int = 0) -> InstalledPackageTree:
manifest = json.loads((base_dir / "manifest.json").read_text())
ethpm_lock = json.loads((base_dir.parent / "ethpm.lock").read_text())
ethpm_lock = json.loads((base_dir.parent / LOCKFILE_NAME).read_text())
content_hash = ethpm_lock[base_dir.name]["resolved_uri"]
dependency_dirs = get_dependency_dirs(base_dir)
children = tuple(
Expand All @@ -99,12 +90,12 @@ def get_installed_package_tree(base_dir: Path, depth: int = 0) -> InstalledPacka
return InstalledPackageTree(depth, base_dir, manifest, children, content_hash)


@to_list
@to_tuple
def get_dependency_dirs(base_dir: Path) -> Iterable[Path]:
dep_dir = base_dir / "ethpm_packages"
dep_dir = base_dir / ETHPM_DIR_NAME
if dep_dir.is_dir():
for ddir in dep_dir.glob("*/"):
if ddir.is_dir() and ddir.name != "src":
for ddir in dep_dir.iterdir():
if ddir.is_dir():
yield ddir


Expand All @@ -115,13 +106,13 @@ def is_package_installed(package_name: str, config: Config) -> bool:
def uninstall_package(package_name: str, config: Config) -> None:
if not is_package_installed(package_name, config):
raise InstallError(
f"Unable to uninstall {package_name} from {config.ethpm_dir}"
f"No package with the name {package_name} found installed under {config.ethpm_dir}."
)

tmp_pkg_dir = Path(tempfile.mkdtemp()) / "ethpm_packages"
tmp_pkg_dir = Path(tempfile.mkdtemp()) / ETHPM_DIR_NAME
shutil.copytree(config.ethpm_dir, tmp_pkg_dir)
shutil.rmtree(tmp_pkg_dir / package_name)
uninstall_from_ethpm_lock(package_name, (tmp_pkg_dir / "ethpm.lock"))
uninstall_from_ethpm_lock(package_name, (tmp_pkg_dir / LOCKFILE_NAME))

shutil.rmtree(config.ethpm_dir)
tmp_pkg_dir.replace(config.ethpm_dir)
Expand All @@ -135,7 +126,7 @@ def write_pkg_installation_files(

write_sources_to_disk(pkg, tmp_pkg_dir, ipfs_backend)
write_build_deps_to_disk(pkg, tmp_pkg_dir, ipfs_backend)
tmp_ethpm_lock = tmp_pkg_dir.parent / "ethpm.lock"
tmp_ethpm_lock = tmp_pkg_dir.parent / LOCKFILE_NAME
install_to_ethpm_lock(pkg, tmp_ethpm_lock)


Expand All @@ -144,12 +135,12 @@ def write_sources_to_disk(
) -> None:
sources = resolve_sources(pkg, ipfs_backend)
for path, source_contents in sources.items():
target_file = pkg_dir / "src" / path
target_file = pkg_dir / SRC_DIR_NAME / path
target_dir = target_file.parent
if not target_dir.is_dir():
target_dir.mkdir(parents=True)
target_file.touch()
validate_parent_directory((pkg_dir / "src"), target_file)
validate_parent_directory((pkg_dir / SRC_DIR_NAME), target_file)
target_file.write_text(source_contents)


Expand Down Expand Up @@ -194,4 +185,6 @@ def install_to_ethpm_lock(pkg: Package, ethpm_lock: Path) -> None:
def uninstall_from_ethpm_lock(package_name: str, ethpm_lock: Path) -> None:
old_lock = json.loads(ethpm_lock.read_text())
new_lock = dissoc(old_lock, package_name)
ethpm_lock.write_text(f"{json.dumps(new_lock, sort_keys=True, indent=4)}\n")
temp_ethpm_lock = Path(tempfile.NamedTemporaryFile().name)
temp_ethpm_lock.write_text(f"{json.dumps(new_lock, sort_keys=True, indent=4)}\n")
temp_ethpm_lock.replace(ethpm_lock)
4 changes: 2 additions & 2 deletions ethpm_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from ethpm_cli.constants import INFURA_HTTP_URI
from ethpm_cli.install import install_package, list_installed_packages
from ethpm_cli.package import Package
from ethpm_cli.parser import get_ethpm_parser
from ethpm_cli.parser import ETHPM_PARSER
from ethpm_cli.scraper import scrape
from ethpm_cli.validation import validate_install_cli_args

Expand Down Expand Up @@ -50,7 +50,7 @@ def scraper(args: argparse.Namespace) -> None:

def main() -> None:
logger = setup_cli_logger()
parser = get_ethpm_parser()
parser = ETHPM_PARSER
logger.info(f"EthPM CLI v{__version__}\n")

args = parser.parse_args()
Expand Down
3 changes: 3 additions & 0 deletions ethpm_cli/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,6 @@ def get_ethpm_parser() -> argparse.ArgumentParser:
help="Path to specific ethpm_packages dir.",
)
return parser


ETHPM_PARSER = get_ethpm_parser()
4 changes: 3 additions & 1 deletion tests/core/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import pytest

from ethpm_cli.constants import ETHPM_DIR_NAME

ASSETS_DIR = Path(__file__).parent / "assets"


Expand All @@ -13,7 +15,7 @@ def test_assets_dir():

@pytest.fixture
def owned_pkg_data(test_assets_dir):
owned_dir = test_assets_dir / "owned" / "ipfs_uri" / "ethpm_packages" / "owned"
owned_dir = test_assets_dir / "owned" / "ipfs_uri" / ETHPM_DIR_NAME / "owned"
owned_raw_manifest = (owned_dir / "manifest.json").read_bytes()
return {
"raw_manifest": owned_raw_manifest,
Expand Down
39 changes: 20 additions & 19 deletions tests/core/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pytest

from ethpm_cli._utils.testing import check_dir_trees_equal
from ethpm_cli.constants import ETHPM_DIR_NAME
from ethpm_cli.exceptions import InstallError
from ethpm_cli.install import (
Config,
Expand All @@ -18,7 +19,7 @@
@pytest.fixture
def config(tmpdir):
namespace = Namespace()
ethpm_dir = Path(tmpdir) / "ethpm_packages"
ethpm_dir = Path(tmpdir) / ETHPM_DIR_NAME
ethpm_dir.mkdir()
namespace.local_ipfs = False
namespace.target_uri = None
Expand Down Expand Up @@ -78,7 +79,7 @@ def test_install_package(uri, pkg_name, alias, install_type, config, test_assets
pkg = Package(uri, alias, config.ipfs_backend)
install_package(pkg, config)

expected_package = test_assets_dir / pkg_name / install_type / "ethpm_packages"
expected_package = test_assets_dir / pkg_name / install_type / ETHPM_DIR_NAME
assert check_dir_trees_equal(config.ethpm_dir, expected_package)


Expand All @@ -101,12 +102,12 @@ def test_can_install_same_package_twice_if_aliased(config, owned_pkg, test_asset
assert (config.ethpm_dir / "owned").is_dir()
assert check_dir_trees_equal(
config.ethpm_dir / "owned",
test_assets_dir / "owned" / "ipfs_uri" / "ethpm_packages" / "owned",
test_assets_dir / "owned" / "ipfs_uri" / ETHPM_DIR_NAME / "owned",
)
assert (config.ethpm_dir / "owned-alias").is_dir()
assert check_dir_trees_equal(
config.ethpm_dir / "owned-alias",
test_assets_dir / "owned" / "ipfs_uri_alias" / "ethpm_packages" / "owned-alias",
test_assets_dir / "owned" / "ipfs_uri_alias" / ETHPM_DIR_NAME / "owned-alias",
)


Expand All @@ -117,7 +118,7 @@ def test_install_multiple_packages(config, test_assets_dir, owned_pkg, wallet_pk
assert (config.ethpm_dir / "wallet").is_dir()
assert (config.ethpm_dir / "owned").is_dir()
assert check_dir_trees_equal(
config.ethpm_dir, (test_assets_dir / "multiple" / "ethpm_packages")
config.ethpm_dir, (test_assets_dir / "multiple" / ETHPM_DIR_NAME)
)


Expand All @@ -132,12 +133,12 @@ def test_uninstall_packages(
assert (config.ethpm_dir / keep).is_dir()
assert not (config.ethpm_dir / uninstall).is_dir()
assert check_dir_trees_equal(
config.ethpm_dir, (test_assets_dir / keep / "ipfs_uri" / "ethpm_packages")
config.ethpm_dir, (test_assets_dir / keep / "ipfs_uri" / ETHPM_DIR_NAME)
)


def test_uninstall_package_warns_if_package_doesnt_exist(config):
with pytest.raises(InstallError, match="Unable to uninstall"):
with pytest.raises(InstallError, match="No package with the name invalid"):
uninstall_package("invalid", config)


Expand All @@ -147,19 +148,19 @@ def test_list(config, owned_pkg, wallet_pkg, caplog):

with caplog.at_level(logging.INFO):
list_installed_packages(config)
assert "owned==1.0.0..." in caplog.text
assert "wallet==1.0.0..." in caplog.text
assert "- safe-math-lib==1.0.0..." in caplog.text
assert "- owned==1.0.0..." in caplog.text
assert (
"(ipfs://QmbeVyFLSuEUxiXKwSsEjef6icpdTdA4kGG9BcrJXKNKUW)\n" in caplog.text
)
"owned==1.0.0 --- (ipfs://QmbeVyFLSuEUxiXKwSsEjef6icpdTdA4kGG9BcrJXKNKUW)\n"
in caplog.text
) # noqa: E501
assert (
"(ipfs://QmRMSm4k37mr2T3A2MGxAj2eAHGR5veibVt1t9Leh5waV1)\n" in caplog.text
)
"wallet==1.0.0 --- (ipfs://QmRMSm4k37mr2T3A2MGxAj2eAHGR5veibVt1t9Leh5waV1)\n"
in caplog.text
) # noqa: E501
assert (
"(ipfs://QmWgvM8yXGyHoGWqLFXvareJsoCZVsdrpKNCLMun3RaSJm)\n" in caplog.text
)
"- safe-math-lib==1.0.0 --- (ipfs://QmWgvM8yXGyHoGWqLFXvareJsoCZVsdrpKNCLMun3RaSJm)\n"
in caplog.text
) # noqa: E501
assert (
"(ipfs://QmbeVyFLSuEUxiXKwSsEjef6icpdTdA4kGG9BcrJXKNKUW)\n" in caplog.text
)
"- owned==1.0.0 --- (ipfs://QmbeVyFLSuEUxiXKwSsEjef6icpdTdA4kGG9BcrJXKNKUW)\n"
in caplog.text
) # noqa: E501

0 comments on commit 24bb48b

Please sign in to comment.