1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.
import functools
import os
from constants import (
BIN_DIRNAME,
CLI_SCRIPTS,
IS_WINDOWS,
PYTHON_EXE_NAME,
ArtifactType,
)
from utils import Utils
WINDOWS_CMD_TEMPLATE = """@echo off
{path} %*
"""
class Uninstaller:
def __init__(self, utils: Utils = None):
if utils is None:
utils = Utils()
self._utils = utils
def uninstall(self, install_dir: str, bin_dir: str):
if self._utils.isdir(install_dir):
self._utils.rmtree(install_dir)
for exe in CLI_SCRIPTS:
exe_path = os.path.join(bin_dir, exe)
if self._utils.islink(exe_path) or self._utils.path_exists(
exe_path
):
self._utils.remove(exe_path)
class Installer:
def __init__(self, build_dir: str, utils: Utils = None):
self._build_dir = build_dir
if utils is None:
utils = Utils()
self._utils = utils
def install(self, install_dir: str, bin_dir: str):
self._copy_to_install_dir(install_dir)
self._install_executables(install_dir, bin_dir)
@functools.cached_property
def artifact_type(self):
if self._utils.isdir(os.path.join(self._build_dir, "exe")):
return ArtifactType.PORTABLE_EXE
return ArtifactType.SYSTEM_SANDBOX
def _copy_to_install_dir(self, install_dir):
build_lib = self._get_build_lib()
if self._utils.isdir(install_dir):
self._utils.rmtree(install_dir)
self._utils.copy_directory(build_lib, install_dir)
if self.artifact_type == ArtifactType.SYSTEM_SANDBOX:
self._update_script_header(install_dir)
def _get_build_lib(self):
if self.artifact_type == ArtifactType.PORTABLE_EXE:
return os.path.join(self._build_dir, "exe", "aws", "dist")
return os.path.join(self._build_dir, "venv")
def _install_executables(self, install_dir, bin_dir):
if IS_WINDOWS and self.artifact_type == ArtifactType.PORTABLE_EXE:
self._install_executables_on_windows(install_dir, bin_dir)
else:
self._symlink_executables(install_dir, bin_dir)
def _install_executables_on_windows(self, install_dir, bin_dir):
filepath = os.path.join(bin_dir, "aws.cmd")
content = WINDOWS_CMD_TEMPLATE.format(
path=os.path.join(install_dir, "aws.exe")
)
self._utils.write_file(filepath, content)
def _symlink_executables(self, install_dir, bin_dir):
if not self._utils.path_exists(bin_dir):
self._utils.makedirs(bin_dir)
for exe in CLI_SCRIPTS:
exe_path = os.path.join(bin_dir, exe)
if self._utils.islink(exe_path):
self._utils.remove(exe_path)
self._utils.symlink(
self._get_install_bin_exe(install_dir, exe), exe_path
)
def _get_install_bin_exe(self, install_dir, exe):
install_bin_dir = install_dir
if self.artifact_type == ArtifactType.SYSTEM_SANDBOX:
install_bin_dir = os.path.join(install_dir, BIN_DIRNAME)
return os.path.join(install_bin_dir, exe)
def _update_script_header(self, install_dir):
python_exe_path = self._get_install_bin_exe(
install_dir, PYTHON_EXE_NAME
)
for exe in CLI_SCRIPTS:
exe_path = self._get_install_bin_exe(install_dir, exe)
lines = self._utils.read_file_lines(exe_path)
lines[0] = self._utils.get_script_header(python_exe_path)
self._utils.write_file(exe_path, "".join(lines))
|