1
0
mirror of https://github.com/checktheroads/hyperglass synced 2024-05-11 05:55:08 +00:00

115 lines
3.2 KiB
Python
Raw Normal View History

"""Install hyperglass."""
# Standard Library
import os
import shutil
from filecmp import dircmp
from pathlib import Path
# Third Party
import inquirer
# Local
from .echo import error, success, warning
from .util import create_dir
USER_PATH = Path.home() / "hyperglass"
ROOT_PATH = Path("/etc/hyperglass/")
ASSET_DIR = Path(__file__).parent.parent / "images"
IGNORED_FILES = [".DS_Store"]
INSTALL_PATHS = [
inquirer.List(
"install_path",
message="Choose a directory for hyperglass",
choices=[USER_PATH, ROOT_PATH],
)
]
def prompt_for_path() -> str:
"""Recursively prompt the user for an app path until one is provided."""
answer = inquirer.prompt(INSTALL_PATHS)
if answer is None:
warning("A directory for hyperglass is required")
answer = prompt_for_path()
return answer["install_path"]
class Installer:
"""Install hyperglass."""
def __init__(self, unattended: bool):
"""Initialize installer."""
self.unattended = unattended
def install(self) -> None:
"""Complete the installation."""
self.app_path = self._get_app_path()
self._scaffold()
self._migrate_static_assets()
def _get_app_path(self) -> Path:
"""Find the app path from env variables or a prompt."""
if self.unattended:
return USER_PATH
app_path = os.environ.get("HYPERGLASS_PATH", None)
if app_path is None:
app_path = prompt_for_path()
return app_path
def _scaffold(self) -> None:
"""Create the file structure necessary for hyperglass to run."""
ui_dir = self.app_path / "static" / "ui"
images_dir = self.app_path / "static" / "images"
favicon_dir = images_dir / "favicons"
custom_dir = self.app_path / "static" / "custom"
create_dir(self.app_path)
for path in (ui_dir, images_dir, favicon_dir, custom_dir):
create_dir(path, parents=True)
def _migrate_static_assets(self) -> bool:
"""Synchronize the project assets with the installation assets."""
target_dir = self.app_path / "static" / "images"
if not target_dir.exists():
shutil.copytree(ASSET_DIR, target_dir)
# Compare the contents of the project's asset directory (considered
# the source of truth) with the installation directory. If they do
# not match, delete the installation directory's asset directory and
# re-copy it.
compare_initial = dircmp(ASSET_DIR, target_dir, ignore=IGNORED_FILES)
if not compare_initial.left_list == compare_initial.right_list:
shutil.rmtree(target_dir)
shutil.copytree(ASSET_DIR, target_dir)
# Re-compare the source and destination directory contents to
# ensure they match.
compare_post = dircmp(ASSET_DIR, target_dir, ignore=IGNORED_FILES)
if not compare_post.left_list == compare_post.right_list:
error(
"Files in {a} do not match files in {b}",
a=str(ASSET_DIR),
b=str(target_dir),
)
return False
success("Migrated assets from {a} to {b}", a=str(ASSET_DIR), b=str(target_dir))
return True