Show HN: New Harness in Town
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:
- Detects the operating system (macOS, Linux, or Windows with WSL).
- Installs or verifies essential command‑line tools (e.g.,
git,python,node,docker, etc.). - Installs a package manager (Homebrew on macOS, apt/yum/dnf on Linux, Chocolatey on Windows).
- Pulls in user‑defined “providers” (e.g., AWS CLI, Azure CLI, Docker‑Compose, Terraform) from a configuration file or environment variables.
- Configures environment variables (PATH, LANG, etc.) and shell profiles (zsh, bash).
- 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
- Prerequisites: Xcode Command‑Line Tools, default shell (zsh in macOS Catalina+).
- 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).
- Path Configuration: The guide ensures
/opt/homebrew/bin(Apple Silicon) or/usr/local/bin(Intel) is inPATH. - Optional Tools:
jq,ffmpeg,cmake,clang,wget. - Security: Uses
sudoonly 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) orsudo dnf update -y(Fedora). - Install Essentials:
sudo apt install -y build-essential git curl wgetor 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
sudoby adding the user to thedockergroup.
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:
PATHupdated 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.exeexists; if not, runs the PowerShell install command. - APT: Assumes
aptis available; otherwise, falls back toyumordnf.
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:
- Clones the repository:
git clone https://github.com/.../project.git. - Runs build commands:
./configure,make,make install. - 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
~/bintoPATH. - 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
hashcache (hash -rfor 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 installfor packages. - Using
Set-ItemPropertyto 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-WebRequestin PowerShell to download the script with a hash check. - Setting
ExecutionPolicy RemoteSignedto 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
- 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.
- Least Privilege: The script only uses
sudofor system‑wide changes. User‑level tools are installed in the user’s home directory when possible. - 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.
- Audit Trails: The script logs every installation step, making it easy to audit which packages were installed and when.
- 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:
- Add the installer to the repository (as a shell script) or reference the GitHub URL.
- Run the installer as a pre‑step in the pipeline job.
- Export environment variables to ensure tools like Terraform or Docker can authenticate.
- 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
- The one‑liner is a powerful, cross‑platform bootstrapper that installs core development tools, optional providers, and sets up environment variables.
- Platform detection is baked in; the script tailors its actions to macOS, Linux, or Windows (WSL).
- Provider configuration is optional and driven by a JSON file, giving users fine‑grained control over which cloud or container tools are installed.
- Source builds are available for bleeding‑edge developers who prefer compiling from source over binaries.
- Security and auditability are considered: logs, hash checks, and minimal privilege usage.
- The installer can be integrated into CI/CD pipelines or managed by automation agents, making it suitable for both individual developers and teams.
- Advanced customizations such as version pinning, proxy support, and multiple provider profiles are supported.
- Windows users can use native Chocolatey installs or WSL for a Unix‑like experience.
- 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.