Skip to content

Commit

Permalink
Pin problem-specifications to a specific commit (#1950)
Browse files Browse the repository at this point in the history
The previous approach used a submodule to keep things somewhat stable.
That worked well for the rust-tooling (exercise generator) which made
use of the submodule. However, configlet continued to use its own cache.
(see exercism/configlet#816)
This could lead to problems where the configlet cache and the submodule
are out of sync and don't agree.

The new approach ditches the submodule and makes everything use the
configlet cache. Some helper scripts are responsible to make sure the
cache is checked out at the pinned commit and a configlet wrapper sets
the `--offile` flag to prevent configlet from updating the cache.
  • Loading branch information
senekor authored Aug 9, 2024
1 parent 8c408f0 commit 2a66d7d
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ exercises/*/*/Cargo.lock
clippy.log
.vscode
.prob-spec
problem-specifications
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "problem-specifications"]
path = problem-specifications
url = [email protected]:exercism/problem-specifications
17 changes: 17 additions & 0 deletions bin/checkout_pinned_problem_specifications_commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(git rev-parse --show-toplevel)"

PINNED_COMMIT_HASH="685ec55d9388937bbb3cc836b52b3ce27f208f37"

dir="$(./bin/get_problem_specifications_dir.sh)"

[ -d "$dir" ] || ./bin/configlet info &> /dev/null # initial population of cache

if ! git -C "$dir" checkout --quiet --detach "$PINNED_COMMIT_HASH" &> /dev/null
then
# maybe the pinned commit hash was updated and the cache has to be refreshed
./bin/configlet info &> /dev/null
git -C "$dir" checkout --quiet --detach "$PINNED_COMMIT_HASH"
fi
29 changes: 29 additions & 0 deletions bin/configlet_wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -eo pipefail

# This wrapper makes sure the problem-specifications repository is checked out
# at the pinned commit and the --offline flag is set for the relevant commands.

cd "$(git rev-parse --show-toplevel)"

[ -f ./bin/configlet ] || ./bin/fetch-configlet

if [ "$#" == 0 ]
then
./bin/configlet
exit
fi

cmd="$1" ; shift

if ! [ "$cmd" == "create" ] && ! [ "$cmd" == "sync" ] && ! [ "$cmd" == "info" ]
then
# problem-specifications independent commands
./bin/configlet "$cmd" "$@"
exit
fi

./bin/checkout_pinned_problem_specifications_commit.sh

set -x # show the added --offile flag
./bin/configlet "$cmd" --offline "$@"
13 changes: 13 additions & 0 deletions bin/get_problem_specifications_dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
prefix="${XDG_CACHE_HOME:-$HOME/.cache}"
elif [[ "$OSTYPE" == "darwin"* ]]; then
prefix="${XDG_CACHE_HOME:-$HOME/Library/Caches}"
else
echo "Unsupported OS: $OSTYPE" >&2
exit 1
fi

echo -n "$prefix/exercism/configlet/problem-specifications"
4 changes: 4 additions & 0 deletions bin/symlink_problem_specifications.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ set -eo pipefail

cd "$(git rev-parse --show-toplevel)"

[ -e "problem-specifications" ] || ln -s "$(./bin/get_problem_specifications_dir.sh)" "problem-specifications"

./bin/checkout_pinned_problem_specifications_commit.sh

for exercise in exercises/practice/*; do
name="$(basename "$exercise")"
if [ -d "problem-specifications/exercises/$name" ]; then
Expand Down
15 changes: 15 additions & 0 deletions bin/update_problem_specifications.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(git rev-parse --show-toplevel)"

./bin/checkout_pinned_problem_specifications_commit.sh

dir="$(./bin/get_problem_specifications_dir.sh)"

git -C "$dir" checkout --quiet main
git -C "$dir" pull --quiet

new_commit_hash="$(git -C "$dir" rev-parse main)"

sed -i "s/^PINNED_COMMIT_HASH=.*$/PINNED_COMMIT_HASH=\"$new_commit_hash\"/g" ./bin/checkout_pinned_problem_specifications_commit.sh
13 changes: 8 additions & 5 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
_default:
just --list --unsorted

# configlet wrapper, uses problem-specifications submodule
configlet *args="":
@[ -f bin/configlet ] || bin/fetch-configlet
./bin/configlet {{ args }}
# configlet wrapper, uses pinned problem-specifications commit
@configlet *args="":
./bin/configlet_wrapper.sh {{ args }}

# update the pinned commit hash
update-problem-specs:
./bin/update_problem_specifications.sh

# generate a new uuid straight to your clipboard
uuid:
./bin/configlet uuid | tr -d '[:space:]' | wl-copy
just configlet uuid | tr -d '[:space:]' | wl-copy

# simulate CI locally (WIP)
test:
Expand Down
1 change: 0 additions & 1 deletion problem-specifications
Submodule problem-specifications deleted from 6c44c8
2 changes: 1 addition & 1 deletion rust-tooling/ci-tests/tests/bash_script_conventions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn error_handling_flags() {
for_all_scripts(|file_name| {
let contents = std::fs::read_to_string(PathBuf::from("bin").join(file_name)).unwrap();
assert!(
contents.contains("set -eo pipefail"),
contents.contains("set -euo pipefail") || contents.contains("set -eo pipefail"),
"'{file_name}' should set error handling flags 'set -eo pipefail'"
);
})
Expand Down

0 comments on commit 2a66d7d

Please sign in to comment.