15 Commits

13 changed files with 271 additions and 69 deletions

View File

@@ -21,7 +21,8 @@ If you want, add yourself to the `CONTRIBUTORS` file in your pull request.
For Rust, just use `cargo fmt`. For Python, use For Rust, just use `cargo fmt`. For Python, use
[black](https://github.com/psf/black). I'd rather not spend any effort in [black](https://github.com/psf/black). I'd rather not spend any effort in
configuring the formatters (not possible for black anyway). configuring the formatters (not possible for black anyway). For shell scripts,
use [`shfmt`](https://github.com/mvdan/sh).
## Tooling ## Tooling
@@ -41,6 +42,9 @@ When contributing, consider whether it makes sense to add tests which could
prevent regressions in the future. When fixing bugs, it makes sense to add prevent regressions in the future. When fixing bugs, it makes sense to add
tests that expose the wrong behaviour beforehand. tests that expose the wrong behaviour beforehand.
To also ensure proper formatting and that the linter is happy, use `just check`.
If that succeeds, your code is most likely fine to push!
## Documentation ## Documentation
The documentation lives in `docs` and uses The documentation lives in `docs` and uses

View File

@@ -1 +1,2 @@
nonnominandus nonnominandus
Maximilian Volk

56
Cargo.lock generated
View File

@@ -80,16 +80,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.1.18" version = "3.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
"clap_derive", "clap_derive",
"clap_lex", "clap_lex",
"indexmap", "indexmap",
"lazy_static", "once_cell",
"strsim", "strsim",
"termcolor", "termcolor",
"textwrap", "textwrap",
@@ -97,9 +97,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "3.1.18" version = "3.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error", "proc-macro-error",
@@ -110,9 +110,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.2.0" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"
dependencies = [ dependencies = [
"os_str_bytes", "os_str_bytes",
] ]
@@ -321,18 +321,18 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.6" version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi 0.10.2+wasi-snapshot-preview1", "wasi",
] ]
[[package]] [[package]]
name = "git-repo-manager" name = "git-repo-manager"
version = "0.7.2" version = "0.7.3"
dependencies = [ dependencies = [
"clap", "clap",
"comfy-table", "comfy-table",
@@ -388,9 +388,9 @@ dependencies = [
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.7" version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
@@ -410,9 +410,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.8.1" version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown", "hashbrown",
@@ -584,7 +584,7 @@ checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi",
"windows-sys", "windows-sys",
] ]
@@ -1015,9 +1015,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.95" version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1105,9 +1105,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.34" version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"log", "log",
@@ -1129,11 +1129,11 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.26" version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
dependencies = [ dependencies = [
"lazy_static", "once_cell",
] ]
[[package]] [[package]]
@@ -1154,9 +1154,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@@ -1212,12 +1212,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "git-repo-manager" name = "git-repo-manager"
version = "0.7.2" version = "0.7.3"
edition = "2021" edition = "2021"
authors = [ authors = [
@@ -54,7 +54,7 @@ version = "=0.14.4"
version = "=2.1.0" version = "=2.1.0"
[dependencies.clap] [dependencies.clap]
version = "=3.1.18" version = "=3.2.5"
features = ["derive", "cargo"] features = ["derive", "cargo"]
[dependencies.console] [dependencies.console]

View File

@@ -1,46 +1,54 @@
set positional-arguments set positional-arguments
target := "x86_64-unknown-linux-musl" static_target := "x86_64-unknown-linux-musl"
check: fmt-check lint test check: fmt-check lint test
cargo check cargo check
cargo fmt --check
cargo clippy --no-deps -- -Dwarnings clean:
cargo clean
git clean -f -d -X
fmt: fmt:
cargo fmt cargo fmt
git ls-files | grep '\.py$' | xargs black git ls-files | grep '\.py$' | xargs black
git ls-files | grep '\.sh$' | xargs -L 1 shfmt --indent 4 --write
fmt-check: fmt-check:
cargo fmt --check cargo fmt --check
git ls-files | grep '\.py$' | xargs black --check git ls-files | grep '\.py$' | xargs black --check
git ls-files | grep '\.sh$' | xargs -L 1 shfmt --indent 4 --diff
lint: lint:
cargo clippy --no-deps -- -Dwarnings cargo clippy --no-deps -- -Dwarnings
git ls-files | grep '\.sh$' | xargs -L 1 shellcheck --norc
lint-fix: lint-fix:
cargo clippy --no-deps --fix cargo clippy --no-deps --fix
release: release:
cargo build --release --target {{target}} cargo build --release
release-static:
cargo build --release --target {{static_target}} --features=static-build
test-binary: test-binary:
env \ env \
GITHUB_API_BASEURL=http://rest:5000/github \ GITHUB_API_BASEURL=http://rest:5000/github \
GITLAB_API_BASEURL=http://rest:5000/gitlab \ GITLAB_API_BASEURL=http://rest:5000/gitlab \
cargo build --target {{target}} --profile e2e-tests --features=static-build cargo build --target {{static_target}} --profile e2e-tests --features=static-build
install: install:
cargo install --path . cargo install --path .
install-static: install-static:
cargo install --target {{target}} --features=static-build --path . cargo install --target {{static_target}} --features=static-build --path .
build: build:
cargo build cargo build
build-static: build-static:
cargo build --target {{target}} --features=static-build cargo build --target {{static_target}} --features=static-build
test: test-unit test-integration test-e2e test: test-unit test-integration test-e2e
@@ -56,7 +64,7 @@ test-e2e +tests=".": test-binary
&& docker-compose build \ && docker-compose build \
&& docker-compose run \ && docker-compose run \
--rm \ --rm \
-v $PWD/../target/{{target}}/e2e-tests/grm:/grm \ -v $PWD/../target/{{static_target}}/e2e-tests/grm:/grm \
pytest \ pytest \
"GRM_BINARY=/grm ALTERNATE_DOMAIN=alternate-rest python3 -m pytest -p no:cacheprovider --color=yes "$@"" \ "GRM_BINARY=/grm ALTERNATE_DOMAIN=alternate-rest python3 -m pytest -p no:cacheprovider --color=yes "$@"" \
&& docker-compose rm --stop -f && docker-compose rm --stop -f

View File

@@ -248,6 +248,7 @@ def test_repos_find_remote_user_empty(
@pytest.mark.parametrize("force_ssh", [True, False]) @pytest.mark.parametrize("force_ssh", [True, False])
@pytest.mark.parametrize("use_alternate_endpoint", [True, False]) @pytest.mark.parametrize("use_alternate_endpoint", [True, False])
@pytest.mark.parametrize("use_config", [True, False]) @pytest.mark.parametrize("use_config", [True, False])
@pytest.mark.parametrize("override_remote_name", [True, False])
def test_repos_find_remote_user( def test_repos_find_remote_user(
provider, provider,
configtype, configtype,
@@ -258,6 +259,7 @@ def test_repos_find_remote_user(
force_ssh, force_ssh,
use_alternate_endpoint, use_alternate_endpoint,
use_config, use_config,
override_remote_name,
): ):
if use_config: if use_config:
with tempfile.NamedTemporaryFile() as config: with tempfile.NamedTemporaryFile() as config:
@@ -274,6 +276,8 @@ def test_repos_find_remote_user(
cfg += f"worktree = {str(worktree).lower()}\n" cfg += f"worktree = {str(worktree).lower()}\n"
if force_ssh: if force_ssh:
cfg += f"force_ssh = true\n" cfg += f"force_ssh = true\n"
if override_remote_name:
cfg += f'remote_name = "otherremote"\n'
if use_owner: if use_owner:
cfg += """ cfg += """
[filters] [filters]
@@ -310,6 +314,8 @@ def test_repos_find_remote_user(
args += ["--user", "myuser1"] args += ["--user", "myuser1"]
if force_ssh: if force_ssh:
args += ["--force-ssh"] args += ["--force-ssh"]
if override_remote_name:
args += ["--remote-name", "otherremote"]
if not worktree_default: if not worktree_default:
args += ["--worktree", str(worktree).lower()] args += ["--worktree", str(worktree).lower()]
if use_alternate_endpoint: if use_alternate_endpoint:
@@ -350,7 +356,10 @@ def test_repos_find_remote_user(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider if override_remote_name:
assert repo["remotes"][0]["name"] == "otherremote"
else:
assert repo["remotes"][0]["name"] == "origin"
if force_ssh or i == 1: if force_ssh or i == 1:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
@@ -535,14 +544,14 @@ def test_repos_find_remote_group(
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
if force_ssh or i == 1: if force_ssh or i == 1:
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
== f"ssh://git@example.com/mygroup1/myproject{i}.git" == f"ssh://git@example.com/mygroup1/myproject{i}.git"
) )
assert repo["remotes"][0]["type"] == "ssh" assert repo["remotes"][0]["type"] == "ssh"
else: else:
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
== f"https://example.com/mygroup1/myproject{i}.git" == f"https://example.com/mygroup1/myproject{i}.git"
@@ -659,7 +668,7 @@ def test_repos_find_remote_user_and_group(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh or i == 1: if force_ssh or i == 1:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
@@ -684,7 +693,7 @@ def test_repos_find_remote_user_and_group(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh or i == 1: if force_ssh or i == 1:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
@@ -814,7 +823,7 @@ def test_repos_find_remote_owner(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh or i == 1: if force_ssh or i == 1:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
@@ -837,7 +846,7 @@ def test_repos_find_remote_owner(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh or i == 1: if force_ssh or i == 1:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
@@ -861,7 +870,7 @@ def test_repos_find_remote_owner(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh: if force_ssh:
assert ( assert (
repo["remotes"][0]["url"] == f"ssh://git@example.com/myuser2/myproject3.git" repo["remotes"][0]["url"] == f"ssh://git@example.com/myuser2/myproject3.git"
@@ -890,7 +899,7 @@ def test_repos_find_remote_owner(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh or i == 1: if force_ssh or i == 1:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
@@ -910,7 +919,7 @@ def test_repos_find_remote_owner(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh: if force_ssh:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]
@@ -936,7 +945,7 @@ def test_repos_find_remote_owner(
assert repo["worktree_setup"] is (not worktree_default and worktree) assert repo["worktree_setup"] is (not worktree_default and worktree)
assert isinstance(repo["remotes"], list) assert isinstance(repo["remotes"], list)
assert len(repo["remotes"]) == 1 assert len(repo["remotes"]) == 1
assert repo["remotes"][0]["name"] == provider assert repo["remotes"][0]["name"] == "origin"
if force_ssh: if force_ssh:
assert ( assert (
repo["remotes"][0]["url"] repo["remotes"][0]["url"]

164
release.sh Executable file
View File

@@ -0,0 +1,164 @@
#!/usr/bin/env bash
set -o nounset
set -o errexit
set -o pipefail
usage() {
printf '%s\n' "usage: $0 (master|minor|patch)" >&2
}
if (($# != 1)); then
usage
exit 1
fi
current_version="$(grep '^version \?=' Cargo.toml | head -1 | cut -d '=' -f 2 | tr -d " '"'"')"
major="$(printf '%s' "${current_version}" | grep -oP '^\d+')"
minor="$(printf '%s' "${current_version}" | grep -oP '\.\d+\.' | tr -d '.')"
patch="$(printf '%s' "${current_version}" | grep -oP '\d+$' | tr -d '.')"
case "$1" in
major)
((major++)) || true
minor=0
patch=0
;;
minor)
((minor++)) || true
patch=0
;;
patch)
((patch++)) || true
;;
*)
usage
exit 1
;;
esac
new_version="${major}.${minor}.${patch}"
if ! [[ "${new_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
printf '%s\n' 'Version has to a complete semver' >&2
exit 1
fi
current_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "${current_branch}" != "develop" ]]; then
printf '%s\n' 'You need to be on develop' >&2
exit 1
fi
gitstatus="$(git status --porcelain)"
if [[ -n "${gitstatus}" ]]; then
printf '%s\n' 'There are uncommitted changes' >&2
exit 1
fi
if git tag --list "v${new_version}" | grep -q .; then
printf 'Tag %s already exists\n' "v${new_version}" >&2
exit 1
fi
for remote in $(git remote); do
if git ls-remote --tags "${remote}" | grep -q "refs/tags/v${new_version}$"; then
printf 'Tag %s already exists on %s' "v${new_version}" "${remote}" >&2
exit 1
fi
done
git fetch --all
for remote in $(git remote); do
for branch in master develop; do
if ! git diff --quiet "${remote}/${branch}..${branch}"; then
printf 'Remote branch %s/%s not up to date, synchronize first!\n' "${remote}" "${branch}" >&2
exit 1
fi
done
done
if ! git merge-base --is-ancestor master develop; then
printf '%s\n' 'Develop is not a straight descendant of master, rebase!' >&2
exit 1
fi
changes="$(git log --oneline master..develop | wc -l)"
if ((changes == 0)); then
printf '%s\n' 'No changes between master and develop?' >&2
exit 1
fi
just update-dependencies
just check
sed -i "0,/^version/{s/^version.*$/version = \"${new_version}\"/}" Cargo.toml
cargo update --package git-repo-manager --precise "${new_version}"
diff="$(git diff --numstat)"
if (($(printf '%s\n' "${diff}" | wc -l || true) != 2)); then
printf '%s\n' 'Weird changes detected, bailing' >&2
exit 1
fi
if ! printf '%s\n' "${diff}" | grep -Pq '^1\s+1\s+Cargo.lock$'; then
printf '%s\n' 'Weird changes detected, bailing' >&2
exit 1
fi
if ! printf '%s\n' "${diff}" | grep -Pq '^1\s+1\s+Cargo.toml$'; then
printf '%s\n' 'Weird changes detected, bailing' >&2
exit 1
fi
git add Cargo.lock Cargo.toml
git commit -m "Release v${new_version}"
git switch master 2>/dev/null || { [[ -d "../master" ]] && cd "../master"; } || {
printf '%s\n' 'Could not change to master' >&2
exit 1
}
current_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "${current_branch}" != "master" ]]; then
printf '%s\n' 'Looks like branch switching to master did not work' >&2
exit 1
fi
git merge --no-ff --no-edit develop
git tag "v${new_version}"
for remote in $(git remote); do
while ! git push "${remote}" "v${new_version}" master; do
:
done
done
git switch develop 2>/dev/null || { [[ -d "../develop" ]] && cd "../develop"; } || {
printf '%s\n' 'Could not change to develop' >&2
exit 1
}
current_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "${current_branch}" != "develop" ]]; then
printf '%s\n' 'Looks like branch switching to develop did not work' >&2
exit 1
fi
git merge --ff-only master
for remote in $(git remote); do
while ! git push "${remote}" develop; do
:
done
done
cargo publish
printf 'Published %s successfully\n' "${new_version}"
exit 0

View File

@@ -53,6 +53,8 @@ pub struct ConfigProvider {
pub worktree: Option<bool>, pub worktree: Option<bool>,
pub init_worktree: Option<bool>, pub init_worktree: Option<bool>,
pub remote_name: Option<String>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@@ -192,6 +194,7 @@ impl Config {
.get_repos( .get_repos(
config.worktree.unwrap_or(false), config.worktree.unwrap_or(false),
config.force_ssh.unwrap_or(false), config.force_ssh.unwrap_or(false),
config.remote_name,
)? )?
} }
RemoteProvider::Gitlab => { RemoteProvider::Gitlab => {
@@ -205,6 +208,7 @@ impl Config {
.get_repos( .get_repos(
config.worktree.unwrap_or(false), config.worktree.unwrap_or(false),
config.force_ssh.unwrap_or(false), config.force_ssh.unwrap_or(false),
config.remote_name,
)? )?
} }
}; };

View File

@@ -103,6 +103,9 @@ pub struct FindRemoteArgs {
#[clap(arg_enum, short, long, help = "Remote provider to use")] #[clap(arg_enum, short, long, help = "Remote provider to use")]
pub provider: RemoteProvider, pub provider: RemoteProvider,
#[clap(short, long, help = "Name of the remote to use")]
pub remote_name: Option<String>,
#[clap( #[clap(
multiple_occurrences = true, multiple_occurrences = true,
name = "user", name = "user",
@@ -189,6 +192,9 @@ pub struct SyncRemoteArgs {
#[clap(arg_enum, short, long, help = "Remote provider to use")] #[clap(arg_enum, short, long, help = "Remote provider to use")]
pub provider: RemoteProvider, pub provider: RemoteProvider,
#[clap(short, long, help = "Name of the remote to use")]
pub remote_name: Option<String>,
#[clap( #[clap(
multiple_occurrences = true, multiple_occurrences = true,
name = "user", name = "user",

View File

@@ -64,7 +64,11 @@ fn main() {
process::exit(1); process::exit(1);
} }
} }
.get_repos(worktree, args.force_ssh) .get_repos(
worktree,
args.force_ssh,
args.remote_name,
)
} }
cmd::RemoteProvider::Gitlab => { cmd::RemoteProvider::Gitlab => {
match provider::Gitlab::new(filter, token, args.api_url) { match provider::Gitlab::new(filter, token, args.api_url) {
@@ -74,7 +78,11 @@ fn main() {
process::exit(1); process::exit(1);
} }
} }
.get_repos(worktree, args.force_ssh) .get_repos(
worktree,
args.force_ssh,
args.remote_name,
)
} }
}; };
@@ -280,6 +288,7 @@ fn main() {
.get_repos( .get_repos(
config.worktree.unwrap_or(false), config.worktree.unwrap_or(false),
config.force_ssh.unwrap_or(false), config.force_ssh.unwrap_or(false),
config.remote_name,
) { ) {
Ok(provider) => provider, Ok(provider) => provider,
Err(error) => { Err(error) => {
@@ -299,6 +308,7 @@ fn main() {
.get_repos( .get_repos(
config.worktree.unwrap_or(false), config.worktree.unwrap_or(false),
config.force_ssh.unwrap_or(false), config.force_ssh.unwrap_or(false),
config.remote_name,
) { ) {
Ok(provider) => provider, Ok(provider) => provider,
Err(error) => { Err(error) => {
@@ -382,7 +392,11 @@ fn main() {
process::exit(1); process::exit(1);
} }
} }
.get_repos(worktree, args.force_ssh) .get_repos(
worktree,
args.force_ssh,
args.remote_name,
)
} }
cmd::RemoteProvider::Gitlab => { cmd::RemoteProvider::Gitlab => {
match provider::Gitlab::new(filter, token, args.api_url) { match provider::Gitlab::new(filter, token, args.api_url) {
@@ -392,7 +406,11 @@ fn main() {
process::exit(1); process::exit(1);
} }
} }
.get_repos(worktree, args.force_ssh) .get_repos(
worktree,
args.force_ssh,
args.remote_name,
)
} }
}; };

View File

@@ -8,7 +8,6 @@ use super::JsonError;
use super::Project; use super::Project;
use super::Provider; use super::Provider;
const PROVIDER_NAME: &str = "github";
const ACCEPT_HEADER_JSON: &str = "application/vnd.github.v3+json"; const ACCEPT_HEADER_JSON: &str = "application/vnd.github.v3+json";
const GITHUB_API_BASEURL: &str = const GITHUB_API_BASEURL: &str =
option_env!("GITHUB_API_BASEURL").unwrap_or("https://api.github.com"); option_env!("GITHUB_API_BASEURL").unwrap_or("https://api.github.com");
@@ -88,10 +87,6 @@ impl Provider for Github {
}) })
} }
fn name(&self) -> &str {
PROVIDER_NAME
}
fn filter(&self) -> &Filter { fn filter(&self) -> &Filter {
&self.filter &self.filter
} }

View File

@@ -8,7 +8,6 @@ use super::JsonError;
use super::Project; use super::Project;
use super::Provider; use super::Provider;
const PROVIDER_NAME: &str = "gitlab";
const ACCEPT_HEADER_JSON: &str = "application/json"; const ACCEPT_HEADER_JSON: &str = "application/json";
const GITLAB_API_BASEURL: &str = option_env!("GITLAB_API_BASEURL").unwrap_or("https://gitlab.com"); const GITLAB_API_BASEURL: &str = option_env!("GITLAB_API_BASEURL").unwrap_or("https://gitlab.com");
@@ -105,10 +104,6 @@ impl Provider for Gitlab {
}) })
} }
fn name(&self) -> &str {
PROVIDER_NAME
}
fn filter(&self) -> &Filter { fn filter(&self) -> &Filter {
&self.filter &self.filter
} }

View File

@@ -14,6 +14,8 @@ use super::repo;
use std::collections::HashMap; use std::collections::HashMap;
const DEFAULT_REMOTE_NAME: &str = "origin";
#[derive(Debug, Deserialize, Serialize, clap::ArgEnum, Clone)] #[derive(Debug, Deserialize, Serialize, clap::ArgEnum, Clone)]
pub enum RemoteProvider { pub enum RemoteProvider {
#[serde(alias = "github", alias = "GitHub")] #[serde(alias = "github", alias = "GitHub")]
@@ -122,7 +124,6 @@ pub trait Provider {
where where
Self: Sized; Self: Sized;
fn name(&self) -> &str;
fn filter(&self) -> &Filter; fn filter(&self) -> &Filter;
fn secret_token(&self) -> &auth::AuthToken; fn secret_token(&self) -> &auth::AuthToken;
fn auth_header_key() -> &'static str; fn auth_header_key() -> &'static str;
@@ -213,6 +214,7 @@ pub trait Provider {
&self, &self,
worktree_setup: bool, worktree_setup: bool,
force_ssh: bool, force_ssh: bool,
remote_name: Option<String>,
) -> Result<HashMap<Option<String>, Vec<repo::Repo>>, String> { ) -> Result<HashMap<Option<String>, Vec<repo::Repo>>, String> {
let mut repos = vec![]; let mut repos = vec![];
@@ -292,10 +294,12 @@ pub trait Provider {
let mut ret: HashMap<Option<String>, Vec<repo::Repo>> = HashMap::new(); let mut ret: HashMap<Option<String>, Vec<repo::Repo>> = HashMap::new();
let remote_name = remote_name.unwrap_or_else(|| DEFAULT_REMOTE_NAME.to_string());
for repo in repos { for repo in repos {
let namespace = repo.namespace(); let namespace = repo.namespace();
let mut repo = repo.into_repo_config(self.name(), worktree_setup, force_ssh); let mut repo = repo.into_repo_config(&remote_name, worktree_setup, force_ssh);
// Namespace is already part of the hashmap key. I'm not too happy // Namespace is already part of the hashmap key. I'm not too happy
// about the data exchange format here. // about the data exchange format here.