Skip to content
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

feat(telemetry) adding yarn 1 support, sanitizing data pre-flight #3082

Merged
merged 11 commits into from
Oct 5, 2021

Conversation

splitinfinities
Copy link
Contributor

Pull request checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)
  • Build (npm run build) was run locally and any changes were pushed
  • Unit tests (npm test) were run locally and passed
  • E2E Tests (npm run test.karma.prod) were run locally and passed
  • Prettier (npm run prettier) was run locally and passed

Pull request type

Please check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

What is the current behavior?

We're unable to understand how Yarn users work with Stencil today.
GitHub Issue Number: N/A

What is the new behavior?

  • This PR allows the yarn.lock file to be read.
  • Sanitizes two data points pre-flight - the system version (Node/Deno) and the packages array.

Does this introduce a breaking change?

  • Yes
  • No

Testing

Other information

@splitinfinities splitinfinities requested a review from a team September 27, 2021 16:37
@splitinfinities splitinfinities changed the title telemetry(yarn) adding yarn support, sanitizing data pre-flight feat(telemetry) adding yarn support, sanitizing data pre-flight Sep 27, 2021
@splitinfinities splitinfinities self-assigned this Sep 27, 2021
Copy link
Contributor

@rwaskiewicz rwaskiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a first pass on this, but didn't get around to testing it going much deeper than the surface level. LMK what you think

src/cli/telemetry/telemetry.ts Outdated Show resolved Hide resolved
packages = await npmPackages(sys, ionicPackages);
} else if (isUsingYarn(sys)) {
packages = await yarnPackages(sys, ionicPackages);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't isUsingYarn always return a boolean? I'm not sure I see the scenario where this else block is entered (since we test both isUsingYarn in the else if condition and it's negation in the if condition clause)

In fact, I think this could be refactored as such

// NOTE to not be committed: I pulled this out to keep our `try` block tiny
const isUsingYarn = isUsingYarn(sys);
try {
  packages = isUsingYarn ? await yarnPackages(sys, ionicPackages) : await npmPackages(sys, ionicPackages);
} catch (e) {
   packages = ionicPackages.map(([k, v]) => `${k}@${v.replace('^', '')}`);
}

@@ -79,6 +79,8 @@
"@types/sizzle": "^2.3.2",
"@types/webpack": "^4.41.26",
"@types/ws": "^7.4.0",
"@types/yarnpkg__lockfile": "^1.1.5",
"@yarnpkg/lockfile": "^1.1.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add @yarnpkg/lockfile to

'@rollup/plugin-node-resolve',

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a dev dependency, how is this getting rolled up and put in the final compiler output?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a part of the compiler process, since anything within the node sys gets bundled up and shipped. Similar to how we bundle TypeScript or Rollup.

*/
async function yarnPackages(sys: d.CompilerSystem, ionicPackages: [string, string][]) {
const appRootDir = sys.getCurrentDirectory();
const yarnLock = sys.readFileSync(appRootDir + '/yarn.lock');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use path.join (or the sys equivalent) here, to make the path delimiter OS-agonstic

*/
async function npmPackages(sys: d.CompilerSystem, ionicPackages: [string, string][]) {
const appRootDir = sys.getCurrentDirectory();
const packageLockJson: any = await tryFn(readJson, sys, sys.resolvePath(appRootDir + '/package-lock.json'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use path.join (or the sys equivalent) here, to make the path delimiter OS-agonstic

src/cli/telemetry/telemetry.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@rwaskiewicz rwaskiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested on Windows + MacOS, looking good 😎

Left a few comments/nitpicks around typings, but nothing major

@@ -79,6 +79,8 @@
"@types/sizzle": "^2.3.2",
"@types/webpack": "^4.41.26",
"@types/ws": "^7.4.0",
"@types/yarnpkg__lockfile": "^1.1.5",
"@yarnpkg/lockfile": "^1.1.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a dev dependency, how is this getting rolled up and put in the final compiler output?

)
: ionicPackages.map(([k, v]) => `${k}@${v}`);
try {
packages = yarn ? await yarnPackages(sys, ionicPackages) : await npmPackages(sys, ionicPackages);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my own knowledge, in what cases do we expect either of these await calls to throw?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the lock files cannot be read (doesn't exist/incorrect file structure), that's when these should throw.

async function getInstalledPackages(
sys: d.CompilerSystem,
config: d.Config
): Promise<{ packages: string[]; packages_no_versions: string[] }> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we camelCase pacakges_no_versions please? I think we'd want to be using camelCase until it's time to send the snake_case value off to the aggregation service

* @returns a cleaned up representation without any qualifiers
*/
function sanitizeDeclaredVersion(version: string) {
return version.replace(/[*^~]/g, '');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is doing a global replace, which is probably fine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intent

async function yarnPackages(sys: d.CompilerSystem, ionicPackages: [string, string][]) {
const appRootDir = sys.getCurrentDirectory();
const yarnLock = sys.readFileSync(sys.resolvePath(appRootDir + '/yarn.lock'));
const packageLockJson = sys.parseYarnLockFile(yarnLock);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rename this to yarnLockYml or something similar?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you walk me through the success/failure cases of this being read? Will packageLockJson (as its named today) always be a truthy value, even when the reading fails?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If reading fails, it throws and resolves back to the parent try/catch block. All other paths are truthy as you say.


return ionicPackages.map(([k, v]) => {
const identifiedVersion = `${k}@${v}`;
let version = packageLockJson.object[identifiedVersion]?.version;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since object is of type any, can we handle the case where it is undefined/null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would handle that above, within the getInstalledPackages try/catch block.

src/cli/telemetry/telemetry.ts Outdated Show resolved Hide resolved
src/cli/telemetry/telemetry.ts Outdated Show resolved Hide resolved
src/cli/telemetry/telemetry.ts Outdated Show resolved Hide resolved
@splitinfinities splitinfinities changed the title feat(telemetry) adding yarn support, sanitizing data pre-flight feat(telemetry) adding yarn 1 support, sanitizing data pre-flight Oct 5, 2021
@splitinfinities
Copy link
Contributor Author

Note that yarn 2+ are not supported

@rwaskiewicz rwaskiewicz merged commit 07f69cb into master Oct 5, 2021
@rwaskiewicz rwaskiewicz deleted the add-yarn-and-expand-data branch October 5, 2021 17:01
rwaskiewicz added a commit that referenced this pull request Oct 8, 2021
this pr moves yarn dependencies from the `dependencies` section of our
package-lock.json to `dev-dependencies`. In
#3082, we didn't use the npm
cli to move these from dependencies->dev-dependencies during iteration
of the feature. this PR puts them in the correct place.
rwaskiewicz added a commit that referenced this pull request Oct 8, 2021
this pr moves yarn dependencies from the `dependencies` section of our
package-lock.json to `dev-dependencies`. In
#3082, we didn't use the npm
cli to move these from dependencies->dev-dependencies during iteration
of the feature. this PR puts them in the correct place.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants