CLI for building powerful aliases

Travis (.com) Go Report Card Coveralls github GitHub Mentioned in Awesome Go

nostromo-mess-hall

nostromo

nostromo is a CLI to manage aliases through simple commands to add and remove scoped aliases and substitutions.

nostromo

Managing aliases can be tedious and difficult to set up. nostromo makes this process easy and reliable. The tool adds shortcuts to your .bashrc / .zshrc that call into the nostromo binary. It reads and manages all aliases within its manifest. This is used to find and execute the actual command as well as swap any substitutions to simplify calls.

nostromo can help you build complex tools in a declarative way. Tools commonly allow you to run multi-level commands like git rebase master branch or docker rmi b750fe78269d which seem clear to use. Imagine if you could wrap your aliases / commands / workflow into custom commands that describe things you do often. Well, now you can with nostromo. 🤓

With nostromo you can take aliases like these:

alias ios-build='pushd $IOS_REPO_PATH;xcodebuild -workspace Foo.xcworkspace -scheme foo_scheme'
alias ios-test='pushd $IOS_REPO_PATH;xcodebuild -workspace Foo.xcworkspace -scheme foo_test_scheme'
alias android-build='pushd $ANDROID_REPO_PATH;./gradlew build'
alias android-test='pushd $ANDROID_REPO_PATH;./gradlew test'

and turn them into declarative commands like this:

build ios
build android
test ios
test android

The possibilities are endless and up to your imagination with the ability to compose commands as you see fit.

Getting Started

Prerequisites

  • Works for MacOS and bash / zsh shells (other combinations untested but may work)

Installation

Using brew:

brew tap pokanop/pokanop
brew install nostromo

Using go get:

go get -u github.com/pokanop/nostromo

Initialization

This command will initialize nostromo and create a manifest under ~/.nostromo:

nostromo init

To customize the directory (and change it from ~/.nostromo), set the NOSTROMO_HOME environment variable to a location of your choosing.

To destroy the manifest and start over you can always run:

nostromo destroy

Key Features

  • Simplified alias management
  • Scoped commands and substitutions
  • Build complex command trees
  • Shell completion support
  • Preserves flags and arguments
  • Execute code snippets

Usage

Managing Aliases

Aliases to commands is one of the core features provided by nostromo. Instead of constantly updating shell profiles manually, nostromo will automatically keep it updated with the latest additions.

Given that nostromo is not a shell command there are some things to note on how it makes its magic:

  • Commands are generated by nostromo and executed using the eval method in a shell function.
  • Commands and changes will be available immediately since nostromo reloads completions automatically

If you want create boring standard shell aliases you can do that with an additional flag or a config setting described below.

To add an alias (or command in nostromo parlance), simply run:

nostromo add cmd foo "echo bar"

And just like that you can now run foo like any other alias.

Descriptions for your commands can easily be added as well:

nostromo add cmd foo "echo bar" -d "My magical foo command that prints bar"

Your descriptions will show up in the shell when autocompleting!

Interactive Mode

You can also add commands and substitutions interactively by using just nostromo add without any arguments. This command will walk through prompts to guide adding new commands easily.

nostromo

Keypaths

nostromo uses the concept of keypaths to simplify building commands and accessing the command tree. A keypath is simply a . delimited string that represents the path to the command.

For example:

nostromo add cmd foo.bar.baz 'echo hello'

will build the command tree for foo 👉 bar 👉 baz such that any of these commands are now valid (of course the first two do nothing yet 😉 ):

foo
foo bar
foo bar baz

where the last one will execute the echo command.

You can compose several commands together by adding commands at any node of the keypath. The default behavior is to concatenate the commands together as you walk the tree. Targeted use of ; or && can allow for running multiple commands together instead of concatenating. More easily, you can change the command mode for any of the commands to do this for you automatically. More info on this later.

Shell Aliases

nostromo allows users to manage shell aliases. By default, all commands are designed to execute the nostromo binary and resolve a command to be evaluated in the shell. This allows you to run those declarative commands easily like foo bar baz in the shell. nostromo only creates an alias as a shell function for the root command foo and passes the remaining arguments to nostromo eval to evaluate the command tree. The result of that is executed with eval in the shell. Standard shell aliases do not get this behavior.

The use of standard shell aliases provides limited benefit if you only want single tiered aliases. Additionally, nostromo commands persist in the shell since they are evaluated (i.e., changing directories via cd).

There are two methods for adding aliases to your shell profile that are considered standard aliases:

  • Use the --alias-only or -a flag when using nostromo add cmd
  • Set the aliasesOnly config setting to affect all command additions

For example, you can see both methods here:

nostromo add cmd foo.bar.baz "cd /tmp" --alias-only

nostromo manifest set aliasesOnly true
nostromo add cmd foo.bar.baz "cd /tmp"

Adding a standard alias will produce this line that gets sourced:

alias foo.bar.baz='cd /tmp'

instead of a nostromo command which adds a shell function:

foo() { eval $(nostromo eval foo "$*") }

Notice how the keypath has no affect in building a command tree when using the alias only feature. Standard shell aliases can only be root level commands.

Scoped Commands & Substitutions

Scope affects a tree of commands such that a parent scope is prepended first and then each command in the keypath to the root. If a command is run as follows:

foo bar baz

then the command associated with foo is concatenated first, then bar, and finally baz. So if these commands were configured like this:

nostromo add cmd foo 'echo oof'
nostromo add cmd foo.bar 'rab'
nostromo add cmd foo.bar.baz 'zab'

then the actual execution would result in:

echo oof rab zab

Standard behavior is to concatenate but you can easily change this with the mode flag when using add or globally. More information under Execution Modes.

Substitutions

nostromo also provides the ability to add substitutions at each one of these scopes in the command tree. So if you want to shorten common strings that are otherwise long into substitutions, you can attach them to a parent scope and nostromo will replace them at execution time for all instances.

A substitution can be added with:

nostromo add sub foo.bar //some/long/string sls

Subsequent calls to foo bar would replace the subs before running. This command:

foo bar baz sls

would finally result in the following since the substitution is in scope:

oof rab zab //some/long/string

Complex Command Tree

Given features like keypaths and scope you can build a complex set of commands and effectively your own tool 🤯 that performs additive functionality with each command node.

You can get a quick snapshot of the command tree using:

nostromo manifest show

With nostromo, you can also visualize the command tree (or manifest) in several other ways including as json, yaml and a tree itself.

nostromo

Setting the verbose config item prints more detailed information as well.

nostromo

Execution Modes

A command's mode indicates how it will be executed. By default, nostromo concatenates parent and child commands along the tree. There are 3 modes available to commands:

  concatenate  Concatenate this command with subcommands exactly as defined
  independent  Execute this command with subcommands using ';' to separate
  exclusive    Execute this and only this command ignoring parent commands

The mode can be set when adding a command with the -m or --mode flag:

nostromo add cmd foo.bar.baz -m exclusive "echo baz"

A global setting can also be set to change the mode from the default concatenate with:

nostromo manifest set mode independent

All subsequent commands would inherit the above mode if set.

Shell Completion

nostromo provides completion scripts to allow tab completion. This is added by default to your shell init file:

eval "$(nostromo completion)"

Even your commands added by nostromo get the full red carpet treatment with shell completion. Be sure to add a description and tab completion will show hints at each junction of your command. Cool right! 😎

Execute Code Snippets

nostromo provides the ability to supply code snippets in the following languages for execution, in lieu of the standard shell command:

  • ruby - runs ruby interpreter
  • python - runs python interpreter
  • js - runs node
  • perl - runs perl interpreter
nostromo add cmd foo --code 'console.log("hello js")' --language js

For more complex snippets you can edit ~/.nostromo/manifest.yaml directly but multiline YAML must be escaped correctly to work.

Credits

Contibuting

Contributions are what makes the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License.

If You ♥️ What We Do

Buy Me A Coffee

Comments
  • Having problems understanding the results.

    Having problems understanding the results.

    1. nostromo add cmd mp '/usr/bin/mpv' is ok; cmd alias is added/created
    2. nostromo add cmd mp.nr '--no-resume-playback' --- this fails with msg: "error: unknown flag: --no-resume-playback"
    3. nostromo add cmd mpnr 'mpv --no-resume-playback' --- this succeeds
    4. nostromo add cmd mpnrp '/usr/bin/mpv --no-resume-playback' -- this fails as 2) above

    nostromo doesn't like specifying the full path names of commands? But why should 1) above succeed? why should 2) above fail.

  • Configure base config location with NOSTROMO_HOME

    Configure base config location with NOSTROMO_HOME

    This change allows users to change the base location of nostromo config to a directory of their choosing, by setting the NOSTROMO_HOME environment variable in their shell.

    Closes #26

  • Support variables in aliases like $1

    Support variables in aliases like $1

    Right now I don't think nostromo supports aliases that reference $1 or $ variables. They expand immediately when running the nostromo command likely. Not sure if this is a limitation but would be great to be able to support it.

  • Passthrough autocomplete not working correctly in shell

    Passthrough autocomplete not working correctly in shell

    In zsh, it seems like nostromo commands aren't defaulting or falling back to the shell's autocomplete logic.

    I like the bat tool which is a replacement to cat. When replacing the standard command with:

    nostromo add cmd cat bat
    

    It works fine but after typing in cat and tabbing with the keyboard, it no longer tries to autocomplete the files or folders on the system.

    This really sucks for the tool and would be great to figure out why it's happening and how to fix to fallback to shell file system completions. Investigate and produce a fix.

  • fix errors on Bash for Linux by ending single line functions with semicolons

    fix errors on Bash for Linux by ending single line functions with semicolons

    I tried getting nostromo to work in Bash on Arch Linux but ran into some errors with the completion output. Turns out single line functions, really want a semicolon at the end of the statement.

    I added those semicolons and things are working in Bash and Zsh for me.

  • Allow configuration of base config location

    Allow configuration of base config location

    It'd be really great if we could customise the location (with an env variable or similar) of ~/.nostromo. I personally (even on macOS) use the XDG directory spec env variables, so being able to store configs in XDG_CONFIG_HOME (for me that's ~/.config, would be really great. Especially when #21 lands, it'd be good to potentially consider having a different location for in-use config file(s), and the shell file backups. (Potentially XDG_CACHE_HOME as that's the one for (non-essential) cached files).

    For the reading from a custom config location alone, I'd be happy to take a look at solving it, if it's something you'd like to see the project support. Happy to take suggestions on naming a custom env variable too. (NOSTROMO_CONFIG for example).

  • Bump github.com/hashicorp/go-getter from 1.5.11 to 1.6.1

    Bump github.com/hashicorp/go-getter from 1.5.11 to 1.6.1

    Bumps github.com/hashicorp/go-getter from 1.5.11 to 1.6.1.

    Release notes

    Sourced from github.com/hashicorp/go-getter's releases.

    v1.6.1

    No release notes provided.

    Commits
    • f710948 Merge pull request #362 from hashicorp/update-x/sys-for-go1.18
    • 226a8c5 Update golang.org/x/sys to work with go1.18
    • 0181334 Add apt-get update before installing dependencies (#360)
    • a2ebce9 Multiple fixes for go-getter (#359)
    • 4553965 fix(decompresser_zip): fix panic when decompressing protected zip file (#343)...
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

  • Add uuidgen command to refresh manifest identifier

    Add uuidgen command to refresh manifest identifier

    Since we need a different uuid to sync manifests, add a convenient way to update an existing manifest's identifier through the nostromo CLI. Otherwise, users would need to manually update to push or publish shared manifests.

    nostromo manifest uuidgen [name]
    

    will regenerate the uuid for the named manifest and update version info as well.

  • Add detach command to create new manifests

    Add detach command to create new manifests

    Provide a new detach command that lets users create new manifests from existing command sets.

    nostromo detach [name] [key.path]... [options]
    

    where:

    • name is the new manifest name
    • key.path is any number of key paths to match in existing manifests
    • option will include the ability to set a destination key path or default to root

    This functionality lets us split existing commands into piecemeal manifests which can be shared to others using the sync feature. Composition of manifests will allow for maximum customizability.

  • Brew formula needs updating

    Brew formula needs updating

    Warning: Calling bottle :unneeded is deprecated! There is no replacement.
    Please report this issue to the pokanop/pokanop tap (not Homebrew/brew or Homebrew/core):
      /usr/local/Homebrew/Library/Taps/pokanop/homebrew-pokanop/Formula/nostromo.rb:6
    
  • still having issues with nostromo

    still having issues with nostromo

    I have defined this command in nostromo: +--------------+-------------------------------------+ | keypath | mpnr | | alias | mpnr | | command | mpv --no-resume-playback | | code | false | | mode | concatenate | | aliasOnly | false | +--------------+-------------------------------------+ Copied these link addresses from youtube.com

    1. 'https://www.youtube.com/watch?v=LjhCEhWiKXk'
    2. 'https://www.youtube.com/watch?v=adLGHcj_fmA'

    executed the following: mpv --no-resume-playback "link address 1) above" ; ## success mpv --no-resume-playback "link address 2) above" ; ## success

    executed these: mpnr "link address 1) above" ; failed mpnr "link address 2) above" ; failed

    Error messages are same for both, as follows:

    • no matches found: 'the youtube link address specified'

    What am I doing wrong?

    Another issue (perhaps):

    I have never been able to get nostromo to process a path/filename with space characters. Unless I edit the yaml? Which I haven't done.

  • Go task synergy

    Go task synergy

    This is really cool.

    There is sone synergy for this to be used with go task. https://github.com/go-task/task

    Go task can reference the aliases!

    btw have you tried this on windows ?. It probably works on Linus , since it works on Mac

  • Must have ascii art on initialization routine

    Must have ascii art on initialization routine

    P0 feature, need to integrate this package to show a cool nostromo ascii art version on init. I mean why not.

    https://github.com/common-nighthawk/go-figure

  • Dock sources like Git or storage systems need additional processing

    Dock sources like Git or storage systems need additional processing

    go-getter seems to only be able to download entire folders or repositories/buckets likely and not a single file. So if you try to reference a single file to a private git repo like this:

    nostromo dock git::https://github.com/org/private-repo/blob/main/manifest.yaml?sshkey=<key>
    

    it'll fail. We'll need to detect these folders first and keep track of the root to download the source first into the /tmp folder, and then extract the actual file from there into the downloads/ folder for processing the merge.

    Also, have not successfully been able to clone private repo either yet, so needs investigation and fix.

  • Move config related items out of Manifest and into Spaceport

    Move config related items out of Manifest and into Spaceport

    With the addition of Theme into Spaceport it makes more sense to migrate some of the other nostromo settings out of the Manifest higher up into the Spaceport type so that way we can keep manifests isolated to containing the commands themselves.

    Spaceports can be used to drive config like log levels, global options, theming, etc. Update logging and refs to settings as well everywhere. Current options include:

    • aliasesOnly
    • backupCount
    • mode
    • theme
    • verbose
  • Dependency management for manifests

    Dependency management for manifests

    When docking a manifest using nostromo dock it pulls down one or more manifests locally. Now that we have support for multiple manifests, it will be likely that users will split functionality up with more granularity. In some cases, it could be that a manifest command may depend on another that isn't in the same manifest.

    To be able to build composable manifests, we can add a dependencies field that includes sources for other manifests. On sync functionality (sync, dock, undock) we can automatically ingest or delete these additional manifests.

    Proposed model.Manifest updates:

    struct LinkedManifest {
        UUID string
        Name string
        Source string
    }
    
    struct Manifest {
        ...
        links []*LinkedManifest
    }
    

    Store the UUID for now in case we can support versioning in the future.

    Add a new command to link manifests together:

    nostromo link <source> <target>
    

    This command, similar to dock, should download the manifest, parse it, store it, and add the dependency record in the target manifest.

    Note that care should be taken with collision detection and circular references. Need a solution to avoid problems with these scenarios.

  • Add YAML struct tags to all types

    Add YAML struct tags to all types

    Forgot to add YAML struct tags so the default marshaling will just turn CamelCase fields into lowercase like camelcase.

    This isn't nice so let's fix it to have the common convention of camel case keys.

Go-file-downloader-ftctl - A file downloader cli built using golang. Makes use of cobra for building the cli and go concurrent feature to download files.

ftctl This is a file downloader cli written in Golang which uses the concurrent feature of go to download files. The cli is built using cobra. How to

Jan 2, 2022
A powerful cli tool to implement gin annotation ⭐
A powerful cli tool to implement gin annotation ⭐

gin-annotation A powerful cli tool to implement gin annotation Chinese Document Features Using code generating technology by operating golang AST Rout

Mar 24, 2022
Powerful CLI written in GO to generate projects in various technologies
Powerful CLI written in GO to generate projects in various technologies

Barca CLI is a project generator written in GO and its purpose is to build and configure HTTP servers, web proxy, SPA/PWA, Blog and custom landing page. It's easy, fast and productive.

Aug 26, 2022
A powerful modern CLI and SHELL
A powerful modern CLI and SHELL

Grumble - A powerful modern CLI and SHELL There are a handful of powerful go CLI libraries available (spf13/cobra, urfave/cli). However sometimes an i

Dec 30, 2021
Mcli - A mininal and very powerful cli library for Go

mcli mcli is a minimal but powerful cli library for Go. m stands for minimal and

Nov 18, 2022
CLI - A package for building command line app with go
CLI - A package for building command line app with go

Command line interface Screenshot Key features Lightweight and easy to use. Defines flag by tag, e.g. flag name(short or/and long), description, defau

Dec 23, 2022
A versatile library for building CLI applications in Go

mow.cli Package cli provides a framework to build command line applications in Go with most of the burden of arguments parsing and validation placed o

Dec 28, 2022
cli is a simple, fast, and fun package for building command line apps in Go.

cli cli is a simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable comm

Jul 10, 2022
Flag is a simple but powerful command line option parsing library for Go support infinite level subcommand

Flag Flag is a simple but powerful commandline flag parsing library for Go. Documentation Documentation can be found at Godoc Supported features bool

Sep 26, 2022
A fast and powerful alternative to grep

sift A fast and powerful open source alternative to grep. Features sift has a slightly different focus than most other grep alternatives. Code search,

Jan 3, 2023
`tmax` is a powerful tool to help you get terminal cmd directly.
`tmax`  is a powerful tool to help you get terminal cmd directly.

The positioning of tmax is a command line tool with a little artificial intelligence. If you frequently deal with the terminal daily, tmax will greatly improve your work efficiency.

Oct 15, 2022
A powerful little TUI framework 🏗
A powerful little TUI framework 🏗

Bubble Tea The fun, functional and stateful way to build terminal apps. A Go framework based on The Elm Architecture. Bubble Tea is well-suited for si

Dec 27, 2022
🚀 Platform providing a powerful and fast public script parsing API dedicated to the Skript community.

SkriptMC-Parser is currently a prototype in the early stages of development of a system that allows the Skript community to test their scripts via a public API for potential errors or warnings. This is a quick and easy way to check your scripts without having to set up a Spigot server on your environment.

Mar 3, 2022
A lightweight but powerful OCR tool.
A lightweight but powerful OCR tool.

这个项目是什么? LOCR(Lightweight OCR)是一款轻量级的文字识别工具, 结合第三方截图工具, 可以快速的对图片文字进行识别。 为什么有这个项目 在日常学习的工作中, 难免会遇到一些文字的复制粘贴任务。但由于一些限制,我们无法复制想要的文字,只能一个字一个字的敲出来。而随着近几年OC

Nov 1, 2022
Simple and complete API for building command line applications in Go

Simple and complete API for building command line applications in Go Module cli provides a simple, fast and complete API for building command line app

Nov 23, 2022
A Go library for building command line applications

gocmd A Go library for building command line applications. Features Advanced command line arguments handling Subcommand handling Short and long comman

Dec 21, 2022
A simple, fast, and fun package for building command line apps in Go

cli cli is a simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable comm

Dec 31, 2022
A golang library for building interactive prompts with full support for windows and posix terminals.
A golang library for building interactive prompts with full support for windows and posix terminals.

Survey A library for building interactive prompts on terminals supporting ANSI escape sequences. package main import ( "fmt" "github.com/Alec

Jan 6, 2023