-
Notifications
You must be signed in to change notification settings - Fork 12
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
Include comments in config files generated with --create-config-file #588
Conversation
Codecov ReportPatch coverage:
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. Additional details and impacted files@@ Coverage Diff @@
## main #588 +/- ##
==========================================
+ Coverage 80.73% 80.82% +0.08%
==========================================
Files 19 19
Lines 2819 2832 +13
==========================================
+ Hits 2276 2289 +13
Misses 543 543
☔ View full report in Codecov by Sentry. |
topostats/run_topostats.py
Outdated
config_file=args.create_config_file, | ||
header_message="Sample configuration file auto-generated", | ||
) | ||
default_config_path = pkg_resources.path(__package__, "default_config.yaml") |
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.
I understand why this is here but I think we can make things a little simpler by changing some code earlier on.
Currently on lines 146-150 we have...
if args.config_file is not None:
config = read_yaml(args.config_file)
else:
default_config = pkg_resources.open_text(__package__, "default_config.yaml")
config = yaml.safe_load(default_config.read())
...and so we have two lines that are very similar here as they both have pkg_resources.open_text(__package__, "default_config.yaml")
.
If we change the logic of the earlier code we only need to have one line for setting the path to the default_config.yaml
...
if args.config_file is None:
default_config = pkg_resources.open_text(__package__, "default_config.yaml")
config = yaml.safe_load(default_config.read())
else:
config = read_yaml(args.config_file)
...and the above line is no longer needed (although line 172 would need changing to use default_config
rather than default_config_path
).
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.
I could be misunderstanding you.
pkg_resources.open_text(__package__, "default_config.yaml")
returns a string of the contents of the config file, which is not usable by shutil.copy
, which takes a file system path. Which is the reason for using
pkg_resources.path(__package__, "default_config.yaml")
This could work if I manually saved to the file using with open() as f
, is this what you intended?
topostats/run_topostats.py
Outdated
) | ||
default_config_path = pkg_resources.path(__package__, "default_config.yaml") | ||
if ".yaml" not in args.create_config_file and ".yml" not in args.create_config_file: | ||
create_config_path = "./" + args.create_config_file + ".yaml" |
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.
Not tested this on M$-Win but would the hard coding of ./
cause any problems? I've a vague memory that the Windows Linux Shell does interpret/handle these correctly. If not perhaps using pathlib.Path("./")
might mitigate the problem (if there is one!).
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.
Thanks for getting this one sorted too @SylviaWhittle
I've suggested a slight change to avoid duplicated lines simply by changing earlier logic.
I think its a bit of a shame to lose the file header which indicates when the sample config was generated but date/time isn't too reliable given people could be on different branches anyway and besides we ask for the config used at any given point to be included in Bug Reports anyway.
Thanks for the comments @ns-rse, I've just pushed a re-jig of it, where I use your suggestion above, and I create a function in I had to add a line to ensure users are not running with I've also moved things about a bit with the documentation, so that we keep the There were some 404 links in the code that I have removed, leaving only a link that works. This should also mean that it should be easy to have all documentation hints standardised and removed link duplication in the codebase Let me know what you think and I'll add tests if you approve of what I've attempted (don't worry I hadn't forgotten about adding tests). 👍 |
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.
Neat, I like this solution of using a string object rather than shutil.copy
and that you've retained the file header at the same time.
Not sure its absolutely necessary to use Path.cwd()
may be overkill. 🤷
topostats/io.py
Outdated
if header_message: | ||
config_yaml.yaml_set_start_comment( | ||
f"{header_message} : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n" + documentation_reference | ||
f"{header_message} : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n" + CONFIG_DOCUMENTATION_REFERENCE |
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.
Could use the get_date_time()
function here as you do below.
A name for the configuration file. Can have a ".yaml" on the end. | ||
""" | ||
|
||
if ".yaml" not in filename and ".yml" not in filename: |
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.
Good to have this eventuality caught 👍
topostats/io.py
Outdated
@@ -86,6 +103,32 @@ def write_yaml( | |||
LOGGER.error(exception) | |||
|
|||
|
|||
def write_config_with_comments(config: str, filename: str = "config.yaml"): |
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.
Minor pedantic typehint for the return value.
def write_config_with_comments(config: str, filename: str = "config.yaml"): | |
def write_config_with_comments(config: str, filename: str = "config.yaml") -> None: |
topostats/io.py
Outdated
f.write(f"# Config file generated {get_date_time()}\n") | ||
f.write(f"# {CONFIG_DOCUMENTATION_REFERENCE}") | ||
f.write(config) | ||
LOGGER.info(f"A sample configuration has been written to : ./{filename}") |
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.
LOGGER.info(f"A sample configuration has been written to : ./{filename}") | |
LOGGER.info(f"A sample configuration has been written to : ./{str(create_config_path)}") |
...although conditional on whether you use Path.cwd()
/ Path("./") / filename
above. If not you don't need the str()
.
topostats/io.py
Outdated
""" | ||
|
||
if ".yaml" not in filename and ".yml" not in filename: | ||
create_config_path = "./" + filename + ".yaml" |
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.
Might be overkill using Path.cwd()
here and under the else:
but could.
create_config_path = "./" + filename + ".yaml" | |
create_config_path = Path.cwd() / f"{filename}.yaml" |
@@ -162,19 +170,10 @@ def main(args=None): | |||
validate_config(config, schema=DEFAULT_CONFIG_SCHEMA, config_type="YAML configuration file") | |||
|
|||
# Write sample configuration if asked to do so and exit | |||
if args.create_config_file and args.config_file: |
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.
👍
if args.config_file is not None: | ||
config = read_yaml(args.config_file) | ||
if args.config_file is None: | ||
default_config = pkg_resources.open_text(__package__, "default_config.yaml").read() |
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.
Ah, very neat trick of shifting the .read()
to get the string representation of the file.
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.
Looks good to go when the tests complete. 👍
Closes #536
This PR changes the behaviour of generating config files using the command-line flag
--create-config-file
, so that it usesshutil
to copy thedefault_config.yaml
file directly. This is a trade-off on functionality, but it seems that users would prefer the convenience of having the comments in the file.If it turns out that the users do not end up liking this change, it should be trivial to reverse it as it's a small change that does not affect any other code as far as I can tell.