-
Notifications
You must be signed in to change notification settings - Fork 20
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
Wizard feature v2 #220
Wizard feature v2 #220
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## development #220 +/- ##
================================================
+ Coverage 77.24% 90.30% +13.06%
================================================
Files 40 45 +5
Lines 1472 1753 +281
================================================
+ Hits 1137 1583 +446
+ Misses 335 170 -165
Flags with carried forward coverage won't be shown. Click here to find out more.
☔ View full report in Codecov by Sentry. |
gdk/wizard/commands/prompt.py
Outdated
# with open(self.project_config_file, "w") as config_file: | ||
# json.dump(self.field_map, config_file, indent=2) |
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.
Remove if not required anymore
gdk/wizard/commons/getters.py
Outdated
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 do you have separate getter and setter files? In Java, bean class with attributes have getters and setters defined in same class. Is this is standard practice in python to have separate classes?
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'm not 100% sure if it is standard practice to have them in separate file. My thought process for to minimize the size of each file and separate out distinct task to hopefully make the code easier to 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.
Sorry to jump in unannounced...I get email notifications and thought I could contribute an opinion here:
Echoing Urvashi's point, I suggest designing around your data model rather than language concepts. For example, get author is really a behavior of project config. Wizard_getter#get_author
vs ProjectConfig#get_author
.
IMO, you get more discoverability and self-documentation with the latter approach. ProjectConfig
clearly shows everything you can do with config, rather than having to inspect the whole Wizard_getter
class to figure that out.
gdk/wizard/commons/checkers.py
Outdated
"then", | ||
} | ||
|
||
if isinstance(schema, dict): |
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.
Use camel case for isInstance
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.
For Python isinstance is a built-in function
gdk/wizard/commons/checkers.py
Outdated
elif key not in ignore_fields: | ||
traverse_schema(value, field_name) | ||
|
||
elif isinstance(schema, 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.
Same here
gdk/wizard/commands/prompt.py
Outdated
# args = self.parser.parse_args( | ||
# [f'--{field}', input(f"Current value of the {require}{field} is {value}: ")] | ||
# ) |
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.
Remove if not required
gdk/wizard/commands/prompt.py
Outdated
[ | ||
f"--change_{build_or_publish}", | ||
input( | ||
f"Do you want to change the {build_or_publish} configurations? (y/n) " |
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 do you want input from Customer? Even if they select "n" the fields will still be editable..right? Or you would simply exit the wizard? What is the behavior in each scenario?
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 idea was to allow users to be prompted in an hierarchical manner. 'custom_build_command' and 'build_system' fall under the umbrella of build and "bucket", "region", and "options" all fall under the umbrella of publish, so if we first ask the user if they would like to change the build config or regions at all before prompting to change specific fields under their respective umbrellas. If the user respond 'n' the prompter would simply skip over the fields in build or publish.
gdk/wizard/tests/__init__.py
Outdated
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.
Remove this file along with the static and the integration folders.
gdk/wizard/commands/data.py
Outdated
|
||
class Wizard_data: | ||
def __init__(self): | ||
self.project_config_file = "/Users/jacksozh/Desktop/aws-greengrass-gdk-cli/gdk/wizard/static/default_config.json" |
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 if file exists? Also, you are specifying your local path which will not be present on customer's system.
gdk/wizard/commands/prompt.py
Outdated
getter: Wizard_getter object | ||
setter: Wizard_setter object |
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.
Update this.
gdk/wizard/commands/prompt.py
Outdated
------- | ||
string: the value for the field key "field" | ||
""" | ||
require = "required " if required else "OPTIONAL " |
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.
Any particular reason why required is in small case and optional is in upper case?
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.
My apologize, I should have been more consistent. I will change them both to upper case for readability and consistency.
gdk/wizard/tests/test_data.py
Outdated
def test_init(self): | ||
# self.project_config_file = _get_project_config_file() | ||
# self.field_map = get_configuration() | ||
# self.project_config = self.field_map["component"] | ||
# self.component_name = next(iter(self.project_config)) | ||
# self.schema = self.get_schema() | ||
pass | ||
|
||
def test_get_schema(): | ||
pass |
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 do not understand this. Are you defaulting it to pass?
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.
My apologizes, the test cases for this section is not yet complete. I just used pass for now
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.
Add a comment then to inform reviewers that it will be updated in future CR.
gdk/wizard/commands/data.py
Outdated
import json | ||
|
||
|
||
class Wizard_data: |
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.
Rename all the class names to camel case - WizardData
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.
Got it
gdk/wizard/commands/data.py
Outdated
# self.project_config_file = _get_project_config_file() | ||
# self.field_map = get_configuration() |
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.
Remove these.
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.
We only need one module for Wizard. So, remove commands and commons modules and merge them into existing ones. We also don't need separate ones just for the wizard functionality testing. Do the same for them as well.
return isinstance(input_value, str) and input_value in allowed_build_systems | ||
|
||
def check_custom_build_command(self, input_value): | ||
# input must be a non-empty string or a non-empty list of strings |
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.
Nit : Use """ """
for multi-line comments.
"""
Line 1
Line 2
....
""""
gdk/wizard/commons/model.py
Outdated
|
||
def get_author(self): | ||
try: | ||
return self.project_config[self.component_name][Fields.AUTHOR.value.key] |
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.
Use return self.project_config.get(self.component_name, default_value)
instead, here and at every other place.
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.
gotcha, I'm assuming that you mean that I should replace return self.project_config[self.component_name] with return self.project_config.get(self.component_name, default_value) and have a default value for component_name ?
gdk/wizard/commands/prompt.py
Outdated
print("Exceeded maximum attempts. Assuming default response.") | ||
return value | ||
|
||
def change_build_or_publish(self, build_or_publish, max_attempts=3): |
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 are we asking for these two together?
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.
Oh its not asking both questions at once. It's asking about build or publish depending on the value of build_or_publish
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 that nothing changes on the customer side but I don't think we need to club these two together in the code. Build and publish are two independent configs so coupling these two will make it hard for us to maintain and test the code in future.
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.
Got it I will separate them out
Issue #, if available:
Description of changes:
Version 2 of the wizard:
Why is this change necessary:
How was this change tested:
change will be tested
Any additional information or context required to review the change:
Checklist:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.