-
Notifications
You must be signed in to change notification settings - Fork 31
feat(7983): improving warnings on incorrect or absent configuration #193
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- .envrc: Language not supported
b7a3909
to
08876e1
Compare
26b75af
to
e08e621
Compare
e08e621
to
84e4286
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM Kieran, I haven't touched the CLI before but your changes are concise, well-documented and make sense.
It might still be best to get a review from someone with more CLI experience than me.
if [ ! -d ".venv" ] | ||
then | ||
# System python doesn't like us installing packages into it | ||
# Test if uv is already installed (via brew or other package manager etc.) | ||
# and use that if available. Otherwise fall back to previous behvaiour | ||
if command -v uv | ||
then | ||
uv venv .venv --python $PYTHON_VERSION | ||
uv pip install -U pip uv | ||
uv pip install -e . | ||
else | ||
python -m uv venv .venv --python $PYTHON_VERSION | ||
python -m uv pip install -U pip uv | ||
python -m uv pip install -e . | ||
fi | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't see this mentioned in the PR description.
There is probably something to be done here. You're right to question the awkward combination of tooling, but I think it's better to omit this from the PR and raise it separately.
return f"{self.__class__.__name__} - {self.cloudsmith_host}" | ||
|
||
|
||
class CliWarnings(list): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why inherit from list here? Can't we just use composition rather than inheritance?
def __dedupe__(self) -> List[CliWarning]: | ||
return list(set(self.warnings)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid user-defined dunders.
I don't see this used anywhere except in the test... what do we need it for?
def __repr__(self) -> str: | ||
return self.__str__() | ||
|
||
def __str__(self) -> str: | ||
return ",".join([str(x) for x in self.warnings]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB: __str__
implicitly returns __repr__
. You only need to define __repr__
.
|
||
def __eq__(self, other): | ||
if not isinstance(other, self.__class__): | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return False | |
return NotImplemented |
class CliWarning(ABC): | ||
""" | ||
Abstract base class for all Cloudsmith CLI warnings. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the benefit of using an abstract base class for this purpose?
if not any(list(existing_config_paths.values())): | ||
config_load_warning = ConfigLoadWarning( | ||
paths=existing_config_paths, | ||
) | ||
warnings.append(config_load_warning) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want to warn if no config file was found?
The user might have provided the CLOUDSMITH_API_KEY
environment variable for example, such as we do in the pytest suite.
opts = config.get_or_create_options(ctx) | ||
|
||
if warnings and not opts.no_warn: | ||
click_warn_partial = partial(click.secho, fg="yellow") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't write warnings to stdout.
(Question: Is writing to stdout why a bunch of pre-existing tests now need the pytest fixture to suppress these warnings? If we write warnings to stderr instead, do those tests pass without that fixture?)
click_warn_partial = partial(click.secho, fg="yellow") | |
click_warn_partial = partial(click.secho, fg="yellow", err=True) |
) | ||
|
||
|
||
class TestWarnings: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WLTS tests that replicate the scenarios mentioned in the PR description.
|
||
|
||
@pytest.fixture() | ||
def set_no_warn_env_var(): | ||
"""Set the CLOUDSMITH_API_KEY environment variable.""" | ||
os.environ["CLOUDSMITH_CLI_NO_WARN"] = "True" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The need to add this fixture to so many pre-existing tests is a bit of a smell.
No, I'm not advocating for autouse=True
:)
What?
Improve Cloudsmith CLI user experience when encountering configuration issues or uncertainties. Can be disabled with a
--no-warn
flagWhy?
Currently, there are a number of potential pitfalls around config management for the Cloudsmith CLI. These include:
Acceptance Criteria (Is It Done?)
Screenshots