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

[BD-46] feat: add paragon-cli #2460

Merged

Conversation

monteri
Copy link
Contributor

@monteri monteri commented Jul 20, 2023

Description

Add paragon CLI that will provide Paragon consumers with paragon <command>. Right now it allows to run paragon install-theme and specify a custom brand package to install with the --no-save option (e.g., @edx/brand-edx.org@latest) to install custom brands during MFE local development without changing package.json.

Deploy Preview

N/A

Merge Checklist

  • If your update includes visual changes, have they been reviewed by a designer? Send them a link to the Netlify deploy preview, if applicable.
  • Does your change adhere to the documented style conventions?
  • Do any prop types have missing descriptions in the Props API tables in the documentation site (check deploy preview)?
  • Were your changes tested using all available themes (see theme switcher in the header of the deploy preview, under the "Settings" icon)?
  • Were your changes tested in the example app?
  • Is there adequate test coverage for your changes?
  • Consider whether this change needs to reviewed/QA'ed for accessibility (a11y). If so, please add wittjeff and adamstankiewicz as reviewers on this PR.

Post-merge Checklist

  • Verify your changes were released to NPM at the expected version.
  • If you'd like, share your contribution in #show-and-tell.
  • 🎉 🙌 Celebrate! Thanks for your contribution.

@openedx-webhooks openedx-webhooks added the blended PR is managed through 2U's blended developmnt program label Jul 20, 2023
@openedx-webhooks
Copy link

openedx-webhooks commented Jul 20, 2023

Thanks for the pull request, @monteri!

When this pull request is ready, tag your edX technical lead.

@netlify
Copy link

netlify bot commented Jul 20, 2023

Deploy Preview for paragon-openedx ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 838e9e6
🔍 Latest deploy log https://app.netlify.com/sites/paragon-openedx/deploys/64df42d877ee5300086d9cad
😎 Deploy Preview https://deploy-preview-2460--paragon-openedx.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

paragon-cli.js Outdated

const themes = [
{ name: '@edx/brand-openedx', value: '' },
{ name: '@edx/brand-edx.org', value: 'npm:@edx/brand-edx.org@latest' },
Copy link
Member

Choose a reason for hiding this comment

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

[suggestion] I believe we may want to avoid hardcoding @brand-edx.org in this specific case. Take consumers other than edX.org in the community that have their own @edx/brand packages. The CLI tool should be able to handle any @edx/brand package provided by the consumer, at the version they specify.

Copy link
Member

Choose a reason for hiding this comment

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

Q: "What @edx/brand package do you want to install?"

A: @edx/brand-edx.org@latest

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to this variant. Also I think it will useful to have commands in own js files. So I updated CLI to use Object instead of switch case

paragon-cli.js Outdated
@@ -0,0 +1,57 @@
#!/usr/bin/env node

const inquirer = require('inquirer');
Copy link
Member

Choose a reason for hiding this comment

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

Oooh neat, I was looking at inquirer awhile back. Seems pretty cool, and more powerful than the commander package we've previously been using to build CLI tools.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😄

Copy link
Member

@adamstankiewicz adamstankiewicz left a comment

Choose a reason for hiding this comment

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

This looks like a great start to the foundations of a single Paragon CLI tool that supports multiple commands/features! 😄

A few additional feedback items / thoughts:

  • In the example app, I noticed that @edx/brand-openedx is installed / imported from directly rather than the expected @edx/brand alias. I believe we'll want to install @edx/brand-openedx in the example MFE as follows: "@edx/brand": "npm:@edx/brand-openedx@^1.1.0"
  • Similarly, the example/src/index.scss file will need to be updated to import from the @edx/brand alias.
  • Add a "start:with-theme" NPM script in the example MFE's package.json file in order to use the command as if you were an engineer in a consuming MFE, something like:
{
  "scripts": {
    "install-brand": "../bin/paragon-scripts.js theme",
    "start:with-brand": "npm run install-theme && npm start"
  }
}

Usage in example MFE

npm run start:with-theme

package.json Outdated
@@ -8,6 +8,9 @@
"publishConfig": {
"access": "public"
},
"bin": {
"paragon": "paragon-cli.js"
Copy link
Member

Choose a reason for hiding this comment

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

[suggestion] Might be good to match the folder structure of @edx/frontend-build regarding its fedx-scripts, i.e. let's move paragon-cli.js under a bin directory (and maybe even rename to paragon-scripts?) such that this line becomes something more like:

{
  "bin": {
    "paragon": "./bin/paragon-scripts.js"
  }
}

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, I agree, updated name and location

paragon-cli.js Outdated
const [command, ...args] = process.argv.slice(2);

switch (command) {
case 'theme':
Copy link
Member

Choose a reason for hiding this comment

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

[suggestion] Perhaps install-theme to be a bit more explicit/descriptive in the command name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, changed

paragon-cli.js Outdated
}

function installTheme(theme) {
const installCommand = `npm install "@edx/brand@${theme}" --no-save`;
Copy link
Member

@adamstankiewicz adamstankiewicz Jul 23, 2023

Choose a reason for hiding this comment

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

[suggestion] This can totally be deferred, but an idea: make the --no-save option configurable/overrideable such that the command can be run where this npm install does save. The default should be --no-save, though.

I'm thinking of a possible use case where the Paragon CLI could be used in infrastructure/deployment code to install the @edx/brand aliases rather than the infrastructure/deployment code needing to do the npm install themselves (might be easier to simply run paragon install-theme during the build+deploy process 🤷‍♂️). Ah, but in this case, the user input wouldn't be possible.

Let's defer on this comment for now but come back to it at some point. I think to support the infrastructure/deployment code use case, we'd need a variant of the paragon install-theme CLI command that allowed its user to pass --brand (or similar) as an argument to avoid needing to provide user input.

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, I think it is good idea, maybe flag -d, --deploy or something will solve the problem and will make it clear for the user. Also I created issue for your three comments that won't be part of this PR. #2483

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for creating the issue!

paragon-cli.js Outdated
break;

default:
console.log('Unknown command. Usage: paragon <command>');
Copy link
Member

@adamstankiewicz adamstankiewicz Jul 23, 2023

Choose a reason for hiding this comment

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

[suggestion] Take a look at the chalk JS library: https://github.com/chalk/chalk

I've started to introduce it into @edx/frontend-build's fedx-scripts CLI tool and think it's a worthwhile pattern to bring here. Basically, chalk allows you to draw more attention to console.log statements such as this by formatting it.

In this case, given it's an error, perhaps its formatted with red and bold, for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added usage of chalk. For both errors I added red and bold color.

paragon-cli.js Outdated
break;

default:
console.log('Unknown command. Usage: paragon <command>');
Copy link
Member

Choose a reason for hiding this comment

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

[curious/suggestion] Is there a way to list out all possible CLI commands as a hint for users on what commands are available to use? In a similar vein, is there or should there be a paragon help type of functionality? This, too, could likely be deferred as a separate feature addition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also put this comment as part of the issue #2483

paragon-cli.js Outdated
(async () => {
const [command, ...args] = process.argv.slice(2);

switch (command) {
Copy link
Member

@adamstankiewicz adamstankiewicz Jul 23, 2023

Choose a reason for hiding this comment

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

[suggestion] To have better observability in how consumers make use of these commands, I might recommend we try dispatching a Segment event describing which command is used and how, similar to how we have sendTrackInfo in the component generator tool.

Speaking of the component generator, we may also want to backlog an issue to migrate its current implementation into this new Paragon CLI as a distinct command (not in scope for this PR).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I put this comment as part of the issue #2483

@monteri monteri marked this pull request as ready for review July 27, 2023 13:34
@monteri
Copy link
Contributor Author

monteri commented Jul 27, 2023

{
  "scripts": {
    "install-brand": "../bin/paragon-scripts.js theme",
    "start:with-brand": "npm run install-theme && npm start"
  }
}

We are able to use paragon command inside example so I added both example's start:with-theme command and example:start:with-theme command in the root.

@monteri monteri mentioned this pull request Jul 27, 2023
@adamstankiewicz
Copy link
Member

@monteri [inform] Looks like there's some linting errors.

For the one's related to "should be listed in the project's dependencies, not devDependencies", we may want to ignore this class of errors in the bin directory?

@monteri
Copy link
Contributor Author

monteri commented Aug 1, 2023

Thank you, I fixed linting errors.

@codecov
Copy link

codecov bot commented Aug 1, 2023

Codecov Report

Patch coverage has no change and project coverage change: +0.26% 🎉

Comparison is base (d55001f) 91.38% compared to head (838e9e6) 91.65%.
Report is 53 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2460      +/-   ##
==========================================
+ Coverage   91.38%   91.65%   +0.26%     
==========================================
  Files         234      236       +2     
  Lines        4157     4195      +38     
  Branches     1001     1012      +11     
==========================================
+ Hits         3799     3845      +46     
+ Misses        351      346       -5     
+ Partials        7        4       -3     

see 9 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@adamstankiewicz adamstankiewicz left a comment

Choose a reason for hiding this comment

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

Looks good! Added a minor question, and a comment about the example NPM script not seeming to work without a modification. Once those items are clarified/resolved, ✅

const COMMANDS = {
'install-theme': themeCommand,
// eslint-disable-next-line no-console
test: () => console.log('Executing "paragon test" function...'),
Copy link
Member

Choose a reason for hiding this comment

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

[curious] Do we intend to keep this as part of the CLI?

@@ -10,12 +10,13 @@
"precommit": "npm run lint",
"snapshot": "fedx-scripts jest --updateSnapshot",
"start": "fedx-scripts webpack-dev-server --progress",
"start:with-theme": "paragon install-theme && npm start",
Copy link
Member

Choose a reason for hiding this comment

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

When running this, I get the following error:

❯ npm run start:with-theme

> example@1.0.0 start:with-theme
> paragon install-theme && npm start

sh: paragon: command not found
npm ERR! Lifecycle script `start:with-theme` failed with error: 
npm ERR! Error: command failed 
npm ERR!   in workspace: example@1.0.0 
npm ERR!   at location: /Users/astankiewicz/Desktop/edx/paragon/example 

I believe we could resolve this error by changing the line to:

../bin/paragon-scripts.js install-theme && npm start

@adamstankiewicz adamstankiewicz linked an issue Aug 11, 2023 that may be closed by this pull request
package.json Outdated
Comment on lines 115 to 116
"chalk": "^4.1.2",
"child_process": "^1.0.2",
Copy link
Member

Choose a reason for hiding this comment

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

[curious] I have a hunch these dependencies will need to be installed of regular dependencies, including inquirer below.

If installed as devDependencies, their code won't be included in the installed bundle in the consuming application, which could lead to not being able to run the Paragon CLI correctly. It's not a concern within the example app in the Paragon repo itself, because these packages are installed into the root node_modules via the devDependencies. However, for MFEs outside of the Paragon repo, this could be a concern.

I wonder if it's worth a sanity check of trying to run the Paragon CLI outside of the example MFE app, too? Perhaps installing this branch of Paragon into frontend-template-application would be a good test (I think the bin script should work?).

npm install "https://github.com/openedx/paragon.git#raccoongang:zadorozhnii/paragon-cli-for-theming" --save

Note this also related to the // eslint-disable-next-line import/no-extraneous-dependencies comments.

type: 'input',
name: 'theme',
message: 'What @edx/brand package do you want to install?',
default: '',
Copy link
Member

Choose a reason for hiding this comment

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

nit: Should this default @edx/brand-openedx@latest? Or a required field? Worth a sanity check.

@adamstankiewicz adamstankiewicz merged commit 33a7c74 into openedx:master Aug 18, 2023
9 checks passed
@openedx-webhooks
Copy link

@monteri 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future.

@edx-semantic-release
Copy link
Contributor

🎉 This PR is included in version 21.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

viktorrusakov pushed a commit that referenced this pull request Aug 23, 2023
Exposes a `paragon` CLI with an `install-theme` command.

Example usage in `package.json`:

```
{
  "scripts": {
    "start:with-theme": "paragon install-theme && npm start",
    "build:with-theme": "paragon install-theme && npm run build"
  }
}
```

The Paragon CLI will prompt from which NPM package you wish to install as the `@edx/brand` package (e.g., `@edx/brand-edx.org@latest`), and install it without modifying the `package.json` or `package-lock.json` files.

Additional commands will be added to the `paragon` CLI tool in the future.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blended PR is managed through 2U's blended developmnt program released
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Discovery: Paragon CLI/Migrator
5 participants