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

Make sure a custom blueprint will be used if it's not the default blueprint #1084

Merged
merged 48 commits into from
Mar 11, 2021

Conversation

gitstevenpham
Copy link
Contributor

@gitstevenpham gitstevenpham commented Dec 16, 2020

Bug

I wanted to update the state of my project with changes to a blueprint from an Ember addon package that is not the default:

{
  "schemaVersion": "1.0.0",
  "packages": [
    {
      "name": "ember-cli",
      "version": "3.23.0",
      "blueprints": [
        {
          "name": "addon",
          "outputRepo": "https://github.com/ember-cli/ember-addon-output",
          "codemodsSource": "ember-addon-codemods-manifest@1",
          "isBaseBlueprint": true,
          "options": [
            "--welcome",
            "--yarn"
          ]
        }
      ]
    },
    {
      "name": "@stpham/generic-addon",
      "version": "0.0.2",
      "blueprints": [
        {
          "name": "@stpham/bootstrapping-project"
        }
      ]
    }
  ]
}

When I run ember-cli-update and choose @stpham/bootstrapping-project, the @stpham/generic-addon version is bumped but the actual blueprint changes aren't there. i.e. file additions.

Root Cause

It seems like the code assumes the default blueprint would be the only blueprint that would be used

async function emberInstallAddon({
  cwd,
  addonNameOverride,
  packageName,
  version,
  blueprintPath,
  stdin
}) {
  let addon;

  if (addonNameOverride) {
    addon = addonNameOverride;
    if (version && !blueprintPath) {
      addon += `@${version}`;
    }
  }

  if (!addon) {
    addon = blueprintPath;
  }

  if (!addon) {
    addon = `${packageName}@${version}`;
  }

  let install = ember(['i', addon], { cwd, stdin });

  let generate;

  if (!blueprintPath) {
    generate = install;
  } else {
    let emberCliVersion = await getEmberCliVersion({ cwd });

    let isBuggyEmberCliVersion = semver.satisfies(emberCliVersion, buggyEmberCliRange);

    if (!isBuggyEmberCliVersion) {
      generate = install;
    } else {
      await install;

      generate = ember(['g', packageName], { cwd, stdin });
    }
  }

  return {
    ps: generate
  };
}

The generate = ember(['g', packageName], { cwd, stdin }); line will only be hit if the ember-cli version is deemed to be a buggy one else it only uses ember install <package>.

Changes

End User Experience

After these changes are pushed, the end-user will be required to provide a blueprint name with the install command if they want to use another blueprint that doesn't match the addon name. ember-cli-update install <package_name> will assume there exists a blueprint with the same name as <package_name>. ember-cli-update install <package_name> -b <some_other_blueprint> to install package and ember g <some_other_blueprint>.

We should release version 1.0.0 to indicate the above requirement exists for custom blueprints. Judging that this problem has existed for a while, I don't think many folks use ember-cli-update for custom blueprints

Code Changes

I opted to move away from using ember install <package_name> to install packages since it will automatically try to generate the default blueprint. Since there will always be a blueprint name in the ember-cli-update.json tied to a package (I assume), I figured the code can be more explicit in what it is doing. I refactored and renamed ember-install-addon.js to install-and-generate-blueprint.js and made it always install a package and generate the specified blueprint.

@gitstevenpham gitstevenpham changed the title Fix blueprint install Make sure a custom blueprint will be used if it's not the default blueprint Dec 17, 2020
package.json Outdated Show resolved Hide resolved
src/get-start-and-end-commands.js Outdated Show resolved Hide resolved
src/install-and-generate-blueprint.js Outdated Show resolved Hide resolved
@gitstevenpham gitstevenpham force-pushed the fix-blueprint-install branch 2 times, most recently from 59223b8 to 4d3d7b5 Compare December 22, 2020 07:42
@gitstevenpham gitstevenpham marked this pull request as ready for review December 22, 2020 07:54
README.md Outdated Show resolved Hide resolved
@rwjblue
Copy link
Member

rwjblue commented Jan 4, 2021

@spham92 - Looks like we have a conflict over in:

src/get-start-and-end-commands.js

@rwjblue
Copy link
Member

rwjblue commented Jan 5, 2021

FWIW, the last failing job is due to the issue I created #1085 to track (fork PRs can never pass CI at the moment).

@gitstevenpham
Copy link
Contributor Author

@kellyselden can you take a look at the PR when you get a chance?

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Co-authored-by: Jordan Hawker <[email protected]>
@gitstevenpham
Copy link
Contributor Author

ping @kellyselden

@gitstevenpham
Copy link
Contributor Author

ping @kellyselden


let generate;

if (!blueprintPath) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't see this logic block in the new version. Is that going to be a problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me know if I missed a use case.

I moved the responsibility of choosing which blueprint to use up to the parent function that calls installAndGenerateBlueprint.

install command will default to the addon name if a blueprint param is not passed by the user.

line 45-53 of src/install.js

  let { ps } = await installAndGenerateBlueprint({
    cwd,
    addonNameOverride: addon,
    packageName,
    blueprintPath: path
    blueprintName: _blueprintName || addon,
    blueprintPath: path,
    packageManager: isYarnProject ? 'yarn' : 'npm'
  });

installAddonBlueprint also will pass a blueprintName param

line 275-284 of src/get-start-and-end-command.js

let { ps } = await installAndGenerateBlueprint({
    cwd: projectRoot,
    packageName: blueprint.packageName,
    version: blueprint.version,
    blueprintPath: blueprint.path,
    stdin: 'pipe'
    blueprintName: blueprint.name,
    blueprintOptions: blueprint.options || [],
    stdin: 'pipe',
    packageManager
  });

test/acceptance/ember-cli-update-test.js Outdated Show resolved Hide resolved
test/integration/install-test.js Outdated Show resolved Hide resolved
src/get-project-options.js Outdated Show resolved Hide resolved
module.exports = installAndGenerateBlueprint;
module.exports.ember = ember;
module.exports.resolvePackageName = resolvePackageName;
module.exports.spawn = spawn;
Copy link
Member

Choose a reason for hiding this comment

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

if you don't mind double checking all of these that can be removed now that the test isn't stubbing anymore.

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 still need these for the actual unit test of this module

src/resolve-package.js Outdated Show resolved Hide resolved
@kellyselden
Copy link
Member

Looking good. I have a few more suggestions. I checked out the code and stepped through the tests, so I have a better understanding of the functionality now :)

@gitstevenpham
Copy link
Contributor Author

@kellyselden current state of code addresses the PR comments

"version": "0.0.1",
"blueprints": [
{
"name": "custom-blueprint"
Copy link
Member

Choose a reason for hiding this comment

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

After the initial install, will someone be able to update this blueprint?

Copy link
Member

Choose a reason for hiding this comment

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

or is it correct that after the initial resolution of the blueprint name from install, we no longer have to worry about it being a name mismatch (and we never have to look it up again)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The latter is correct. Once the blueprint name is set in ember-cli-update.json it will be the one generated when user wants to update the package version the blueprint belongs to.

src/install.js Outdated Show resolved Hide resolved
@gitstevenpham
Copy link
Contributor Author

Friendly reminder @kellyselden

@@ -45,4 +45,9 @@ describe(getBlueprintNameOverride, function() {
let defaultBlueprintOverride = await getBlueprintNameOverride(localPackageFixture);
expect(defaultBlueprintOverride).to.be.equal('custom-blueprint');
});

it('NPM package with nondefault returns expected value', async function() {
Copy link
Member

Choose a reason for hiding this comment

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

nitpick but this test should be moved to a new file test/integration/get-default-blueprint-name-override-test.js

Copy link
Member

Choose a reason for hiding this comment

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

as well as the above one which is testing the disk blueprints

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

@kellyselden kellyselden merged commit 17f200d into ember-cli:master Mar 11, 2021
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.

5 participants