Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise error if pinned hash from .configure file is not found #410

Open
wants to merge 7 commits into
base: trunk
Choose a base branch
from

Conversation

mokagio
Copy link
Contributor

@mokagio mokagio commented Sep 20, 2022

I just run into this edge case while attempting to update a repository.

bundle exec run configure_update crashed on me because it tried to compare nil and a number with >=.

The nil value was the result of looking for the index of the pinned commit in .configure in the .mobile-secrets repository.

I believe that occurred because, when prompted

[13:24:11]: The current branch is 2 commit(s) behind. Would you like to update it? (y/n)

I selected no, resulting in my local copy of .mobile-secrets to be two commits out of date.

For the record, I selected n because I interpreted the prompt as a suggestion to update the pinned has in .configure, not the .mobile-secrets repository. The messages to STDOUT from the tool's internal made me think it already pulled the repo.

Regardless of how I ended up in that inconsistent state, I think this early failure and error message would have helped me.

For reference, below is the stacktrace:

(/path/to/repo/vendor/bundle/ruby/2.7.0/bin/fastlane) Traceback (most
recent call last):
[...]
8: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:229:in
`execute_action'
7: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:229:in
`chdir'
6: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:255:in
`block in execute_action'
5: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/actions/actions_helper.rb:69:in
`execute_action'
4: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:263:in
`block (2 levels) in execute_action'
3: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_update_action.rb:20:in
`run'
2: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_update_action.rb:94:in
`configure_file_is_behind_repo'
1: from
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb:98:in
`configure_file_is_behind_local'
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb:109:in
`configure_file_commits_behind_repo': \e[31m[!] undefined method `>=' for
nil:NilClass\e[0m (NoMethodError)

I just run into this edge case while attempting to update a repository.

`bundle exec run configure_update` crashed on me because it tried to
compare `nil` and a number with `>=`.

The `nil` value was the result of looking for the index of the pinned
commit in `.configure` in the `.mobile-secrets` repository.

I believe that occurred because, when prompted

```
[13:24:11]: The current branch is 2 commit(s) behind. Would you like to update it? (y/n)
```

I selected no, resulting in my local copy of `.mobile-secrets` to be two
commits out of date.

For the record, I selected `n` because I interpreted the prompt as a
suggestion to update the pinned has in `.configure`, not the
`.mobile-secrets` repository. The messages to `STDOUT` from the tool's
internal made me think it already pulled the repo.

Regardless of how I ended up in that inconsistent state, I think this
early failure and error message would have helped me.

For reference, below is the full stacktrace:

```
bundler: failed to load command: fastlane (/path/to/repo/vendor/bundle/ruby/2.7.0/bin/fastlane)
Traceback (most recent call last):
	37: from /path/to/repo/gio/.rbenv/versions/2.7.4/bin/bundle:23:in `<main>'
	36: from /path/to/repo/gio/.rbenv/versions/2.7.4/bin/bundle:23:in `load'
	35: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/exe/bundle:36:in `<top (required)>'
	34: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors'
	33: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/exe/bundle:48:in `block in <top (required)>'
	32: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:25:in `start'
	31: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
	30: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:31:in `dispatch'
	29: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
	28: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
	27: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
	26: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:485:in `exec'
	25: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:23:in `run'
	24: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:58:in `kernel_load'
	23: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:58:in `load'
	22: from /path/to/repo/vendor/bundle/ruby/2.7.0/bin/fastlane:23:in `<top (required)>'
	21: from /path/to/repo/vendor/bundle/ruby/2.7.0/bin/fastlane:23:in `load'
	20: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/bin/fastlane:23:in `<top (required)>'
	19: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off'
	18: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/commands_generator.rb:43:in `start'
	17: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/commands_generator.rb:354:in `run'
	16: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!'
	15: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!'
	14: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command'
	13: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/command.rb:157:in `run'
	12: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/command.rb:187:in `call'
	11: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/commands_generator.rb:226:in `block (2 levels) in run'
	10: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/one_off.rb:22:in `execute'
	 9: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/one_off.rb:42:in `run'
	 8: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:229:in `execute_action'
	 7: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:229:in `chdir'
	 6: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action'
	 5: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/actions/actions_helper.rb:69:in `execute_action'
	 4: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:263:in `block (2 levels) in execute_action'
	 3: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_update_action.rb:20:in `run'
	 2: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_update_action.rb:94:in `configure_file_is_behind_repo'
	 1: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb:98:in `configure_file_is_behind_local'
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb:109:in `configure_file_commits_behind_repo': undefined method `>=' for nil:NilClass (NoMethodError)
	37: from /path/to/repo/gio/.rbenv/versions/2.7.4/bin/bundle:23:in `<main>'
	36: from /path/to/repo/gio/.rbenv/versions/2.7.4/bin/bundle:23:in `load'
	35: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/exe/bundle:36:in `<top (required)>'
	34: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors'
	33: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/exe/bundle:48:in `block in <top (required)>'
	32: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:25:in `start'
	31: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
	30: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:31:in `dispatch'
	29: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
	28: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
	27: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
	26: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:485:in `exec'
	25: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:23:in `run'
	24: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:58:in `kernel_load'
	23: from /path/to/repo/gio/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:58:in `load'
	22: from /path/to/repo/vendor/bundle/ruby/2.7.0/bin/fastlane:23:in `<top (required)>'
	21: from /path/to/repo/vendor/bundle/ruby/2.7.0/bin/fastlane:23:in `load'
	20: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/bin/fastlane:23:in `<top (required)>'
	19: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off'
	18: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/commands_generator.rb:43:in `start'
	17: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/commands_generator.rb:354:in `run'
	16: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!'
	15: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!'
	14: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command'
	13: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/command.rb:157:in `run'
	12: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/commander-4.6.0/lib/commander/command.rb:187:in `call'
	11: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/commands_generator.rb:226:in `block (2 levels) in run'
	10: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/one_off.rb:22:in `execute'
	 9: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/one_off.rb:42:in `run'
	 8: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:229:in `execute_action'
	 7: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:229:in `chdir'
	 6: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action'
	 5: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/actions/actions_helper.rb:69:in `execute_action'
	 4: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-2.210.0/fastlane/lib/fastlane/runner.rb:263:in `block (2 levels) in execute_action'
	 3: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_update_action.rb:20:in `run'
	 2: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_update_action.rb:94:in `configure_file_is_behind_repo'
	 1: from /path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb:98:in `configure_file_is_behind_local'
/path/to/repo/vendor/bundle/ruby/2.7.0/gems/fastlane-plugin-wpmreleasetoolkit-5.4.0/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb:109:in `configure_file_commits_behind_repo': \e[31m[!] undefined method `>=' for nil:NilClass\e[0m (NoMethodError)
```
result = `cd #{repository_path} && git --no-pager log -10000 --pretty=format:"%H" && echo`
hashes = result.each_line.map { |s| s.strip }.reverse

index_of_configure_hash = hashes.find_index(configure_file_commit_hash)

UI.user_error!("Could not find Git commit #{configure_file_commit_hash} from `.configure` file in local secrets repository. Please verify your local copy is up to date with the remote.") if index_of_configure_hash.nil?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2022-09-20 at 1 34 30 pm

@mokagio mokagio marked this pull request as ready for review September 20, 2022 03:54
@mokagio mokagio self-assigned this Sep 20, 2022
@AliSoftware
Copy link
Contributor

AliSoftware commented Sep 20, 2022

For the record, I selected n because I interpreted the prompt as a suggestion to update the pinned has in .configure, not the .mobile-secrets repository. The messages to STDOUT from the tool's internal made me think it already pulled the repo.

To be honest, the configure tool has always confused me a lot in terms of its terminology, commands and log messages / prompts. I never remember which of the subcommands do what (update, apply, etc) in which direction (encrypt secrets from mobile-secrets into .enc files in repo? Copy secrets from mobile-secrets raw for immediate local consumption? Decrypt .enc files?), nor what the prompts shown by the tool really mean ("Would you like to update [something unclear about what it will update and in which direction]?".

I'd really love if we could make some improvement in the self-documentation and log messages of this tool at some point, to avoid a lot of confusion around it 😓

Copy link
Contributor

@AliSoftware AliSoftware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error message seems clear enough to me.

I think we can improve the tool logic that it uses to find the distance between current and requested commit, but I'll let you decide if it's worth working on this in this PR, or a subsequent one.

@@ -99,11 +99,16 @@ def self.configure_file_is_behind_local
end

def self.configure_file_commits_behind_repo
# Get a sily number of revisions to ensure we don't miss any
# Get a large number of revisions to ensure we don't miss any
result = `cd #{repository_path} && git --no-pager log -10000 --pretty=format:"%H" && echo`
Copy link
Contributor

@AliSoftware AliSoftware Sep 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why the tool uses this kind of solution instead of using ad-hoc git commands like git -c "#{repository_path}" rev-list --count #{configure_file_commit_hash}..HEAD for example…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cool. I'll implement in the context of this PR because there's no rush to merge it as it.

Copy link
Contributor

@AliSoftware AliSoftware Sep 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 In that case you might also want to take the occasion to look at the git Ruby gem (that I think we already use in other parts of the release-toolkit and is already one of our dependencies) to implement that call instead and to avoid the shell out 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why the tool uses this kind of solution

Because the author (me) was a noob 😜

Copy link
Contributor

@AliSoftware AliSoftware Dec 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cool. I'll implement in the context of this PR because there's no rush to merge it as it.

@mokagio FYI I am about to make a new release of the toolkit today to ship some new features I want to use in WPAndroid/WCAndroid.

Since you mentioned you'd implement the suggested change above in this PR rather than a separate one, I won't include this PR it in the upcoming release… except if you would like me to merge it as is (modulo CHANGELOG conflict resolution) now to include it after all, and plan for addressing the change in a future subsequent one? 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the ping. Here's another nice to have but not urgent PR that may take a while to get addressed... 🤔

I missed the boat on 6.1.0, #432, so I might as well keep this in the queue in the hope to get to it sooner rather than later.

Copy link
Contributor Author

@mokagio mokagio Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 09d3863 with some help from Cursor to write the integration tests

Not impressed with the fact that I asked it to help me write tests to support refactoring and it suggested tests that stubbed out the method calls 😓

image

image

@jkmassel
Copy link
Contributor

@mokagio, somehow this is still sitting on my review list?

Figured I'd bump it :)

@mokagio mokagio requested a review from AliSoftware January 30, 2025 05:36
@mokagio
Copy link
Contributor Author

mokagio commented Jan 30, 2025

@jkmassel Thanks for the ping! I got to addressing the Git implementation suggestion in the end.

But that only made me realize that there are various other git... calls done with `` in the code. I resisted the temptation of addressing them here and added a note in #572 instead.

@mokagio mokagio enabled auto-merge January 30, 2025 05:38
@mokagio mokagio added the bug Something isn't working label Jan 30, 2025
Comment on lines +9 to +16
def run_git_command(command:, repo_path: test_repo_path)
# Notice that this will break if the command contains arguments in quotes,
# e.g. `commit -m "Test commit"` will be split into `['commit', '-m', '"Test', 'commit"']`
# which is not a valid arguments list for Git.
#
# For the context of these tests, we can deal with this limitation.
system('git', '-C', repo_path, *command.split, %I[out err] => File::NULL)
end
Copy link
Contributor

@AliSoftware AliSoftware Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gosh this feels a bit dirty nowadays compared to when that PR was first opened 2 years ago, and very tempting to migrate the implementation of all this to (1) use the git gem instead of system shell calls directly for a cleaner implementation and tests (2) and thus lift this limitation as a bonus side effect.

I'd also argue that those specs end up being more integration tests (with them creating a dummy local git repo in a temp dir for each spec example) than unit tests focusing on how it's being tested 🤔 (though to be able to write them as unit tests it'd be simpler to update the implementation first so it'd make it easier to mock the git actions in the spec to begin with …)


But at this point and given the age of this PR, better finally land it and postpone that refactor for later (as you mentioned above and in #572) than continue pushing the can down the road and never merging this 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking back to this and I also realized that this should be implemented with the APIs from the git gem.

I'd also argue that those specs end up being more integration tests

That was intentional. I wanted to update the implementation from "shelling out in one single command that calls Git etc." to "uses git gem APIs for (hopefully) better and neater code." The only way to make sure that my rewrite was a correct refactor was to test the end state instead of how the code interacted with Git.

I think this approach is best in the instance of interacting with the outside world, like we do with Git here.

The only other option I can think of that I would consider as good from the testing point of view is what I would do in Swift where I'd wrap Git in a protocol and provide a test double in the tests. But that's not really a thing in Ruby.

@mokagio
Copy link
Contributor Author

mokagio commented Feb 2, 2025

Just waiting for #627 to land and address the Danger issue...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants