Skip to content

Commit

Permalink
style: isort and black
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbraun89 authored Mar 12, 2023
1 parent 07fd397 commit 6d2a61b
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 83 deletions.
17 changes: 12 additions & 5 deletions dcontainer/__main__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import typer

from dcontainer.cli.feature import app as feature_app
from dcontainer.utils.version import resolve_own_package_version, resolve_own_release_version
from dcontainer.utils.version import (
resolve_own_package_version,
resolve_own_release_version,
)

app = typer.Typer(pretty_exceptions_show_locals=False, pretty_exceptions_short=False)
app.add_typer(feature_app, name="feature")
Expand All @@ -18,13 +21,17 @@ def release_version_callback(value: bool) -> None:
typer.echo(f"dcontainer release version: {resolve_own_release_version()}")
raise typer.Exit()


@app.callback()
def version(
version: bool = typer.Option(None, "--version", callback=version_callback, is_eager=True),
release_version: bool = typer.Option(None, "--release-version", callback=release_version_callback, is_eager=True),

version: bool = typer.Option(
None, "--version", callback=version_callback, is_eager=True
),
release_version: bool = typer.Option(
None, "--release-version", callback=release_version_callback, is_eager=True
),
):
return
return


def main() -> None:
Expand Down
12 changes: 6 additions & 6 deletions dcontainer/cli/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,27 @@ def install_command(
verbose: bool = False,
) -> None:
def _strip_if_wrapped_around(value: str, char: str) -> str:

if len(char) > 1:
raise ValueError("For clarity sake, will only strip one character at a time")

raise ValueError(
"For clarity sake, will only strip one character at a time"
)

if len(value) >= 2 and value[0] == char and value[-1] == char:
return value.strip(char)
return value


if option is None:
options = []
else:
options = option

options_dict = {}
for single_option in options:
single_option = _strip_if_wrapped_around(single_option, '"')

option_name = single_option.split("=")[0]

option_value = single_option[len(option_name)+1:]
option_value = single_option[len(option_name) + 1 :]
option_value = _strip_if_wrapped_around(option_value, '"')

options_dict[option_name] = option_value
Expand Down
8 changes: 2 additions & 6 deletions dcontainer/cli/generate/dir_models/src_dir.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@
from dcontainer.cli.generate.file_models.devcontainer_feature_json import (
DevcontainerFeatureJson,
)
from dcontainer.cli.generate.file_models.install_command_sh import (
InstallCommandSH,
)
from dcontainer.cli.generate.file_models.install_command_sh import InstallCommandSH
from dcontainer.cli.generate.file_models.install_sh import InstallSH
from dcontainer.models.devcontainer_feature_definition import (
FeatureDefinition,
)
from dcontainer.models.devcontainer_feature_definition import FeatureDefinition


class SrcDir(Directory):
Expand Down
12 changes: 6 additions & 6 deletions dcontainer/cli/generate/file_models/dependencies_sh.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
FeatureDependencies,
FeatureDependency,
)
from dcontainer.utils.version import resolve_own_release_version
from dcontainer.settings import ENV_CLI_LOCATION, ENV_FORCE_CLI_INSTALLATION
from dcontainer.utils.version import resolve_own_release_version

RELEASE_VERSION = resolve_own_release_version()

Expand Down Expand Up @@ -64,7 +64,9 @@
"""

SINGLE_DEPENDENCY = """$dcontainer_location feature install "{feature_oci}" {stringified_envs_args} """
SINGLE_DEPENDENCY = (
"""$dcontainer_location feature install "{feature_oci}" {stringified_envs_args} """
)


class DependenciesSH(File):
Expand Down Expand Up @@ -139,11 +141,9 @@ def to_str(self) -> str:
)

return HEADER.format(
dependency_installation_lines="\n\n".join(
installation_lines
),
dependency_installation_lines="\n\n".join(installation_lines),
dcontainer_link=DCONTAINER_LINK,
checksums_link=CHECKSUM_LINK,
force_cli_installation_env=ENV_FORCE_CLI_INSTALLATION,
cli_location_env=ENV_CLI_LOCATION
cli_location_env=ENV_CLI_LOCATION,
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from easyfs import File

from dcontainer.models.devcontainer_feature_definition import (
FeatureDefinition,
)
from dcontainer.models.devcontainer_feature_definition import FeatureDefinition


class DevcontainerFeatureJson(File):
Expand Down
4 changes: 1 addition & 3 deletions dcontainer/cli/generate/generate_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

from dcontainer.cli.generate.dir_models.src_dir import SrcDir
from dcontainer.cli.generate.dir_models.test_dir import TestDir
from dcontainer.models.devcontainer_feature_definition import (
FeatureDefinition,
)
from dcontainer.models.devcontainer_feature_definition import FeatureDefinition


def generate(
Expand Down
2 changes: 1 addition & 1 deletion dcontainer/models/devcontainer_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Config:
default: Optional[str] = Field(
"",
description="Default value if the user omits this option from their configuration.",
) # todo: remove Optional state after SDKMAN feature is fixed
) # todo: remove Optional state after SDKMAN feature is fixed
description: Optional[str] = Field(
None,
description="A description of the option displayed to the user by a supporting tool.",
Expand Down
66 changes: 38 additions & 28 deletions dcontainer/oci/oci_feature_installer.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import logging
import os
import pwd
import tempfile
from typing import Dict, Optional, Union
import sys
import os
import tempfile
from pathlib import Path
from typing import Dict, Optional, Union

import invoke

from dcontainer.models.devcontainer_feature import Feature
from dcontainer.oci.oci_feature import OCIFeature
from dcontainer.settings import DContainerSettings, ENV_CLI_LOCATION, ENV_PROPAGATE_CLI_LOCATION, ENV_FORCE_CLI_INSTALLATION, ENV_VERBOSE
from dcontainer.settings import (
ENV_CLI_LOCATION,
ENV_FORCE_CLI_INSTALLATION,
ENV_PROPAGATE_CLI_LOCATION,
ENV_VERBOSE,
DContainerSettings,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -43,14 +49,12 @@ def install(
) -> None:
if options is None:
options = {}

if envs is None:
envs = {}
feature_obj=feature_oci.get_devcontainer_feature_obj()
feature_obj = feature_oci.get_devcontainer_feature_obj()

options = cls._resolve_options(
feature_obj=feature_obj, options=options
)
options = cls._resolve_options(feature_obj=feature_obj, options=options)
logger.info("resolved options: %s", str(options))

remote_user = cls._resolve_remote_user(remote_user_name)
Expand All @@ -67,7 +71,7 @@ def install(
settings = DContainerSettings()

if settings.verbose == "1":
verbose = True
verbose = True

envs[ENV_VERBOSE] = settings.verbose
envs[ENV_FORCE_CLI_INSTALLATION] = settings.force_cli_installation
Expand All @@ -76,26 +80,32 @@ def install(
if settings.propagate_cli_location == "1":
if settings.cli_location != "":
envs[ENV_CLI_LOCATION] = settings.cli_location
elif getattr(sys, 'frozen', False):
elif getattr(sys, "frozen", False):
envs[ENV_CLI_LOCATION] = sys.executable
else:
# override it with empty string in case it already exists
# override it with empty string in case it already exists
envs[ENV_CLI_LOCATION] = ""

except Exception as e:
logger.warning(f"could not create settings: {str(e)}")

env_variables_cmd = " ".join(
[f'{env_name}="{cls._escape_quotes(env_value)}"' for env_name, env_value in envs.items()]
[
f'{env_name}="{cls._escape_quotes(env_value)}"'
for env_name, env_value in envs.items()
]
)



with tempfile.TemporaryDirectory() as tempdir:
feature_oci.download_and_extract(tempdir)

sys.stdout.reconfigure(encoding='utf-8') # some processes will print in utf-8 while original stdout accept only ascii, causing a "UnicodeEncodeError: 'ascii' codec can't encode characters" error
sys.stderr.reconfigure(encoding='utf-8') # some processes will print in utf-8 while original stdout accept only ascii, causing a "UnicodeEncodeError: 'ascii' codec can't encode characters" error

sys.stdout.reconfigure(
encoding="utf-8"
) # some processes will print in utf-8 while original stdout accept only ascii, causing a "UnicodeEncodeError: 'ascii' codec can't encode characters" error
sys.stderr.reconfigure(
encoding="utf-8"
) # some processes will print in utf-8 while original stdout accept only ascii, causing a "UnicodeEncodeError: 'ascii' codec can't encode characters" error

response = invoke.run(
f"cd {tempdir} && \
chmod +x -R . && \
Expand All @@ -108,17 +118,19 @@ def install(
raise OCIFeatureInstaller.FeatureInstallationException(
f"feature {feature_oci.path} failed to install. return_code: {response.return_code}. see logs for error reason."
)

cls._set_permanent_envs(feature_obj)

@classmethod
def _set_permanent_envs(cls, feature: Feature) -> None:
if feature.containerEnv is None:
return

feature_profile_dir = Path(cls._PROFILE_DIR)
feature_profile_dir.mkdir(exist_ok=True, parents=True)
feature_profile_file = feature_profile_dir.joinpath(f"dcontainer-{feature.id}.sh")
feature_profile_file = feature_profile_dir.joinpath(
f"dcontainer-{feature.id}.sh"
)

if not feature_profile_file.exists():
feature_profile_file.touch()
Expand All @@ -130,19 +142,17 @@ def _set_permanent_envs(cls, feature: Feature) -> None:
for env_name, env_value in feature.containerEnv.items():
statement = f"export {env_name}={env_value}"
if statement not in current_content:
current_content += f"\n{statement}"
current_content += f"\n{statement}"

modified = True

if modified:
with open(feature_profile_file, "w") as f:
f.write(current_content)


@classmethod
def _escape_quotes(cls, value: str) -> str:
return value.replace('"', '\\"')


@classmethod
def _resolve_options(
Expand Down
9 changes: 3 additions & 6 deletions dcontainer/oci/oci_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ def _generate_token(raw_response_header: str) -> str:
www_authenticate = OCIRegistry._parse_www_authenticate(raw_response_header)

token_request_link = f"{www_authenticate.realm}?service={www_authenticate.service}&scope={www_authenticate.scope}"
if not token_request_link.startswith('http'):
if not token_request_link.startswith("http"):
raise ValueError("only http/https links are permited")

response = urllib.request.urlopen(token_request_link) # nosec
token = json.loads(response.read())["token"]
return token
Expand All @@ -116,18 +116,15 @@ def _generate_token(raw_response_header: str) -> str:
def _attempt_request(
url: str, headers: Optional[Dict[str, str]] = None
) -> http.client.HTTPResponse:

if not url.startswith('http'):
if not url.startswith("http"):
raise ValueError("only http/https links are permited")


if headers is None:
headers = {}

if "User-Agent" not in headers:
headers["User-Agent"] = "dcontainer"


request = urllib.request.Request(url=url, headers=headers)

try:
Expand Down
10 changes: 8 additions & 2 deletions dcontainer/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from pydantic import BaseSettings


class DContainerSettings(BaseSettings):
class Config:
env_prefix = "DCONTAINER_"
Expand All @@ -12,7 +13,12 @@ class Config:
force_cli_installation: str = ""
verbose: str = ""


ENV_CLI_LOCATION = f"{DContainerSettings.Config.env_prefix}CLI_LOCATION"
ENV_PROPAGATE_CLI_LOCATION = f"{DContainerSettings.Config.env_prefix}PROPAGATE_CLI_LOCATION"
ENV_FORCE_CLI_INSTALLATION = f"{DContainerSettings.Config.env_prefix}FORCE_CLI_INSTALLATION"
ENV_PROPAGATE_CLI_LOCATION = (
f"{DContainerSettings.Config.env_prefix}PROPAGATE_CLI_LOCATION"
)
ENV_FORCE_CLI_INSTALLATION = (
f"{DContainerSettings.Config.env_prefix}FORCE_CLI_INSTALLATION"
)
ENV_VERBOSE = f"{DContainerSettings.Config.env_prefix}VERBOSE"
21 changes: 13 additions & 8 deletions dcontainer/utils/version.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import json
import urllib
import urllib.request
import json
from importlib.metadata import version
from typing import Optional, List
from typing import List, Optional

OWN_REPO = "devcontainers-contrib/cli"
OWN_PACKAGE = "dcontainer"
Expand All @@ -13,25 +13,30 @@ def _resolve_package_version(package: str) -> str:


def _get_latest_release(repo: str) -> str:
response = urllib.request.urlopen(f"https://api.github.com/repos/{repo}/releases/latest") # nosec
response = urllib.request.urlopen(
f"https://api.github.com/repos/{repo}/releases/latest"
) # nosec
response_json = json.loads(response.read())
resolved_version = response_json['name']
resolved_version = response_json["name"]
return resolved_version


def _get_github_tags(repo: str) -> List[str]:
response = urllib.request.urlopen(f"https://api.github.com/repos/{repo}/tags") # nosec
return [tag['name'] for tag in json.loads(response.read())]
response = urllib.request.urlopen(
f"https://api.github.com/repos/{repo}/tags"
) # nosec
return [tag["name"] for tag in json.loads(response.read())]


def resolve_own_package_version() -> str:
return _resolve_package_version(OWN_PACKAGE)


def resolve_own_release_version() -> str:
package_version = _resolve_package_version(OWN_PACKAGE)
tags = _get_github_tags(OWN_REPO)
if package_version is not None:
if f"v{package_version}" in tags:
return f"v{package_version}"
return _get_latest_release(OWN_REPO)

return _get_latest_release(OWN_REPO)
Loading

0 comments on commit 6d2a61b

Please sign in to comment.