Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .commitlintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ extends:
- '@commitlint/config-conventional'

rules:
# Scopes are project-specific (see nodeup.md §12). We allow a small
# extra set: "deps" for dependency bumps, "release" for release-prep
# commits.
# Scopes are project-specific. The core set comes from the package
# layout (detector, cli, platform, ...); extras: "deps" for
# dependency bumps, "release" for release-prep commits.
scope-enum:
- 2
- always
Expand All @@ -29,7 +29,7 @@ rules:
- ci
- docs
- lint
# Type whitelist matches nodeup.md §12 exactly.
# Type whitelist matches Conventional Commits.
type-enum:
- 2
- always
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Who benefits from this? What's the workflow it unlocks?

## Out-of-scope check

Some things are explicitly out of scope for v1 (see [`nodeup.md`](../../nodeup.md) §3). Is your request covered there?
Some things are explicitly out of scope for v1 — at minimum: `.nvmrc` / `.node-version` management, updating `npm` itself, `yarn`/`pnpm` global packages, and `nodeup` self-updates. If your request falls in one of these buckets, comment on the existing tracking issue instead.

- [ ] Yes — I'll comment on the existing tracking issue instead
- [ ] No — this is a new request
Expand Down
2 changes: 0 additions & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
# - A GitHub Release titled `v<version>` with changelog and all artifacts
# - A homebrew formula pushed to github.com/dipto0321/homebrew-tap
# - A scoop manifest pushed to github.com/dipto0321/scoop-bucket
#
# See nodeup.md §15 for the rationale behind these choices.

version: 2

Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Consolidated the internal `nodeup.md` design doc into `README.md`
(new "Compatibility notes" subsection, expanded Contributing
conventions) and stripped the now-dangling `nodeup.md` references
from source, config, docs, and issue templates. The file is removed.

### Added
- Initial project scaffolding (`chore: initial project scaffolding`)
- Cobra-based CLI with `upgrade`, `check`, `list`, `packages`, `config`, `version` subcommands
Expand All @@ -22,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.0.0] - 2024-07-01

### Added
- Project blueprint (`nodeup.md`) — design doc covering language choice, scope, detection engine, version resolution, package migration, architecture, CLI design, edge cases, git workflow, conventional commits, versioning, CI/CD, and distribution
- Project blueprint — internal design doc covering language choice, scope, detection engine, version resolution, package migration, architecture, CLI design, edge cases, git workflow, conventional commits, versioning, CI/CD, and distribution. (Superseded by `README.md`; the standalone doc was removed in the Unreleased section.)

[Unreleased]: https://github.com/dipto0321/nodeup/compare/v0.0.0...HEAD
[0.0.0]: https://github.com/dipto0321/nodeup/releases/tag/v0.0.0
59 changes: 47 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ them over, and (optionally) cleans up — all interactively, all resumable.
- 🧪 **Dry-run mode** — see the plan before anything changes
- 🔌 **Zero lock-in**: works on top of your existing manager, doesn't replace it

## Compatibility notes

A few things worth knowing before you run `nodeup`:

- **`nvm` is a shell function, not a binary** — `nodeup` transparently
sources `~/.nvm/nvm.sh` (or `$NVM_DIR/nvm.sh`) before calling it. No
setup required.
- **Multiple managers installed?** `nodeup` prompts you to pick one
the first time and remembers it in `~/.nodeup/config.yaml`. You can
override per-invocation with `--manager <name>`.
- **System Node (e.g. installed via Homebrew, apt, or the Windows
installer) is detected but cannot be upgraded** — install a version
manager first if you want `nodeup` to manage it.
- **Bundled packages are always skipped during migration**: `npm`,
`corepack`, and `npx` ship with Node itself and are not reinstalled.
- **Native addons may need a rebuild** after a major Node version
bump. If something like `node-sass` or `sharp` misbehaves, run
`npm rebuild -g` against the new version.
- **Concurrent runs are blocked** via a lock file at
`~/.nodeup/nodeup.lock`. If a run crashes mid-upgrade, the next
invocation offers to restore from the snapshot written at the start.

## Installation

### Homebrew (macOS, Linux)
Expand Down Expand Up @@ -122,7 +144,7 @@ Run `nodeup <command> --help` for the full flag reference.

## How it works

See [`nodeup.md`](./nodeup.md) for the full design doc. In short:
In short:

1. **Detect** which version manager(s) are installed
2. **Resolve** to a single manager (prompt if multiple)
Expand Down Expand Up @@ -161,24 +183,37 @@ full schema.

## Project status

This is the **v1.0.0 development line**. See [`nodeup.md`](./nodeup.md) for the
phased execution plan and `CHANGELOG.md` for what's done.
This is the **v1.0.0 development line**. See `CHANGELOG.md` for what's done.

| Version | Status | Notes |
|---|---|---|
| v1.0.0 | 🛠 in development | Initial release: all managers, all platforms |

## Contributing

Contributions welcome! See [`CONTRIBUTING.md`](./CONTRIBUTING.md) (TBD) and the
branching / commit conventions in [`nodeup.md`](./nodeup.md) §11–§12.

TL;DR:

- Branch from `main`: `feat/<scope>/<short-desc>`, `fix/<scope>/<short-desc>`, etc.
- Conventional Commits: `feat(detector): add Volta support`
- One PR per logical change
- CI must be green; `make ci` runs everything locally
Contributions welcome! A `CONTRIBUTING.md` will land alongside Phase 5; in the
meantime, this is the working contract.

**Branching.** Branch from `main` using one of:
`feat/<scope>/…`, `fix/<scope>/…`, `chore/<scope>/…`,
`docs/…`, `ci/…`, `test/<scope>/…`, `refactor/<scope>/…`.
`main` is protected — every change goes through a PR and is squash-merged
with the source branch deleted. Releases are tag-driven: pushing a
`v*.*.*` tag fires the GoReleaser workflow.

**Commit messages — Conventional Commits.** Type and scope are
enforced by commitlint in CI.

- Allowed **types**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`,
`test`, `build`, `ci`, `chore`, `revert`.
- Allowed **scopes**: `detector`, `manager`, `packages`, `node`, `config`,
`ui`, `platform`, `cli`, `deps`, `release`, `ci`, `docs`, `lint`.
- **Breaking changes** use the `!` marker in the type/scope header and a
`BREAKING CHANGE:` footer in the body, e.g.
`feat(config)!: drop legacy manager=auto key`.

**Pull requests.** One PR per logical change. CI must be green; `make ci`
runs everything locally.

## License

Expand Down
4 changes: 1 addition & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,4 @@ Resolution precedence (highest first):
| `packages.skip` | []string | `[npm, corepack, npx]` | Packages to never migrate |
| `cleanup.auto` | bool | `false` | Auto-remove old versions |
| `cleanup.prompt` | bool | `true` | Ask before removing each old version |
| `cache.ttl` | int | `3600` | Cache TTL in seconds |

See `nodeup.md` §9 for the design rationale.
| `cache.ttl` | int | `3600` | Cache TTL in seconds |
2 changes: 0 additions & 2 deletions docs/managers.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ priority order — earlier managers win when multiple are installed.
~/.nvm/nvm.sh && nvm <cmd>"` so the function is loaded.
3. **Strategy B (fallback):** Use a binary wrapper if one is installed.

See `nodeup.md` §5 for the rationale.

## Locking to a specific manager

```bash
Expand Down
7 changes: 3 additions & 4 deletions internal/cli/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import "github.com/spf13/cobra"

// newCheckCmd is a stub for Phase 0. It will be implemented in Phase 2.
//
// See nodeup.md §6 (Node.js Version Resolution) — it calls the
// nodejs.org/dist/index.json endpoint, resolves the latest LTS and
// Current versions, and prints them alongside the user's installed
// versions without making any changes.
// It calls the nodejs.org/dist/index.json endpoint, resolves the latest
// LTS and Current versions, and prints them alongside the user's
// installed versions without making any changes.
func newCheckCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "check",
Expand Down
1 change: 0 additions & 1 deletion internal/cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import "github.com/spf13/cobra"

// newConfigCmd is a stub for Phase 0. It will be implemented in Phase 5.
//
// See nodeup.md §9 (CLI Design — nodeup config set/get/show).
// The config file lives at ~/.nodeup/config.yaml and stores the manager
// preference, tracked channels, migration strategy, cleanup policy,
// and cache TTL.
Expand Down
5 changes: 2 additions & 3 deletions internal/cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import "github.com/spf13/cobra"

// newListCmd is a stub for Phase 0. It will be implemented in Phase 1.
//
// See nodeup.md §5 (Version Manager Detection Engine). The command
// delegates to the detected manager's native "list" command, or
// enumerates versions directly from the manager's data directory.
// The command delegates to the detected manager's native "list" command,
// or enumerates versions directly from the manager's data directory.
func newListCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "github.com/spf13/cobra"

// newPackagesCmd is a stub for Phase 0. It will be implemented in Phase 3.
//
// See nodeup.md §7 (Global Package Migration). Subcommands:
// Subcommands:
//
// nodeup packages snapshot — capture global npm packages for the active version
// nodeup packages list — list packages for a snapshot
Expand Down
5 changes: 2 additions & 3 deletions internal/cli/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import (

// newUpgradeCmd is a stub for Phase 0. It will be implemented in Phase 4.
//
// See nodeup.md §4 (Core Algorithm) and §9 (CLI Design) for the planned
// behavior: detect manager → fetch versions → diff → snapshot → install →
// migrate → cleanup.
// Planned behavior: detect manager → fetch versions → diff → snapshot →
// install → migrate → cleanup.
func newUpgradeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "upgrade",
Expand Down
4 changes: 2 additions & 2 deletions internal/cli/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
//
// It prints the version, git commit, build date, and runtime info (Go
// version, OS, architecture). The --check flag is reserved for a future
// self-update mechanism (out of scope for v1.0.0 per nodeup.md §3).
// self-update mechanism (out of scope for v1.0.0).
func newVersionCmd(version, commit, date string) *cobra.Command {
var check bool

Expand All @@ -33,7 +33,7 @@ Example:
fmt.Fprintf(out, " platform: %s/%s\n", runtime.GOOS, runtime.GOARCH)

if check {
// Self-update is a v2 feature (see nodeup.md §3 "Out of Scope").
// Self-update is a v2 feature — out of scope for v1.
// We intentionally do nothing here but make the flag a
// no-op rather than failing, so user scripts that pre-set
// the flag don't break.
Expand Down
3 changes: 2 additions & 1 deletion internal/detector/asdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import (
)

// ASDF is the asdf-vm implementation (https://asdf-vm.com) with the
// nodejs plugin installed. See nodeup.md §5 for the detection strategy.
// nodejs plugin installed. See internal/detector/detector.go for the
// Manager interface contract.
//
// ASDF is a true binary (unlike NVM). Its installed Node versions are
// queryable via `asdf list nodejs`, which is more reliable than parsing
Expand Down
3 changes: 2 additions & 1 deletion internal/detector/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import (
var ErrNoManager = errors.New("no Node.js version manager detected")

// Manager is the abstraction every concrete manager implementation
// satisfies. See nodeup.md §5 for the full contract.
// satisfies. See the doc comments on individual Manager methods for
// the full contract.
type Manager interface {
// Name returns the canonical short name: "fnm", "nvm", "volta", ...
Name() string
Expand Down
4 changes: 2 additions & 2 deletions internal/detector/fnm.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/dipto0321/nodeup/internal/platform"
)

// FNM is the Fast Node Manager implementation. See nodeup.md §5 for the
// detection strategy and the supported command surface.
// FNM is the Fast Node Manager implementation. See
// internal/detector/detector.go for the Manager interface contract.
//
// Phase 1 implements the detection surface only:
// - Detect : cheap PATH probe via exec.LookPath
Expand Down
5 changes: 3 additions & 2 deletions internal/detector/nvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import (
)

// NVM is the Node Version Manager implementation. nvm is unusual because
// it is a SHELL FUNCTION, not a binary. See nodeup.md §5 "The nvm Special
// Case" for the three strategies we use.
// it is a SHELL FUNCTION, not a binary — NVM is a shell function
// wrapper around the real `nvm` script, so we must source it before
// running any subcommand.
//
// Strategy C is used for reads (parse ~/.nvm/versions/node/* directly).
// For mutating operations (install, uninstall, use) we will fall back to
Expand Down
4 changes: 2 additions & 2 deletions internal/detector/volta.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (
// Volta is the Volta implementation (https://volta.sh). Volta is a true
// binary (unlike NVM, which is a shell function), but it stores Node
// installs in a fixed on-disk layout under $VOLTA_HOME rather than
// advertising them through a CLI query. See nodeup.md §5 for the full
// detection strategy.
// advertising them through a CLI query. See
// internal/detector/detector.go for the Manager interface contract.
//
// Volta's on-disk layout (v2.x, "v4" internal layout):
//
Expand Down
Loading
Loading