From a3202ec7e46916727e53621177bb5c05537938a7 Mon Sep 17 00:00:00 2001 From: Vasiliy Vasilyuk Date: Sun, 4 Feb 2024 20:00:00 +0300 Subject: [PATCH] Initial commit Inception | Your mind is the scene of the crime. Signed-off-by: Vasiliy Vasilyuk --- .editorconfig | 15 ++++++ .github/workflows/shell.yml | 19 +++++++ LICENSE | 28 +++++++++++ Makefile | 21 ++++++++ README.md | 99 +++++++++++++++++++++++++++++++++++++ go-mod-bump.sh | 78 +++++++++++++++++++++++++++++ 6 files changed, 260 insertions(+) create mode 100644 .editorconfig create mode 100644 .github/workflows/shell.yml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100755 go-mod-bump.sh diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..08336c6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +tab_width = 4 +trim_trailing_whitespace = true +max_line_length = 100 + +[Makefile] +indent_style = tab + +[{*.yml,*.yaml}] +indent_size = 2 diff --git a/.github/workflows/shell.yml b/.github/workflows/shell.yml new file mode 100644 index 0000000..2fdb47a --- /dev/null +++ b/.github/workflows/shell.yml @@ -0,0 +1,19 @@ +name: Shell + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +jobs: + check-shell-scripts: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run shfmt and shellcheck + uses: luizm/action-sh-checker@v0.8.0 + env: + SHFMT_OPTS: -d -s -w -i 4 -ln bash diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7babce0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright 2024 Vasiliy Vasilyuk All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c38d678 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +.DEFAULT_GOAL:= help + +.PHONY: check shellcheck shfmt help + +check: shfmt shellcheck ## Static analysis files existing in repository. + +shellcheck: ## Check shell scripts. + @if ! command -v 'shellcheck' &> /dev/null; then \ + echo "Please install shellcheck! See https://www.shellcheck.net"; exit 1; \ + fi; + @shellcheck *.sh + +shfmt: ## Format shell scripts. + @if ! command -v 'shfmt' &> /dev/null; then \ + echo 'Please install shfmt! See https://github.com/mvdan/sh'; exit 1; \ + fi; + @shfmt -d -s -w -i 4 -ln bash *.sh + +help: ## Print this help. + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ + awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/README.md b/README.md new file mode 100644 index 0000000..5f5c80e --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +# go-mod-bump + +Script to elegantly update direct Go modules in separate commits. + +Automatically updates dependencies similar to `go get -u`, but commits the update to each direct +module in a separate commit. + +## How to install + +```shell +mkdir -p ~/bin +curl https://raw.githubusercontent.com/xorcare/go-mod-bump/main/go-mod-bump.sh > ~/bin/go-mod-bump +chmod +x ~/bin/go-mod-bump +``` + +After that don't forget to add the `~/bin` directory to the `$PATH` variable. +Use one of the following commands to do this: + +```shell +echo 'export PATH="$PATH:$HOME/bin"' >> ~/.bashrc +# Or +echo 'export PATH="$PATH:$HOME/bin"' >> ~/.zshrc +``` + +If you know a better way use it or let me know I will update the documentation. + +## How to use + +For update all direct models, use: + +```shell +go-mod-bump all +``` + +For update one specific direct module, specify its name. For example: + +```shell +go-mod-bump github.com/xorcare/pointer +``` + +For update multiple direct modules, specify their names. For example: + +```shell +go-mod-bump github.com/xorcare/pointer github.com/xorcare/tornado +``` + +## Know issues and limitations + +- The script does not know how to work with `replace` directive, if it is used in your project be + careful and do not forget to update dependencies manually. +- Pipelines are not supported, you cannot use go-mod-bump in combination with `|`. +- The script runs very slowly on projects with a lot of dependencies. +- The script does not abort execution if a module fails to update. It will try to update other + modules if possible. + +## Disclaimer + +When using this script, you should be aware that it propagates changes to the Git history. In some +cases, you may lose all your uncommitted changes forever. + +## Examples of output + +
+ Log with all modules updated successfully + + go-mod-bump: upgraded github.com/xorcare/pointer v1.0.0 => [v1.1.1] + go-mod-bump: upgraded github.com/xorcare/tornado v0.1.0 => [v0.1.1] + go-mod-bump: upgraded github.com/xorcare/golden v0.6.0 => [v0.8.2] + go-mod-bump: upgraded golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 => [v0.18.0] + go-mod-bump: upgraded golang.org/x/lint v0.0.0-20200302205851-738671d3881b => + [v0.0.0-20210508222113-6edffad5e616] + +
+ +
+ Log with on module update failed + + go-mod-bump: failed to update module github.com/xorcare/golden + v0.0.0-20180918085934-3c96afc26e10 to v0.0.0-20200320164324-52e96869b7ff + try to update module manually using commands: + go get github.com/xorcare/golden@v0.0.0-20180918085934-3c96afc26e10 + go mod tidy + go build ./... + go-mod-bump: upgraded github.com/xorcare/tornado v0.1.0 => [v0.1.1] + go-mod-bump: upgraded github.com/xorcare/pointer v1.0.0 => [v1.1.1] + +
+ +
+ Git log example + + Bump github.com/xorcare/pointer from v1.0.0 to v1.1.1 + Bump github.com/xorcare/tornado from v0.1.0 to v0.1.1 + Bump github.com/xorcare/golden from v0.6.0 to v0.8.2 + Bump golang.org/x/crypto from v0.0.0-20191011191535-87dc89f01550 to v0.18.0 + Bump golang.org/x/lint from v0.0.0-20200302205851-738671d3881b to + v0.0.0-20210508222113-6edffad5e616 + +
diff --git a/go-mod-bump.sh b/go-mod-bump.sh new file mode 100755 index 0000000..1989a44 --- /dev/null +++ b/go-mod-bump.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +# Copyright 2024 Vasiliy Vasilyuk All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# See https://github.com/xorcare/go-mod-bump/blob/main/LICENSE + +# Script to elegantly update direct Go modules in separate commits. +# +# Automatically updates dependencies similar to `go get -u`, but commits the update to each direct +# module in a separate commit. +# +# Source https://github.com/xorcare/go-mod-bump + +set -e + +function echoerr() { + echo "$@" >&2 +} + +if [ -z "$1" ]; then + echoerr <') +readonly DIRECT_MODULES + +GO_LIST_FORMAT_FOR_UPDATE='{{.Path}}@{{.Version}}@{{if .Update}}{{.Update.Version}}{{else}}{{end}}{{if .Indirect}}{{end}}' +readonly GO_LIST_FORMAT_FOR_UPDATE + +# shellcheck disable=SC2086 +MODULES_FOR_UPDATE=$(go list -f "$GO_LIST_FORMAT_FOR_UPDATE" -m -u $DIRECT_MODULES | grep -v '') +readonly MODULES_FOR_UPDATE + +function update_module() { + go get "$1" + + go mod tidy + go build ./... +} + +function bump_module() { + module=$(echo "$1" | cut -f1 -d@) + current_version=$(echo "$1" | cut -f2 -d@) + latest_version=$(echo "$1" | cut -f3 -d@) + + if ! update_module "${module}@${latest_version}" >/dev/null 2>&1 >/dev/null; then + echoerr "go-mod-bump: failed to update module ${module} from ${current_version} to ${latest_version}" + echoerr "try to update module manually using commands:" + echoerr "go get ${module}@${latest_version}" + echoerr "go mod tidy" + echoerr "go build ./..." + git checkout -f HEAD -- go.mod go.sum + return + fi + + git reset HEAD -- . >/dev/null + git add go.mod go.sum >/dev/null + git cm -a -m "Bump ${module} from ${current_version} to ${latest_version}" >/dev/null + + echoerr "go-mod-bump: upgraded ${module} ${current_version} => [${latest_version}]" +} + +for mdl in $MODULES_FOR_UPDATE; do + (bump_module "$mdl") +done