From 418d794320c1e4ac9b92b3e94569771dfee6ab9c Mon Sep 17 00:00:00 2001 From: Jason Ross Date: Sun, 17 May 2026 11:21:01 -0500 Subject: [PATCH] add gitignore --- .gitignore | 1 + bootstrap_environment.py | 79 ++++++++++++++++++++++++++++++++++++++++ formatted_packages.txt | 4 ++ 3 files changed, 84 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/bootstrap_environment.py b/bootstrap_environment.py index 84f914c..20a7423 100755 --- a/bootstrap_environment.py +++ b/bootstrap_environment.py @@ -644,6 +644,8 @@ def _default_install_path(pkg: CustomPackage) -> Optional[Path]: return Path("~/.nvm") if n == "pyenv": return Path("~/.pyenv") + if n == "neovim": + return Path("/opt/nvim-linux-x86_64") return None @@ -773,6 +775,78 @@ def _install_nvm() -> None: print(f" NVM {version} installed to ~/.nvm") +def _install_neovim(pkg: CustomPackage, tmp: Path) -> None: + data = _fetch_json("https://api.github.com/repos/neovim/neovim/releases/latest") + if data is None: + return + + asset_name = "nvim-linux-x86_64.tar.gz" + asset = next((a for a in data["assets"] if a["name"] == asset_name), None) + if asset is None: + err(f"Neovim asset {asset_name} not found") + return + + expected_digest = asset.get("digest") + if not expected_digest or not expected_digest.startswith("sha256:"): + err("Neovim asset digest missing or invalid") + return + expected_hash = expected_digest.split(":", 1)[1] + + dest = tmp / asset_name + if not _download(asset["browser_download_url"], dest): + return + + actual_hash = _sha256_of(dest) + if actual_hash != expected_hash: + err(f"Neovim SHA256 mismatch: expected {expected_hash}, got {actual_hash}") + return + print(" SHA256 OK") + + print(" Extracting Neovim to /opt ...") + run(["rm", "-rf", "/opt/nvim-linux-x86_64"], as_sudo=True) + run(["tar", "-C", "/opt", "-xzf", str(dest)], as_sudo=True) + + profile_line = 'export PATH="$PATH:/opt/nvim-linux-x86_64/bin"' + profile_script = "/etc/profile.d/neovim.sh" + run(["bash", "-c", + f"grep -qxF {profile_line!r} {profile_script} 2>/dev/null || " + f"echo {profile_line!r} >> {profile_script}"], + as_sudo=True, check=False) + print(f" Neovim installed to /opt/nvim-linux-x86_64") + + +def _clone_nvim_config() -> None: + config_dir = Path.home() / ".config" / "nvim" + repo_url = "git@github.com:JMR-dev/nvim-config.git" + + print(f"\n[Neovim] Setting up configuration from {repo_url} ...") + + if config_dir.exists(): + print(f" Removing existing configuration at {config_dir} ...") + shutil.rmtree(config_dir) + + config_dir.parent.mkdir(parents=True, exist_ok=True) + + print(f" Cloning to {config_dir} ...") + # We use a temp clone and then move to ensure we handle the "rename" part of the request + # although cloning directly to 'nvim' is effectively the same. + # The user asked: "clones my nvim config to $HOME/.config/$REPO and renames the repo root folder to just nvim" + repo_name = repo_url.split("/")[-1].replace(".git", "") + temp_clone = config_dir.parent / repo_name + + if temp_clone.exists(): + shutil.rmtree(temp_clone) + + result = run(["git", "clone", repo_url, str(temp_clone)], check=False) + if result.returncode != 0: + err("Neovim configuration clone failed") + return + + print(f" Renaming {temp_clone.name} to {config_dir.name} ...") + temp_clone.rename(config_dir) + print(f" Neovim configuration ready at {config_dir}") + + def ensure_node_lts() -> None: """If nvm is present, ensure Node LTS is installed and set as the default.""" nvm_dir = Path.home() / ".nvm" @@ -906,6 +980,10 @@ def install_custom_packages(to_install: list[CustomPackage]) -> None: if name_lower == "pyenv": _install_pyenv() continue + if name_lower == "neovim": + with tempfile.TemporaryDirectory() as tmp_str: + _install_neovim(pkg, Path(tmp_str)) + continue if not pkg.url: warn(f"No URL or install handler for '{pkg.name}' — skipping") @@ -1200,6 +1278,7 @@ def main() -> None: if args.only is None: check_and_setup_ssh() + _clone_nvim_config() if pyenv_thread is not None: if pyenv_thread.is_alive(): diff --git a/formatted_packages.txt b/formatted_packages.txt index 5bc4727..a63e155 100644 --- a/formatted_packages.txt +++ b/formatted_packages.txt @@ -15,6 +15,7 @@ dotnet-sdk-10.0 ffmpeg-free gcc gh +git github-desktop google-chrome-stable lua @@ -70,6 +71,9 @@ Name - go-1.26.3 URL - https://go.dev/dl/go1.26.3.linux-amd64.tar.gz SHA256 - 2b2cfc7148493da5e73981bffbf3353af381d5f93e789c82c79aff64962eb556 +Name - neovim +URL - https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz + Name - firecracker-v1.15.1 URL - https://github.com/firecracker-microvm/firecracker/releases/download/v1.15.1/firecracker-v1.15.1-x86_64.tgz SHA256 - d4a32ab2322d887ca1bc4a4e7afa9cc35393e6362dfc2b3becb389d362e4275a