Skip to content

feat(cli): provide parameter values via command line #8898

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

Merged
merged 34 commits into from
Aug 9, 2023
Merged

Conversation

mtojek
Copy link
Member

@mtojek mtojek commented Aug 4, 2023

Fixes: #8782

This PR refactors the parameter-resolving logic in Coder CLI in terms of consistency and cleaner code. Additionally, it enables passing parameter values via command line flags (--build-option and --parameter).

Note:

The business logic is updated. I may need to cover the new flags with tests, but the assumption is that existing CLI tests should not change unless there are new issues discovered.

@mtojek mtojek self-assigned this Aug 4, 2023
@mtojek mtojek changed the title feat(cli): provide parameter values via CLI feat(cli): provide parameter values via command line Aug 4, 2023
@mtojek mtojek marked this pull request as ready for review August 8, 2023 13:27
@mtojek mtojek requested a review from mafredri August 8, 2023 13:31
Copy link
Member

@mafredri mafredri left a comment

Choose a reason for hiding this comment

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

Looks good 👍. A few small suggestions and I'm thinking it might be good to have a bit more test coverage of the precedence of parameter/build values. I.e. when they're coming from previous builds, files and flags (and different combinations of). I don't see that as a reason to delay this PR though.

for i, r := range resolved {
if r.Name == name {
resolved[i].Value = value
goto done
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: We could label the loop instead and use continue Loop. Continue/break have a simpler flow and are usually considered more idiomatic Go.

(Same with other loops.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Are you thinking about this form:

next:
	for name, value := range pr.richParametersFile {
		for i, r := range resolved {
			if r.Name == name {
				resolved[i].Value = value
				continue next
			}
		}

		resolved = append(resolved, codersdk.WorkspaceBuildParameter{
			Name:  name,
			Value: value,
		})
	}

If so, then it will be a bit different logic - iterate over pr.richParametersFile again and again.

Alternatively, I can add break/if, but with goto the code is shorter/simpler.

Copy link
Member

@mafredri mafredri Aug 9, 2023

Choose a reason for hiding this comment

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

I think there's a misunderstanding around how loop labels work. This is kind of like tagging a loop so that continue knows where to go. See here (only one iteration through the range is performed): https://go.dev/play/p/oAbzFLuh8O5

The reason I say continue/break [Label] is simpler, is that they don't break control flow, whereas goto does and can go anywhere in the function.

Copy link
Member Author

Choose a reason for hiding this comment

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

return xerrors.Errorf("parameter %q is not present in the template", r.Name)
}

if tvp.Ephemeral && !pr.promptBuildOptions && len(pr.buildOptions) == 0 {
Copy link
Member

Choose a reason for hiding this comment

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

Why do we check len 0 here? Wouldn't it be possible for some build options to be provided but not this one? Should are check the contents instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

This condition only applies to ephemeral/one-time build parameters, hence tvp.Ephemeral. !pr.promptBuildOptions means that the user didn't use the flag --build-options to input manually values for next build options, and len(pr.buildOptions) == 0 means that they didn't provide them via --build-option key=value.

Copy link
Member

Choose a reason for hiding this comment

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

I understand the reasoning for the other checks, however my thinking is that, say there are two ephemeral values. The user providers only one of them via --build-option. Then len(pr.buildOptions) == 1 even though current tvp wasn't provided. Does that make sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

@mtojek
Copy link
Member Author

mtojek commented Aug 9, 2023

I'm thinking it might be good to have a bit more test coverage of the precedence of parameter/build values. I.e. when they're coming from previous builds, files and flags (and different combinations of)

I admit that I don't want to blow up CLI with an excessive number of test cases. Full coverage would require a matrix <create/update/start/restart>:<build-option>:<parameter-flag>:<parameter-file>.

@mtojek
Copy link
Member Author

mtojek commented Aug 9, 2023

I'm going to merge this PR, and apply fixes in follow ups if necessary. In the worst case, this PR be reverted entirely as it just modifies CLI.

@mtojek mtojek merged commit 0d382d1 into main Aug 9, 2023
@mtojek mtojek deleted the 8782-build-option branch August 9, 2023 11:00
@github-actions github-actions bot locked and limited conversation to collaborators Aug 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Specify one-time parameters on CLI command line
2 participants