-
Notifications
You must be signed in to change notification settings - Fork 47
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
Improving null safety: Add FinalizedBsConfig and tweak plugin events #1000
Improving null safety: Add FinalizedBsConfig and tweak plugin events #1000
Conversation
src/Program.ts
Outdated
@@ -60,7 +60,7 @@ export class Program { | |||
/** | |||
* The root directory for this program | |||
*/ | |||
public options: BsConfig, | |||
public options: FinalizedBsConfig, |
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 you'd like this to be a backwards-compatible change we could let BsConfig
be passed here, and then apply normalizeConfig
inside of the constructor. This feels a little weird to me, because it's letting potentially invalid data get pretty far into the program before getting normalized, but I can't think of any concrete cases where it would be harmful.
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.
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.
Sounds good to me. I've fixed this and reverted all of the test changes that were necessitated by the interface change.
This has significantly shrunk this PR. Should I keep it small or should I roll in the rest of the changes I have waiting in the wings? (I have a branch off of this branch that fixes a few hundred more issues.) I'm not sure how you want to group these changes since some of them may be breaking changes to the externally-published type definitions.
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.
Let's keep this PR as-is, and open new ones with other stuff. Feel free to open those other PRs targeting this one so you don't have to keep remembering which one is next. They'll get back in sync as we merge.
e7eb8b0
to
6d6d95e
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.
Got a few suggestions, but overall looking good!
src/Program.ts
Outdated
@@ -74,12 +74,13 @@ export class Program { | |||
//normalize the root dir path | |||
this.options.rootDir = util.getRootDir(this.options); | |||
|
|||
this.createGlobalScope(); | |||
this.globalScope = this.createGlobalScope(); |
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 was the purpose of changing this to an assignment? The global scope was created in createGlobalScope
.
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.
This was to make it easier to convince TS that this was indeed created in the constructor. As an alternative I could declare the scope property on the class as public globalScope: Scope = undefined as any
, which might be less disruptive.
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.
Updated to public globalScope: Scope = undefined as any
src/ProgramBuilder.ts
Outdated
@@ -237,6 +243,9 @@ export class ProgramBuilder { | |||
* The rootDir for this program. | |||
*/ | |||
public get rootDir() { | |||
if (!this.program) { | |||
throw new Error('Cannot call `ProgramBuilder.rootDir` until after `ProgramBuilder.run()`'); |
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.
throw new Error('Cannot call `ProgramBuilder.rootDir` until after `ProgramBuilder.run()`'); | |
throw new Error('Cannot access `ProgramBuilder.rootDir` until after `ProgramBuilder.run()`'); |
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.
fixed!
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 a few suggestions, but overall looking good!
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.
Everything looks great. Thanks for this!
This only reduces the total number of null check errors by 30, but it pushes the errors a little farther towards the edges. I've resolved most of the errors in
Program
andProgramBuilder
. I believe this may be a breaking change, if plugins are allowed to callnew Program()
, because the interface toProgram
's constructor is now more strict.I'm a little unsure of what to do about
FinalizedBsConfig.rootDir
andFinalizedBsConfig.stagingDir
. I'd like to make them required, because a number of places assume that they exist. AFAICT their default values come from roku-deploy though, rather than anywhere inbsc
, and if I add the default values from roku-deploy tonormalizeConfig
, tons of tests break. I'm figuring that it's better to make incremental progress by making the other fields required than it is to risk breakage by making a more significant change to runtime behavior.I've added a unit test that asserts that the return value of
normalizeConfig
deeply matches an exact object. I added this test and confirmed that it was passing before making any changes tonormalizeConfig
. This is to give some level of confidence that behavior is unchanged, even though I've had to update the configs in a lot of other tests to satisfy the more strict types.The changes to the plugin interface are as I mentioned in Slack, and shouldn't be more restrictive than what already exists. I made the name a little prettier than what I originally used in the Slack thread.