-
Notifications
You must be signed in to change notification settings - Fork 46
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
[WIP] package.json helper class #34
base: master
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## master #34 +/- ##
=========================================
+ Coverage 88.85% 89.16% +0.3%
=========================================
Files 19 20 +1
Lines 1795 1855 +60
Branches 368 385 +17
=========================================
+ Hits 1595 1654 +59
- Misses 200 201 +1
Continue to review full report at Codecov.
|
+1 |
If we add support for changing packaging name and version, then yes, I'd agree. Currently though, it's intended that |
I think I would make writes explicit either way. Reasons:
I've had a few more thoughts about this: My first thought was that this actually solves more problems than it should. To me, modifying a package.json file while keeping its formatting intact and updating cordova specific contents of package.json seem to be different enough to warrant separate tools (Interface segregation principle). I think the very generic name is partly a symptom of that too. The use cases for Trying to formulate suggestions for other aspects of this class, I found that it was very hard to do so because I couldn't exactly pinpoint the scope of this class. Some use cases that I saw covered by this class:
Use cases I came up with but that weren't handled (they might be irrelevant; I just don't know):
Maybe you have a better overview of the relevance of these use cases in the current code base. Another thought was, that we might even want to aggregate information for plugins/platforms like it is in config.xml (i.e. an object with I hope these remarks weren't too much of a stream of consciousness. I just wanted to get out some of my thoughts about this in the hopes that some of them might actually be helpful. I find it very hard to do the right thing here, which is probably at least in part due to the fact that this change intersects with the topic of package management in Cordova and the messed up state of the latter. |
src/PackageHelper.js
Outdated
* @returns {CordovaMetadata} The Cordova project metadata. | ||
*/ | ||
get cordova () { | ||
return this.pkgfile.cordova || {}; |
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 think this getter and the related platform and plugin getters are somewhat problematic. Consider the following scenario:
const ph = new PackageHelper(...);
ph.cordova.foo = 'bar';
ph.writeSync();
I guess that's not a use case you had in mind, but it's possible. The problem is it persists foo
if and only if we already had a cordova
object. A more probable scenario with a similar problem would be a batch update of platforms:
const ph = new PackageHelper(...);
ph.cordovaPlatforms.push(...['amiga', 'c64', 'famicon']);
ph.writeSync();
One problem is that this class was designed as the first step in a larger proposal that I never finished writing/formatting for review. I'll try my best to get that posted on cordova-discuss today. 😅
Maybe those getters should return readonly/frozen copies of the data, to prevent trying to assign into them. They were not intended to be used for writing. |
That's exactly what I was thinking. We would need a deepFreeze lib though. |
e4deacf
to
3caa777
Compare
I've updated this to return frozen data anywhere that it's not returning a simple type like a string. I've also added I've removed the calls to write, so consumers of this API will need to remember to call
The plan is to deprecate storing any of that information in config.xml and keep it all in package.json, which this class is intended to help with. Right now it's a giant mess of over-complicated code that tries to keep them in sync, and seems to pick which file overrules the other at random, which was done as a sort of transition period. We want to only look at package.json for dependencies going forward and keep config.xml reserved for application config stuff like preferences, icons, and splashscreens. |
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 very good to me. Left one little remark in the code.
Another thing I noticed, was that there are no methods for removing platforms and plugins. Do you plan adding some?
That being said, I think this would already be super useful as it is.
src/PackageHelper.js
Outdated
// Already have the plugin installed, but might need to merge vars | ||
let existing_vars = this.pkgfile.cordova.plugins[plugin]; | ||
|
||
this.pkgfile.cordova.plugins[plugin] = Object.assign({}, existing_vars, vars); |
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 would have expected this to replace the variables, not merge them. With the current implementation we cannot remove variables. Merging would still be doable, if a little verbose:
const oldVars = pkgHelper.getPluginVariables('cordova-plugin-foo')
pkgHelper.addPlugin('cordova-plugin-foo', Object.assign({}, oldVars, newVars))
I couldn't tell whether we have to merge often. If so, we should probably provide an option for that.
TODO: Address apache/cordova-lib#694 here to avoid writing if there are no changes |
Also possibly worth looking at: https://github.com/npm/read-package-json |
I hope the Todo and read-package-json ideas will be kept in a new issue to
avoid losing them after the merge.
…On Fri, Sep 21, 2018, 3:06 PM Darryl Pogue ***@***.***> wrote:
Also possibly worth looking at: https://github.com/npm/read-package-json
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#34 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABfNUDkzo3kEjDwvscmbOavC1rQQd3dNks5udTjSgaJpZM4VSRfM>
.
|
I'm hoping to update this before it's merged. This probably won't make the next major |
This uses the same modules for writing package.json that npm uses internally, which should resolve the issue where newlines and indents are changed after running cordova.
3caa777
to
5dd80db
Compare
I just marked this as [WIP] to avoid a premature merge. |
I'd personally prefer to keep a copy of the initial contents and use
get cordovaDependencies () {
const mergedDependencies = Object.assign({}, this.pkgfile.dependencies, this.pkgfile.devDependencies);
return deepFreeze(
this.cordovaPlatforms
.map(p => p.startsWith('cordova-') ? p : `cordova-${p}`)
.concat(this.cordovaPlugins)
.reduce((deps, cur) => {
deps[cur] = mergedDependencies[cur];
return deps;
}, {})
);
}
When test-driving this class on the new As this class has reached quite some size and still could do more (see block above) I stand by my remarks regarding interface segregation from above and would appreciate feedback on it:
Edit: Please note that this is just me trying to give feedback to make a good thing even better. No offense intended. |
@raphinesse Thanks for the re-review! I agree with almost all of those comments. Funny thing, when working on apache/cordova-lib#752 I was referencing back to this PR and actually wrote it to use this class's API before refactoring it to the expanded form. I definitely see the value in splitting this up into a PackageFileEditor and a CordovaPackageFileEditor subclass. 🙂 The only suggestion I'm not really a fan of is changing the format of the data stored in package.json, unless you were thinking just of providing a getter that returned an object with aggregated data?
|
Yes, my suggestion was to provide getters similar to cordova-common/src/ConfigParser/ConfigParser.js Lines 400 to 427 in f9951b3
cordova-common/src/ConfigParser/ConfigParser.js Lines 355 to 359 in f9951b3
|
Okay cool, that definitely sounds reasonable to do :) |
First of all sorry for my ignorace, as I haven't read this PR's commits and comments. I just want to say that IMHO package.json should be saved in same format as npm uses. Update Sorry, didn't notice that sentences in PR description: consistent with npm about how newlines and indentation are handled BTW it's handled via stringify-package package |
What is the status of this? |
No change in status. I've had no time to look at this any further.
Yep, I extracted that from npm CLI into its own module as part of putting this proposal together :) |
As is the default behavior of npm. When it's finished, we should use apache/cordova-common#34 here. Co-Authored-By: エリス <[email protected]>
"fs-extra": "^7.0.0", | ||
"glob": "^7.1.2", | ||
"minimatch": "^3.0.0", | ||
"plist": "^3.0.1", | ||
"q": "^1.4.1", | ||
"stringify-package": "^1.0.0", |
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 package is deprecated now, the replacement is https://www.npmjs.com/package/@npmcli/package-json
I think we can actually close this PR for |
Platforms affected
Tooling
What does this PR do?
Adds a class to manage finding and updating the
cordova
section of package.json, while also being consistent with npm about how newlines and indentation are handled.The idea is to use this class in refactoring some pieces of cordova-lib.
I also added JSDoc/TypeScript-style doc comments to the class, which will provide autocompletion and tooltip information for anyone using VS Code. This partially helps to more clearly define what is "public"/private API, and also provides the opportunity to do type checking as a future testing step.
What testing has been done on this change?
Unit tests written with 100% coverage.