Skip to content
kent010341Public

About

CLI for managing grouped hostnames and switching between targets.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

hostman

Manage project hostnames together and switch them between local, lab, or production IPs. For example, switch both foo.test and api.foo.test to another environment with one command.

New here or unsure what to do? Just run hostman. Its interactive menu is the recommended way to get started: choose an action and follow the prompts without memorizing commands.

Install

You need Node.js 24 or newer and npm. Hostman runs on Windows, Linux, and macOS.

Build and install from source. These commands work in PowerShell and Unix shells:

git clone https://github.com/kent010341/hostman.git
cd hostman
npm ci
npm run build
npm link
hostman --help

Keep the checkout while using this linked installation. To install from a supplied package instead:

npm install --global ./hostman-1.0.0.tgz
hostman --help

To uninstall, run npm uninstall --global hostman.

Get started

Start with the interactive menu (recommended)

After installation, open a terminal and run:

hostman

The menu lets you initialize management, import existing rules, manage groups and hostnames, switch targets, and more. Select an action, then follow its prompts for the required inputs. You can return to this menu whenever you are unsure which command to use.

The command examples below provide direct alternatives for common workflows. Commands also prompt for missing inputs in an interactive terminal. Without interactive input and output, hostman shows help instead of the menu; scripts must supply complete command arguments.

Already have custom hosts rules?

Preview what hostman can import, then select the groups you want to manage:

hostman migrate --dry-run
hostman migrate
hostman show all

You do not need to run init first. A hostname such as api.foo.test becomes part of the foo.test group. Migration imports effective rules and commented rules such as #127.0.0.1 api.foo.test. Each distinct IP reuses a matching global or becomes a literal target, with default names imported, imported-2, and so on. Interactive imports let you name each new literal target; press Enter to accept its default. Multiple matching globals require a terminal choice or --global <name> in scripts. Existing groups retain their active selection and target definitions. Hostnames are combined across destinations. One effective IP enables the new group and selects that target. Commented-only groups start disabled.

Run hostman migrate again whenever you add more rules manually. Multiple effective IPs or conflicts with an existing group's active IP are skipped with source details; fix those rules before trying again. The preview uses a separate READY or SKIP block for each group. Skipped groups show the reason and original source line numbers, while eligible groups list their targets, hostnames and proposed active state.

Starting a new project?

Create a group pointing to your local machine, then add a lab target:

hostman init
hostman add group foo.test --target local=127.0.0.1
hostman add host foo.test api
hostman target add foo.test lab 10.20.0.10
hostman show foo.test
hostman use foo.test lab

This creates foo.test and api.foo.test. The first target, local, is initially active. The final command switches both names to the lab IP. Replace the example domain and IPs with your own.

Without --host, add group includes the root hostname (foo.test) automatically. To choose the initial hostnames explicitly, use --host @ --host api for the root and api.foo.test, or --host api for only api.foo.test.

Permissions: when writing system hosts, an interactive terminal may show Windows UAC or request your sudo password. Approve it to save the changes; cancelling leaves the file unchanged.

Common tasks

The examples below assume that foo.test is already managed.

See what is active

hostman show
hostman show all
hostman show foo.test

Use show for enabled groups, show all to include disabled groups, and show <group> for its hosts and targets.

Add an environment and switch to it

hostman target add foo.test prod 10.30.0.10
hostman use foo.test prod
hostman target set foo.test prod 10.30.0.20

target add defines a destination; use selects it. target set changes an existing destination's IP. If that target is active, all enabled hosts in the group update immediately.

Rename destinations while preserving their IPs and selections:

hostman target rename example.com local dev
hostman global rename local shared

Group target renames update the active selection when needed. Global renames update every direct @local selection, including disabled groups, while preserving group-owned targets and all IPs. Replacement names must be valid and unused in their scope. Renaming a target to its current name makes no changes when its managed state is clean. In an interactive terminal, omit the existing target name to select it from a list, then enter its new name.

To add a local destination to an imported group:

hostman target add foo.test local 127.0.0.1
hostman use foo.test local

Add or remove a hostname

hostman add host foo.test admin
hostman remove host foo.test admin

Use @ for foo.test, api for api.foo.test, or a full name such as admin.foo.test. In an interactive terminal, omit the hostname from remove host to select a full hostname from the group's list.

Temporarily turn a project off

hostman disable foo.test
hostman enable foo.test

Disabling removes the group's effective mappings while keeping its hosts and targets for later use.

Share one target across projects

hostman global add local 127.0.0.1
hostman use foo.test '@local'
hostman global set local 192.168.50.21

Select a global directly with @name; no group target needs to be created first. The Switch target menu also lists all global targets with their IPs. Changing a global IP updates every enabled group selecting it. local selects a group-owned target; @local selects the global even when both have the same name.

You can create a group using only a global destination:

hostman add group example.com --active '@local' --host '@' --host api

In a terminal, hostman add group example.com --host '@' offers existing globals first, displaying each IP. Press Enter to use the first global, or choose the final Enter a new group target option to enter a literal target name and IP. Selecting a global creates no group-owned targets. With no globals, the menu offers only manual entry. Explicit --target or --active options skip this menu; scripts must supply destination flags.

Group targets created with target add/set or --target name=IP accept literal IPs only. Omit the existing target name from target set or global set in an interactive terminal to select its name and IP from a list before entering the replacement IP. New target names still use text input.

Clean duplicate destinations

Preview and clean one group's targets, or deduplicate globals separately:

hostman target clean example.com --dry-run
hostman target clean example.com
hostman global clean --dry-run
hostman global clean

Group cleanup removes literal targets whose IP matches a global and switches an active literal to that global. It also keeps one local target per remaining duplicate IP. The terminal asks which name to retain. Scripts retain the active local target, or the first definition when none is active; use --keep example.com=lab to override. Multiple matching globals require a choice; scripts supply --global local. Group cleanup has no --all option. The enabled state, hostnames and selected IP stay the same. Choosing a global makes future global IP changes apply to the group.

Global cleanup keeps one global per duplicate IP and redirects direct selections, including disabled groups. It leaves all group-owned targets intact. Scripts must specify one --keep <name> per duplicate IP, for example hostman global clean --keep local. Both clean commands support repeated selection flags and no-write dry runs. Dry runs show unresolved choices without prompting. For migration, use hostman migrate --all --global local when multiple globals match an imported destination; migration leaves existing target definitions intact.

Remove a target or project

hostman use foo.test local
hostman target remove foo.test prod
hostman remove group foo.test

Switch away from a target before removing it. Removing a group deletes its managed hosts and target definitions. Remove a global with hostman global remove <name> after switching every group selecting it to another destination. Disabled groups also retain their selection and prevent removal. Omit the target name from target remove or global remove in an interactive terminal to select from a list. Protected targets remain visible but disabled, with their active selection or referencing groups shown. If no target can be removed, the command explains how to switch selections first.

Resolve changes made by hand

hostman show foo.test
hostman repair foo.test

Use migrate for rules added outside hostman's markers. Use repair when changes inside a managed group conflict with its target. Repair offers available resolutions; malformed markers may require manual correction.

Help and another hosts file

Every command has help, including nested commands:

hostman --help
hostman migrate --help
hostman target set --help

In an interactive terminal, commands suggest relevant next steps using your group and target names. For example, after add group, you can copy a command to add a hostname to that group. Suggestions keep your custom hosts file path. Use hostman --no-hints <command> to hide them; scripts omit them automatically. Command help also includes related command examples.

Hostman uses the system hosts file by default: $env:SystemRoot\System32\drivers\etc\hosts on Windows, or /etc/hosts on Linux/macOS. To work with an existing custom file, put its path before the command:

hostman --hosts-file "./sample hosts" migrate --dry-run
hostman --hosts-file "./sample hosts" show all

For scripts, supply complete arguments and use migrate --group foo.test or migrate --all for explicit imports. Scripts must already have write permission; automatic elevation only runs in an interactive terminal. --no-elevate disables it there too.

Further reading

About

CLI for managing grouped hostnames and switching between targets.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages