From 6ddb4c1e825722649081a6f867272358663fa809 Mon Sep 17 00:00:00 2001 From: ViViDboarder Date: Fri, 19 Jul 2024 12:36:35 -0700 Subject: [PATCH] Use new python based helper installer --- docker/Dockerfile | 5 +- install-coding-helpers.sh | 4 +- install-helpers.py | 235 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+), 4 deletions(-) create mode 100755 install-helpers.py diff --git a/docker/Dockerfile b/docker/Dockerfile index 5282c47..0b2a61e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -15,6 +15,7 @@ RUN apk add --no-cache \ npm \ py3-pip \ py3-pynvim \ + pipx \ python3 \ ; @@ -47,8 +48,8 @@ RUN mkdir $HOME/bin ENV PATH $HOME/bin:$PATH # Install Language servers -COPY --chown=vividboarder:users ./install-coding-helpers.sh ./ -RUN ./install-coding-helpers.sh +COPY --chown=vividboarder:users ./install-helpers.py ./ +RUN ./install-helpers.py # Add config COPY --chown=vividboarder:users ./neovim $HOME/.config/nvim diff --git a/install-coding-helpers.sh b/install-coding-helpers.sh index ab79906..fd8d81b 100755 --- a/install-coding-helpers.sh +++ b/install-coding-helpers.sh @@ -97,10 +97,10 @@ function maybe_pip_install() { else if command_exists pip3 ;then # If pip3 is there, use it to ensure we're using python 3 - pip3 install --user --upgrade "${user_bins[@]}" + pip3 install --user --upgrade --break-system-packages "${user_bins[@]}" else # Use pip and hope for the best - pip install --user --upgrade "${user_bins[@]}" + pip install --user --upgrade --break-system-packages "${user_bins[@]}" fi fi } diff --git a/install-helpers.py b/install-helpers.py new file mode 100755 index 0000000..e90ef1b --- /dev/null +++ b/install-helpers.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python3 +import argparse +import os +import shutil +import subprocess +import sys +from enum import Enum + + +class Language(Enum): + PYTHON = "python" + CSS = "css" + VIM = "vim" + NEOVIM = "neovim" + YAML = "yaml" + TEXT = "text" + GO = "go" + LUA = "lua" + DOCKER = "docker" + TERRAFORM = "terraform" + RUST = "rust" + BASH = "bash" + KOTLIN = "kotlin" + JAVASCRIPT = "javascript" + HTML = "html" + JSON = "json" + WEB = "web" + + +def command_exists(command: str) -> bool: + return shutil.which(command) is not None + + +def maybe_run(*args: str) -> bool: + if command_exists(args[0]): + print("> " + " ".join(args)) + result = subprocess.run(args) + return result.returncode == 0 + else: + print(f"ERROR: {args[0]} does not exist. Could not run {' '.join(args)}") + return False + + +def should_install_user(command: str) -> bool: + bin_path = shutil.which(command) + if not bin_path: + return True + + if bin_path.startswith(os.path.expanduser("~")): + return True + + print("WARNING: Already installed by system. Skipping installation of", command) + return False + + +def maybe_pip_install(*args: str, library=False) -> bool: + user_bins = [arg for arg in args if should_install_user(arg)] + if not user_bins: + return True + + if not library and command_exists("pipx"): + return maybe_run("pipx", "install", *user_bins) + elif command_exists("pip3"): + return maybe_run( + "pip3", + "install", + "--user", + "--upgrade", + "--break-system-packages", + *user_bins, + ) + else: + return maybe_run( + "pip", + "install", + "--user", + "--upgrade", + "--break-system-packages", + *user_bins, + ) + + +def maybe_npm_install(*args: str) -> bool: + user_bins = [arg for arg in args if should_install_user(arg)] + if not user_bins: + return True + + return maybe_run("npm", "install", "-g", *user_bins) + + +def install_language_servers(langs: set[Language]): + if Language.PYTHON in langs: + maybe_npm_install("pyright") + if Language.RUST in langs: + maybe_run( + "rustup", + "component", + "add", + "rustfmt", + "rust-analysis", + "rust-src", + "clippy", + "rust-analyzer", + ) + if Language.GO in langs: + maybe_run("go", "install", "golang.org/x/tools/gopls@latest") + + +def install_linters(langs: set[Language]): + if Language.PYTHON in langs: + maybe_pip_install("mypy") + if {Language.CSS, Language.WEB} & langs: + maybe_npm_install("csslint") + if {Language.VIM, Language.NEOVIM} in langs: + maybe_pip_install("vim-vint") + if Language.YAML in langs: + maybe_pip_install("yamllint") + if Language.TEXT in langs: + maybe_npm_install("alex", "write-good") + maybe_pip_install("proselint") + if Language.GO in langs: + maybe_run( + "release-gitter", + "--git-url", + "https://github.com/golangci/golangci-lint", + "--map-arch", + "armv7l=armv7", + "--extract-all", + "--exec", + os.path.expanduser("mv /tmp/$(echo {}|sed s/\\.tar\\.gz$//)/golangci-lint ~/bin/"), + "golangci-lint-{version}-{system}-{arch}.tar.gz", + "/tmp/", + ) + if {Language.LUA, Language.NEOVIM} & langs: + if not maybe_run("lua", "-e", "require('lfs')"): + maybe_run("luarocks", "--local", "install", "luafilesystem") + maybe_run("luarocks", "--local", "install", "luacheck", "1.1.0") + if Language.DOCKER in langs: + if should_install_user("hadolint"): + hadolint_arm64 = "arm64" + if sys.platform == "darwin": + hadolint_arm64 = "x86_64" + maybe_run( + "release-gitter", + "--git-url", + "https://github.com/hadolint/hadolint", + "--map-arch", + f"aarch64={hadolint_arm64}", + "--map-arch", + f"arm64={hadolint_arm64}", + "--exec", + os.path.expanduser("mv ~/bin/{} ~/bin/hadolint && chmod +x ~/bin/hadolint"), + "hadolint-{system}-{arch}", + os.path.expanduser("~/bin"), + ) + if Language.TERRAFORM in langs: + maybe_run( + "release-gitter", + "--git-url", + "https://github.com/aquasecurity/tfsec", + "--exec", + os.path.expanduser("mv ~/bin/{} ~/bin/tfsec && chmod +x ~/bin/tfsec"), + "tfsec-{system}-{arch}", + os.path.expanduser("~/bin"), + ) + maybe_run( + "release-gitter", + "--git-url", + "https://github.com/terraform-linters/tflint", + "--extract-all", + "--exec", + os.path.expanduser("chmod +x ~/bin/tflint"), + "tflint_{system}_{arch}.zip", + os.path.expanduser("~/bin"), + ) + + +def install_fixers(langs: set[Language]): + if { + Language.PYTHON, + Language.HTML, + Language.CSS, + Language.WEB, + Language.JSON, + } & set(langs): + maybe_npm_install("prettier") + if Language.PYTHON in langs: + maybe_pip_install("black", "reorder-python-imports", "isort") + if Language.RUST in langs: + maybe_run("rustup", "component", "add", "rustfmt") + if {Language.LUA, Language.NEOVIM} in langs: + maybe_run("luarocks", "--local", "install", "stylua", "0.19.1") + + +def install_debuggers(langs): + if Language.PYTHON in langs: + maybe_pip_install("debugpy", library=True) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--ignore-missing", action="store_true") + parser.add_argument("langs", nargs="*", type=Language) + args = parser.parse_args() + + maybe_pip_install("release-gitter") + + os.environ["PYTHONPATH"] = "" + + if args.ignore_missing: + os.environ["set"] = "+e" + else: + os.environ["set"] = "-e" + + langs = set(args.langs or Language) + + # Handle some aliases + if Language.NEOVIM in langs: + langs.add(Language.VIM) + langs.add(Language.LUA) + if Language.WEB in langs: + langs.add(Language.CSS) + langs.add(Language.JAVASCRIPT) + langs.add(Language.HTML) + + install_language_servers(langs) + install_linters(langs) + install_fixers(langs) + install_debuggers(langs) + + print("DONE") + + +if __name__ == "__main__": + main()