Skip to content

mkloubert/go-package-manager

Repository files navigation

gpm - A package manager in and for Go

Share via Facebook Share via X Share via Pinterest Share via Reddit Share via LinkedIn Share via Wordpress Share via Email

Table of contents

Overview []

gpm is a command-line tool designed to simplify developer workflows in particular for Go projects.

However, it's not only limited to Go but can also be utilized for other project types as well.

KEEP IN MIND: This project is in an beta state and under heavy development. It might happen that there will be breaking changes. Have a look at the CHANGELOG.md file.

Installation []

You can install gpm from a pre-build binary or build it by your own:

Linux / UNIX []

The following curl operation(s) will download the latest version from GitHub and extract it to /usr/local/bin as gpm executable, which should be part of the $PATH environment variable (this also requires jq tool):

# replace "<!!!OS!!!>" with one of the following values:
# - "openbsd"
# - "linux"
# - "freebsd"
#
# replace "<!!!CPU!!!>" with one of the following values:
# - "386": Intel compatible (32-bit)
# - "amd64": Intel compatible (64-bit)
# - "arm": ARM (32-bit)
# - "arm64": ARM (64-bit)
curl -s https://api.github.com/repos/mkloubert/go-package-manager/releases/latest | jq -r '.assets[].browser_download_url | select(contains("<!!!OS!!!>") and contains("<!!!CPU!!!>") and (. | tostring | contains("sha256") | not))' | xargs curl -sL | tar xzOf - gpm | sudo tee /usr/local/bin/gpm > /dev/null && sudo chmod +x /usr/local/bin/gpm

Later, you can also execute the following command, which will install a script named gpm-update in $HOME/.gpm/bin folder:

gpm setup updater

MacOS []

The following curl operation(s) will download the latest version from GitHub and extract it to /usr/local/bin as gpm executable, which should be part of the $PATH environment variable (this also requires jq tool):

# Apple Silicon
curl -s https://api.github.com/repos/mkloubert/go-package-manager/releases/latest | jq -r '.assets[].browser_download_url | select(contains("darwin") and contains("arm64") and (. | tostring | contains("sha256") | not))' | xargs curl -sL | tar xzOf - gpm | sudo tee /usr/local/bin/gpm > /dev/null && sudo chmod +x /usr/local/bin/gpm

# use the following commands if you use a legacy Intel 64-bit system
# curl -s https://api.github.com/repos/mkloubert/go-package-manager/releases/latest | jq -r '.assets[].browser_download_url | select(contains("darwin") and contains("amd64") and (. | tostring | contains("sha256") | not))' | xargs curl -sL | tar xzOf - gpm | sudo tee /usr/local/bin/gpm > /dev/null && sudo chmod +x /usr/local/bin/gpm

Later, you can also execute the following command, which will install a script named gpm-update in $HOME/.gpm/bin folder:

gpm setup updater

Windows []

will download the latest version from GitHub and extract it to C:\Program Files\gpm as gpm.exe executable, which should be made part of the PATH environment variable:

# replace "<!!!CPU!!!>" with one of the following values:
# - "386": Intel compatible (32-bit)
# - "amd64": Intel compatible (64-bit)
# - "arm": ARM (32-bit)
Invoke-WebRequest 'https://api.github.com/repos/mkloubert/go-package-manager/releases/latest' -UseBasicParsing | ConvertFrom-Json | % { $_.assets | Where-Object { $_.browser_download_url -like '*windows*<!!!CPU!!!>*.zip' -and $_.browser_download_url -notlike '*sha256*' } | Select-Object -ExpandProperty browser_download_url -First 1 } | % { $url=$_; $output="gpm.zip"; Invoke-WebRequest $url -OutFile $output; Expand-Archive $output -DestinationPath "$env:TEMP\gpm" -Force; New-Item -ItemType Directory -Path "C:\Program Files\gpm" -Force | Out-Null; Copy-Item "$env:TEMP\gpm\gpm.exe" -Destination "C:\Program Files\gpm" }

Build from source []

# checkout current source
git clone https://github.com/mkloubert/go-package-manager.git -o gpm

# switch to new subfolder, build and run it
cd gpm
go build . && ./gpm --version

Usage []

Commands []

Add alias []

With

gpm add alias yaml https://github.com/go-yaml/yaml

you define the alias yaml which refers to the Git repository in https://github.com/go-yaml/yaml. This information will be stored in aliases.yaml file inside your $HOME/.gpm folder.

If you later run

gpm install yaml

go get -u https://github.com/go-yaml/yaml will be executed instead.

Add project []

With

gpm add project react-project https://github.com/ofnullable/react-spa-template

you define the alias react-project which refers to the Git repository in https://github.com/ofnullable/react-spa-template. This information will be stored in projects.yaml file inside your $HOME/.gpm folder.

If you later run

gpm new react-project

the repository will be cloned to react-spa-template subfolder, then its .git folder will be removed and the new folder will be re-initialized with git init.

AI chat []

AI Chat Demo 1

AI prompt []

AI Prompt Demo 1

Audit dependencies []

Audit Demo 1

Build and install executable []

gpm make https://github.com/gohugoio/hugo

will clone the repository into a temp folder and run gpm build from it.

The final executable will be installed in $HOME/.gpm/bin folder. So it could be useful to add it to the $PATH enviornment variable.

FYI: Instead of the URL as argument you can use a project alias added by add project command.

Build project []

gpm build

will run go build . in the current directory or the build script in gpm.yaml, if defined.

Bump version []

The simple execution of

gpm bump version

will detect the latest version of the underlying repository from Git tags and then upgrade the minor part only, e.g. 1.2.4 => 1.3.4. Finally a new Git tag is created in the format v1.3.4.

You also can use at least one of the following flags to increase parts of the current version number as well:

  • --breaking: 1.2.4 => 2.0.0 by default
  • --feature: 1.2.4 => 1.3.0 by default
  • --fix: 1.2.4 => 1.2.5

Checkout branch []

The execution of

gpm checkout my-branch

will checkout or create the branch my-branch in the current Git repository.

If the branch does not exist, you can use --suggest to use AI which generates a branch name from a description using format <type>/<description>.

An execution of

gpm checkout "i will fix the save button on start page" --suggest

for example could suggest a value like feature/fix-save-button-on-start-page when using ChatGPT 3.5

Have a look at the Setup AI which describes how to setup OpenAI or Ollama API.

Branch aliases []

For example, if you define the environment variable GPM_BRANCH_DEV with development as value, you can run

gpm checkout :dev

from the command line to switch to development branch.

The :dev is the part after the GPM_BRANCH_ prefix in the environment variable name.

This means you are also able to define a variable, lets say GPM_BRANCH_FOO, with the value bar, which will allow you to easily switch to bar branch if you execute

gpm checkout :foo

Keep in mind: If you have no value for an alias defined, gpm will take its name as fallback!

Cleanup project []

gpm tidy

is a short form of go mod tidy.

Compare code changes []

Diff demo 1

Docker shorthands []

Shorthand Final command
gpm down docker compose down
gpm up docker compose up --build

Execute shell command []

Execute demo 1

Import aliases []

gpm import aliases https://raw.githubusercontent.com/mkloubert/go-package-manager/main/aliases.yaml

loads aliases from https://raw.githubusercontent.com/mkloubert/go-package-manager/main/aliases.yaml and merge them with entries in aliases.yaml file in $HOME/.gpm folder.

You can also use a local file path and/or pipe from STDIN as well.

Import projects []

gpm import projects https://raw.githubusercontent.com/mkloubert/go-package-manager/main/projects.yaml

loads projects from https://raw.githubusercontent.com/mkloubert/go-package-manager/main/projects.yaml and merge them with entries in projects.yaml file in $HOME/.gpm folder.

You can also use a local file path and/or pipe from STDIN as well.

Install dependencies []

gpm install <alias> is designed to install a module via an alias defined with Add alias command.

For example if you define an alias called yaml with

gpm add alias yaml https://github.com/go-yaml/yaml

you can run

gpm install yaml

later which will simply call go get -u https://github.com/go-yaml/yaml instead.

List aliases []

Simply run

gpm list aliases

will output a list like this:

cobra
        https://github.com/spf13/cobra
mongo
        go.mongodb.org/mongo-driver/mongo
yaml
        https://github.com/go-yaml/yaml

List executables []

Executables / binaries created with make command can be listed with

gpm list binaries

List projects []

Simply run

gpm list projects

will output a list like this:

mkloubert
        [email protected]:mkloubert/mkloubert.git

Monitor process []

Monitor Demo 1

New project []

gpm new <project> is designed to setup a project via an alias defined with Add project command.

For example if you define an alias called mkloubert with

gpm add project mkloubert [email protected]:mkloubert/mkloubert.git

you can run

gpm new mkloubert

later which will simply call git clone [email protected]:mkloubert/mkloubert.git instead that clones the Git repository to mkloubert subfolder, removes its .git folder and re-initializes it with git init.

Open alias []

Aliases created by Add alias command can be opened by default handler of the operating system.

Lets say you created an alias called cobra with the URL https://github.com/spf13/cobra, the execution of

gpm open alias cobra

will open this URL usually in the browser.

Open project []

Project entries created by Add project command can be opened by default handler of the operating system.

Lets say you created a project alias called gpm with the URL https://github.com/mkloubert/go-package-manager, the execution of

gpm open project cobra

will open this URL usually in the browser.

Pack project []

AI Chat Demo 1

Pull from Git remotes []

The execution of

gpm pull

will pull from all remotes which are stored inside the current Git repository.

Push to Git remotes []

The execution of

gpm push

will push to all remotes which are stored inside the current Git repository.

Remove alias []

With

gpm remove alias yaml

you will remove the yaml alias from aliases.yaml file, which is stored in $HOME/.gpm folder.

Remove project []

With

gpm remove project yaml

you will remove the yaml alias from projects.yaml file, which is stored in $HOME/.gpm folder.

Remove executable []

If you installed a binary with make command like

gpm make https://github.com/gopasspw/gopass

you can simply remove it with gpm remove binary gopass if the binary is stored as gopass in $HOME/.gpm/bin folder.

Run script []

In the gpm.yaml file you can define script which are executed in shell/terminal context:

scripts:
  foo: "echo bar"

With

gpm run foo

you will run echo bar.

Run tests []

gpm test

will execute go test . instead or the test script defined in current gpm.yaml file, if defined.

Show dependency graph []

Running

gpm show dependencies

will create and open a temporary HTML file which will display a dependency graph of all installed modules:

Show dependency graph demo 1

Start project []

gpm start

will execute go run . instead or the start script defined in current gpm.yaml file, if defined.

Synchronize with Git remotes []

With execution of

gpm sync

you will pull from and then push to all remotes as defined in the current Git repository.

Uninstall dependencies []

gpm uninstall <alias> is designed to un-install a module via an alias defined with Add alias command.

For example if you define an alias called yaml with

gpm add alias yaml https://github.com/go-yaml/yaml

you can run

gpm uninstall yaml

later which will simply call go get -u https://github.com/go-yaml/yaml@none instead.

Setup AI []

If you would like to use AI feature, like suggestion of branch names, you can setup one of the following APIs:

OpenAI / ChatGPT []

Create (or use) an API from https://platform.openai.com/api-keys and write it to OPENAI_API_KEY environment variable.

By default gpt-3.5-turbo model is used. You can change this, by setting up GPM_AI_CHAT_MODEL environment variable with a value from here like this:

GPM_AI_CHAT_MODEL=gpt-4-turbo

Ollama []

If you want to use Ollama instead, you have to setup the following environment variables:

GPM_AI_API=ollama
GPM_AI_CHAT_MODEL=<name of the model>

Replace <name of the model> with one of these models.

Two good models are llama3 by Meta or phi3 by Microsoft.

gpm.yaml []

The idea of an gpm.yaml file is very similar to package.json file for Node / NPM environments.

An example can be found here.

If you want to initialize an empty one, you only need to execute

gpm init

in your terminal.

Files []

The files section contains a list of regular expressions of files which is used by pack command:

# ...

files:
  - my-app
  - LICENSE
  - README.md
  - ^commands/p
# ...

If the list is empty or not defined, the following default values are set:

  • possible name of the executable file build with build command
  • ^CHANGELOG.md$
  • ^CONTRIBUTING.md$
  • ^CONTRIBUTION.md$
  • ^LICENSE$
  • ^README.md$

Scripts []

Create or update the scripts section with key/value pairs:

scripts:
  test1: "echo Test1"
  test2: "echo Test2"

From the project folder you will be able to execute gpm run test1 or gpm run test2 to run the defined shell/terminal commands.

Predefined []

Name Description
postbuild Is executed after successful execution of build command.
postinstall Is executed after successful execution of install command.
posttest Is executed after successful execution of test command.
prebuild Is executed before build command is executed.
preinstall Is executed before install command is executed.
pretest Is executed before test command is executed.
start Is executed by start command. If not defined go run . is executed.
test Is executed by test command. If not defined go test . is executed.
tidy Is executed by tidy command. If not defined go mod tidy is executed.

Environment variables []

Environment variables can be loaded from external files, which are handled in this order:

  • $HOME/.gpm/.env<SUFFIX> (if exist)
  • <PROJECT-DIR>/.env (if exist)
  • <PROJECT-DIR>/.env<SUFFIX> (if exist)
  • <PROJECT-DIR>/.env.local (if exist)
  • <PROJECT-DIR>/.env<SUFFIX>.local (if exist)
  • from --env-file flags (must exist!)

<SUFFIX> is the lower case value from --environment and can be empty.

Supported variables []

Name Description Example
GPM_AI_API ID of the AI API to use. Possible values are ollama or openai. openai
GPM_AI_CHAT_MODEL ID of the AI chat model to use. Possible values are models by OpenAI or Ollama. gpt-4o
GPM_AI_CHAT_TEMPERATURE Temperature value for an AI chat (operation) 0
GPM_AI_PROMPT Custom prompt for operations which are using chat completion operations, like checkout command.
GPM_AI_SYSTEM_PROMPT Custom (initial) system prompt for AI chat operations. You are a helpful AI assistant. You always answer in a very sarcastic way.
GPM_BIN_PATH Custom folder for binaries installed by make command. Default is $HOME/.gpm/bin. /my/custom/bin/path
GPM_DOWN_COMMAND Custom command for docker compose down shorthand. docker-compose down
GPM_ENV ID of the current environment. This is especially used for the .env files. prod
GPM_INSTALL_PATH Custom installation path of global gpm binary. /usr/bin
GPM_TERMINAL_FORMATTER Default formatter for syntax highlighting in terminal. See chroma project for more information. terminal16m
GPM_TERMINAL_STYLE Default style for syntax highlighting in terminal. See chroma project for more information. monokai
GPM_UP_COMMAND Custom command for docker compose up shorthand. docker-compose up
OPENAI_API_KEY Key which is used for the API by OpenAI. sk-...

Contribution []

If you have ideas and/or want to participate you are welcome!

Open an issue or create a pull request.

Support []

If you like the project you can donate via PayPal.

License []

The project is licensed under the MIT.

Credits []

gpm makes use of these following great projects: