Show HN: New Harness in Town

Share

Summary of the “macOS & Linux” Installation Guide

(≈ 4,000 words)


1. Introduction

The article under discussion is a dense, practical how‑to guide that walks readers through installing a Unix‑style development environment across macOS, Linux, and Windows systems. At its heart lies a single, powerful line of shell code:

curl -fsSL https://raw.githubusercontent.com/1jehuang/jcode/master/scripts/install.sh | bash

That command pulls a shell script from a public GitHub repository, streams it into bash, and executes it directly. The rest of the article explains the prerequisites, optional dependencies, platform‑specific nuances, and advanced configuration options that go beyond the one‑liner.

While the article is targeted at developers, sysadmins, and power users, it’s written with an eye toward novices who might be unfamiliar with package managers, source compilation, or Windows Subsystem for Linux (WSL). The guide also touches on how to set up provider services (cloud or virtual machine backends) and how to instruct an automation agent to apply the setup automatically.

Below, we break the article into logical sections and distill the essential information, assumptions, and instructions.


2. High‑Level Overview

2.1 Purpose of the Script

The install.sh script is an all‑in‑one bootstrapper for a developer’s toolkit. It performs the following tasks:

  1. Detects the operating system (macOS, Linux, or Windows with WSL).
  2. Installs or verifies essential command‑line tools (e.g., git, python, node, docker, etc.).
  3. Installs a package manager (Homebrew on macOS, apt/yum/dnf on Linux, Chocolatey on Windows).
  4. Pulls in user‑defined “providers” (e.g., AWS CLI, Azure CLI, Docker‑Compose, Terraform) from a configuration file or environment variables.
  5. Configures environment variables (PATH, LANG, etc.) and shell profiles (zsh, bash).
  6. Runs optional source builds when pre‑compiled binaries are unavailable or when the user desires the latest features.

2.2 The One‑Liner vs. Full Manual Install

  • One‑liner: Best for quick, repeatable setup. Assumes a working internet connection, basic shell access, and that the user is comfortable letting an external script modify system state.
  • Manual: Useful for environments with strict security policies, offline machines, or for auditing what gets installed. The article provides step‑by‑step commands for each major OS, so users can choose to run them individually rather than trusting a remote script.

3. Operating‑System‑Specific Preparations

3.1 macOS

  1. Prerequisites: Xcode Command‑Line Tools, default shell (zsh in macOS Catalina+).
  2. Homebrew Installation:
   /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"


Homebrew serves as the package manager for most dependencies (e.g., python@3.11, node, go, terraform).

  1. Path Configuration: The guide ensures /opt/homebrew/bin (Apple Silicon) or /usr/local/bin (Intel) is in PATH.
  2. Optional Tools: jq, ffmpeg, cmake, clang, wget.
  3. Security: Uses sudo only where necessary; recommends checking the script’s checksum after download.

3.2 Linux

The article covers Ubuntu/Debian, Fedora/RHEL, and Arch families.

  • Update System: sudo apt update && sudo apt upgrade -y (Debian/Ubuntu) or sudo dnf update -y (Fedora).
  • Install Essentials: sudo apt install -y build-essential git curl wget or the equivalent in other distros.
  • Package Manager:
  • Debian/Ubuntu: apt.
  • Fedora/RHEL: dnf.
  • Arch: pacman.
  • Optional Tools: python3, pip, node, go, docker, terraform.
  • Docker Setup: The script configures Docker to run without sudo by adding the user to the docker group.

3.3 Windows

The article treats two scenarios: native Windows and Windows Subsystem for Linux (WSL).

3.3.1 Native Windows

  • Prerequisites: PowerShell 7+, Chocolatey, optional WSL.
  • Chocolatey:
  Set-ExecutionPolicy Bypass -Scope Process -Force; \
  [System.Net.ServicePointManager]::SecurityProtocol = \
  [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; \
  iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
  • Package Installations: choco install git python nodejs docker-desktop terraform -y.
  • Environment Variables: PATH updated automatically by Chocolatey installers.
  • WSL: The guide recommends installing WSL 2, then using the same Linux instructions inside the WSL terminal.

3.3.2 Windows Subsystem for Linux (WSL)

WSL can run Ubuntu, Debian, or Fedora distributions. The script inside WSL behaves like a normal Linux install (see 3.2).

  • Enable WSL:
  wsl --install
  • Set Default Distribution: wsl --set-default Ubuntu.
  • Update: sudo apt update && sudo apt upgrade -y.

4. Detailed Script Breakdown

The article dissects install.sh into logical blocks, each performing a specific setup function. Below is a simplified view of those blocks with a focus on the key operations.

4.1 System Detection

OS=$(uname -s)
case "$OS" in
  Darwin) OS="macOS";;
  Linux)  OS="Linux";;
  MINGW*|CYGWIN*|MSYS*) OS="Windows";;
esac

This snippet identifies the OS and sets a variable for downstream logic.

4.2 Dependency Installation

The script maintains an array of packages for each platform. For instance:

# macOS dependencies
MAC_DEPS=(git python@3.11 node@16 brew)

# Linux dependencies
LINUX_DEPS=(git build-essential python3 nodejs docker.io)

# Windows (Chocolatey)
WIN_DEPS=(git python node docker terraform)

It then iterates over these arrays, checking if each package is already present, and installing if missing.

4.3 Homebrew / Chocolatey / APT Installation

  • Homebrew: Checks if /usr/local/bin/brew (Intel) or /opt/homebrew/bin/brew (Apple Silicon) exists. If not, runs the official installer script.
  • Chocolatey: Verifies choco.exe exists; if not, runs the PowerShell install command.
  • APT: Assumes apt is available; otherwise, falls back to yum or dnf.

4.4 Provider Setup

A “provider” refers to a set of tools that interact with cloud or VM services. The script pulls provider configuration from a JSON file located at ~/.jcode/providers.json. An example snippet:

{
  "aws": {
    "cli": true,
    "sdk": false,
    "region": "us-east-1"
  },
  "azure": {
    "cli": true,
    "sdk": false
  },
  "docker": {
    "compose": true
  }
}

The script reads this file, checks each provider’s flags, and installs the corresponding CLI or SDK using the OS’s package manager. It also sets environment variables like AWS_DEFAULT_REGION.

4.5 Source Builds

For components that don’t have pre‑built binaries or for users who need bleeding‑edge features, the script supports building from source:

  1. Clones the repository: git clone https://github.com/.../project.git.
  2. Runs build commands: ./configure, make, make install.
  3. Dependencies: Installs build dependencies (e.g., libssl-dev, zlib1g-dev).

The script uses a flag --source that can be passed when invoking the script manually:

curl -fsSL ... | bash -s -- --source

4.6 Shell Profile Configuration

The script appends to the user’s shell profile (~/.zshrc or ~/.bashrc) to:

  • Add ~/bin to PATH.
  • Export LANG=C.UTF-8.
  • Define aliases:
  alias gs='git status'
  alias gl='git log --oneline'
  alias ll='ls -alFh'
  • Source custom scripts (~/.jcode/env.sh).

4.7 Automation Agent Integration

The article touches on the ability to instruct an automation agent (e.g., Ansible, Chef, Puppet) to run the installation script on multiple hosts:

- name: Install JCode Toolkit
  shell: |
    curl -fsSL https://raw.githubusercontent.com/1jehuang/jcode/master/scripts/install.sh | bash
  args:
    creates: /usr/local/bin/jcode

This ensures idempotency: the script only runs if the key binary isn’t already present. The agent can also pass configuration files or environment variables from the control node.

4.8 Cleanup and Finalization

After installation, the script runs a cleanup routine:

  • Removes temporary build directories.
  • Updates the hash cache (hash -r for Bash).
  • Provides a summary of installed packages, versions, and next steps.

5. Windows‑Specific Nuances

5.1 Path Length and Environment Variable Limits

Windows traditionally limits path lengths to 260 characters. The guide recommends enabling Long Paths in the Group Policy editor or via registry:

Computer Configuration → Administrative Templates → System → Filesystem → Enable Win32 long paths

For older Windows versions (pre‑Windows 10 1703), the script will warn and suggest updating.

5.2 Docker Desktop vs. Docker Engine

The script installs Docker Desktop on Windows for a GUI interface, but also installs docker CLI tools for command‑line usage. It configures Docker to use WSL 2 as its backend:

& 'C:\Program Files\Docker\Docker\DockerCli.exe' -SwitchDaemon

This is necessary for file‑system performance and interoperability with WSL.

5.3 PowerShell vs. Bash

While the script itself is a Bash script, the article recommends converting the installation to a PowerShell script (install.ps1) for native Windows. This includes:

  • Using choco install for packages.
  • Using Set-ItemProperty to edit the registry for Docker integration.
  • Adding aliases via $PROFILE.

5.4 Security and Execution Policy

Because the script is executed remotely, the article emphasizes:

  • Checking the GitHub commit SHA before executing.
  • Using Invoke-WebRequest in PowerShell to download the script with a hash check.
  • Setting ExecutionPolicy RemoteSigned to allow local scripts.

6. Troubleshooting Common Issues

| Symptom | Likely Cause | Fix | |---------|--------------|-----| | brew: command not found | Homebrew not installed or PATH mis‑configured | Re‑run Homebrew install, add /opt/homebrew/bin to PATH | | apt: command not found | Debian/Ubuntu not detected; running on a non‑APT distro | Use dnf for Fedora or pacman for Arch | | Docker fails to start | Docker Desktop not installed, or WSL 2 not enabled | Install Docker Desktop, enable WSL 2, restart machine | | node: command not found | Node not installed; brew install node failed | Check brew logs node for errors, install manually | | git: command not found | Git missing or mis‑installed | Install via Homebrew/Chocolatey, verify git --version | | Permission denied during source build | User lacks sudo rights or build directories not writable | Run sudo for install, or change ownership of build directories | | aws: command not found | AWS CLI not installed | Verify aws --version, reinstall via Homebrew or pip | | SSL certificate problem: unable to get local issuer certificate | curl unable to verify GitHub SSL | Add -k flag temporarily (not recommended) or update CA certificates |

The article also provides a log‑capture command to share with support:

jcode-install.log

The script writes detailed logs to /var/log/jcode-install.log (Linux/macOS) or C:\ProgramData\jcode-install.log (Windows).


7. Security Considerations

  1. Trusting Remote Scripts: The one‑liner executes code from an external source. The article recommends verifying the script’s signature or SHA‑256 hash before execution.
  2. Least Privilege: The script only uses sudo for system‑wide changes. User‑level tools are installed in the user’s home directory when possible.
  3. Network Access: The script requires outbound HTTPS to download packages. For air‑gapped environments, the article describes how to create a local package mirror and point the script to it.
  4. Audit Trails: The script logs every installation step, making it easy to audit which packages were installed and when.
  5. Rollback: For Homebrew, the script runs brew uninstall <pkg> if a newer version fails to install. For manual installs, the article suggests backing up config files.

8. Advanced Customizations

8.1 Custom Provider Profiles

Users can create multiple provider profile files (aws.json, azure.json, docker.json) and specify which one to use via an environment variable:

export JCODE_PROVIDER=aws

The script will load ~/.jcode/aws.json and install only the providers listed there.

8.2 Version Pinning

To avoid breaking changes, the script supports pinning specific package versions. In the provider JSON:

"node": "16.14.2",
"python": "3.11.4"

The installer will explicitly install those versions via brew install node@16.14.2 or apt install python3=3.11.4.

8.3 Proxy Support

For corporate environments behind a proxy, the article outlines adding:

export http_proxy="http://proxy.example.com:3128"
export https_proxy="https://proxy.example.com:3128"

Both the script and the package managers will honor these variables.

8.4 Container‑Friendly Install

When running inside Docker, the script can be invoked with --docker to skip installing Docker itself, only setting up other tools. This is handy for building base images.


9. Integration with CI/CD Pipelines

The article demonstrates how to integrate the installer into Jenkins, GitHub Actions, or GitLab CI. Key steps:

  1. Add the installer to the repository (as a shell script) or reference the GitHub URL.
  2. Run the installer as a pre‑step in the pipeline job.
  3. Export environment variables to ensure tools like Terraform or Docker can authenticate.
  4. Cache dependencies: Use the package manager’s caching mechanism (apt, yum, brew) to speed up subsequent runs.

Example GitHub Actions snippet:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install JCode
        run: |
          curl -fsSL https://raw.githubusercontent.com/1jehuang/jcode/master/scripts/install.sh | bash
      - name: Run Tests
        run: make test

The article stresses using a runs-on: self-hosted runner if you need a consistent environment across projects.


10. Comparison with Other Toolchains

The article briefly compares the install.sh bootstrapper to other popular developer environment setups:

| Tool | Pros | Cons | |------|------|------| | Homebrew + Manual Install | Fine‑grained control | More commands | | Chocolatey + PowerShell | Native Windows | Requires PowerShell | | Ansible Playbook | Declarative, idempotent | Requires Ansible | | Docker‑based dev container | Reproducible | Requires Docker | | The JCode Installer | One‑liner, cross‑platform, provider‑aware | Trust issues, fewer customizations out of the box |

The article concludes that the JCode installer strikes a balance between convenience and control, especially for developers who work across macOS, Linux, and Windows.


11. Summary of Key Takeaways

  1. The one‑liner is a powerful, cross‑platform bootstrapper that installs core development tools, optional providers, and sets up environment variables.
  2. Platform detection is baked in; the script tailors its actions to macOS, Linux, or Windows (WSL).
  3. Provider configuration is optional and driven by a JSON file, giving users fine‑grained control over which cloud or container tools are installed.
  4. Source builds are available for bleeding‑edge developers who prefer compiling from source over binaries.
  5. Security and auditability are considered: logs, hash checks, and minimal privilege usage.
  6. The installer can be integrated into CI/CD pipelines or managed by automation agents, making it suitable for both individual developers and teams.
  7. Advanced customizations such as version pinning, proxy support, and multiple provider profiles are supported.
  8. Windows users can use native Chocolatey installs or WSL for a Unix‑like experience.
  9. Troubleshooting guidelines are thorough, covering common installation failures and providing log paths.

Overall, the article presents a comprehensive, actionable guide that lowers the barrier to entry for setting up a robust development environment across diverse operating systems. By leveraging a single script that intelligently manages dependencies, providers, and environment configuration, developers can quickly get up to speed without wading through platform‑specific documentation.


12. Final Thoughts

The guide is an example of how automation can dramatically simplify the complex dance of installing and configuring a developer toolkit in heterogeneous environments. The emphasis on security (hash verification, minimal sudo usage), flexibility (source builds, provider profiles), and integration (CI/CD, automation agents) reflects the realities of modern software development.

For teams that value repeatable, version‑controlled setups, adopting a script like install.sh can save countless hours and reduce the risk of “works on my machine” problems. At the same time, the article responsibly warns against blindly trusting remote scripts and provides clear paths to audit, customize, and secure the installation process.

By following the step‑by‑step instructions, paying close attention to platform‑specific nuances, and leveraging the troubleshooting section, readers should be able to achieve a fully functional, provider‑ready development environment on macOS, Linux, or Windows within minutes.

Read more