Skip to content

Conversation

@natescherer
Copy link

Hello! This is my attempt to complete the work that was done in #1031. (Should close #1020, as well.)

What's Changed

Here's what I've changed versus the previous PR, by type:

Outstanding changes requested in discussions on old PR

  • Subcommand updated to check-update
  • Hard-coded exit code when an update is detected to 5
  • Tests added

Necessary Updates

  • Restructured to match updates made to project in the intervening years

Other Changes

  • Minor rewording
  • Added --check-update-output-as-json flag for integrating with CI/scripts/etc
    • I'm not in love with this name but seeing as how I had to add it at the Worker level I figured I should make it pretty specific

Questions/To-Do

I have a few questions for the maintainers:

  • Are we sure that having the app exit with an error when there is an update is the right pattern?
    • I preserved it based on the work previously done, but if I was designing this from scratch, I wouldn't consider an update being available an error in the classic sense
    • My addition of --check-update-output-as-json provides a hook for scripts to detect if there is an update, from the discussions I saw before that seemed to be the overall intention of the exit code
  • What level of documentation would you like for this subcommand?
    • Maybe a docs/checking_for_updates.md?

Thanks for making such an awesome tool! Please let me know if there are changes you'd like me to make.

Copy link
Member

@sisp sisp left a comment

Choose a reason for hiding this comment

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

Thanks for contributing this feature to Copier, @natescherer! 🙇

I've left a couple of inline comments.

Comment on lines +465 to +468
check_update_output_as_json = cli.Flag(
["--check-update-output-as-json"],
help="Output a JSON object to stdout containing information about if an update is needed",
)
Copy link
Member

Choose a reason for hiding this comment

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

How about renaming this flag to --output-format with two allowed values plain and json similar to, e.g., Ruff's corresponding flag?

--output-format <OUTPUT_FORMAT>
    Output serialization format for violations. The default serialization
    format is "full" [env: RUFF_OUTPUT_FORMAT=] [possible values:
    concise, full, json, json-lines, junit, grouped, github, gitlab,
    pylint, rdjson, azure, sarif]

Copy link
Author

Choose a reason for hiding this comment

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

Works for me, is an updated help message like this acceptable?

Output format, either 'plain' (the default) or 'json'. This flag is only supported by the 'check-update' subcommand.

Copy link
Member

Choose a reason for hiding this comment

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

For the CLI flag, the context is clear, so the second sentence isn't needed. But it makes sense to keep it for the Worker class attribute. One day, I'll try to split this class, so we won't have attributes that are only meaningful for some operations. 🤞

Comment on lines +1484 to +1485
"update_available": self.template.version
> self.subproject.template.version,
Copy link
Member

Choose a reason for hiding this comment

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

This might be a bit more legible with surrounding parentheses:

Suggested change
"update_available": self.template.version
> self.subproject.template.version,
"update_available": (
self.template.version > self.subproject.template.version
),

Comment on lines +1497 to +1498
"Parent template update available. "
f"\nCurrent version is {self.subproject.template.version}, "
Copy link
Member

Choose a reason for hiding this comment

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

  • I think "template" suffices, parent template sounds like the parent of a template in a hierarchy. Or perhaps even "New template version available"? WDYT?
  • I'd move the line break to the first line for better legibility.
Suggested change
"Parent template update available. "
f"\nCurrent version is {self.subproject.template.version}, "
"New template version available.\n"
f"Current version is {self.subproject.template.version}, "

Copy link
Author

Choose a reason for hiding this comment

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

Good point, I agree with the terminology change. I have been making a series of hierarchical templates myself and got my wires crossed I think.

Copy link
Member

Choose a reason for hiding this comment

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

Since this is a new test file for an entirely new feature, can we reduce the test cases code to a minimum?

  • Avoid Git bundles.
  • Avoid custom _envops settings.
  • Minimize test file content (README.txt.jinja).
  • Keep commit messages simple, e.g. git("commit", "-m", "v1").

It might make sense to factor out the test template to a fixture, similar to, e.g., this:

@pytest.fixture(scope="module")
def template_path(tmp_path_factory: pytest.TempPathFactory) -> str:
root = tmp_path_factory.mktemp("template")
build_file_tree(
{
root / "{{ _copier_conf.answers_file }}.jinja": """\
# Changes here will be overwritten by Copier
{{ _copier_answers|to_nice_yaml }}
""",
root / "copier.yml": """\
_answers_file: ".copier-answers-{{ module_name }}.yml"
module_name:
type: str
""",
}
)
return str(root)

Copy link
Author

Choose a reason for hiding this comment

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

Sure, I can simplify it. I just grabbed an existing test more or less at random, I agree it is a little over complex.

@natescherer
Copy link
Author

@sisp While I'm working on those changes, would appreciate your thoughts on the two questions I raised at the bottom of the PR, thanks. 🙏

Copy link
Member

@sisp sisp left a comment

Choose a reason for hiding this comment

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

Regarding the exit code: I think exiting with 0 when there's no update (i.e., the project is up-to-date) and with non-zero otherwise seems reasonable. At least Cruft follows a similar approach. The specific non-zero exit code is another question. Cruft exits with 1 when there is an update, but 1 is already used for, e.g., precondition errors like a missing old template reference. Exit code 2 is used for indicating unsafe templates without explicit user trust, but this error can only occur for copy and update operations but never when checking for an update. I think it's fine to use the same exit code for different errors by different subcommands.

[...] but if I was designing this from scratch, I wouldn't consider an update being available an error in the classic sense

What exactly do you mean by "in the classic sense"?


Regarding documentation: How about adding a section on our "Updating a project" page, similar to Cruft's corresponding section?

Comment on lines +465 to +468
check_update_output_as_json = cli.Flag(
["--check-update-output-as-json"],
help="Output a JSON object to stdout containing information about if an update is needed",
)
Copy link
Member

Choose a reason for hiding this comment

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

For the CLI flag, the context is clear, so the second sentence isn't needed. But it makes sense to keep it for the Worker class attribute. One day, I'll try to split this class, so we won't have attributes that are only meaningful for some operations. 🤞

@natescherer
Copy link
Author

Sounds good re: the documentation.

As far as what I mean by "in the classic sense" this is probably my SRE brain talking, but I tend to see any application ending with a non-zero status code as indicating that there is some failure in execution, but there's no failure/error/issue when the sub command checks and sees there is an update; the update checking process worked just fine. Hopefully that makes sense?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a 'check' CLI command / API to check for new template version

3 participants