-
Notifications
You must be signed in to change notification settings - Fork 122
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
[OC-28] Cli init allows for --templateType to be npm module #480
Conversation
I'm not sure what's happening with appveyor. When I click details, it goes to a different PR |
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.
First round of reviews. There are many minor things but the overall structure seems ok and I think tests cover the
various scenarios quite well 👍
const logger = config.logger; | ||
|
||
try { | ||
const bluprinting = new Spinner(`Blueprinting component...`); |
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.
Can we move this to the shared strings?
|
||
fs.writeJsonSync(componentPath + '/package.json', packageContent); | ||
bluprinting.stop(); | ||
logger.log(`${colors.green('✔')} Files created at ${componentPath}`); |
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.
same for this one
logger.log(`${colors.green('✔')} Files created at ${componentPath}`); | ||
return callback(null, { ok: true }); | ||
} catch (error) { | ||
return callback(`Blueprinting failed. Please open an issue on ${templatePackage.bugs.url} with the following information: ${error}`); |
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.
and this one
creating.start(); | ||
fs.ensureDirSync(componentPath); | ||
creating.stop(true); | ||
logger.log(`${colors.green('✔')} Created directory "${componentName}"`); |
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.
same
createComponentDir(config); | ||
|
||
try { | ||
// If template available in the dev registry, generate boilerplate out of its blueprint |
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.
Whatever this comment is trying to tell me, I don't understand it :D Can you be more clear about what this is doing?
src/cli/domain/local.js
Outdated
const pathDir = '../../components/base-component-' + templateType, | ||
baseComponentDir = path.resolve(__dirname, pathDir), | ||
npmIgnorePath = path.resolve(__dirname, pathDir + '/.npmignore'); | ||
// LEGACY TEMPLATES |
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.
Can we move this to own file like init-legacy-templates.js
so that we can make this comment redundant?
src/cli/facade/init.js
Outdated
@@ -19,7 +19,7 @@ module.exports = function(dependencies){ | |||
|
|||
callback = wrapCliCallback(callback); | |||
|
|||
local.init(componentName, templateType, (err) => { | |||
local.init(componentName, templateType, { logger: logger }, err => { |
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.
{ logger } ?
}); | ||
it('should correctly invoke ensureDirSync', () => { | ||
expect(deps['fs-extra'].ensureDirSync.calledWith( | ||
config.componentPath |
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.
personal preference, I like repetition on tests to improve readability. I prefer to read that's called with path/to/component
over the config, so that if I scroll a lot in the bottom, each tests still tells me what this is doing by looking at it instead of scrolling back up?
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.
im fine either way
} | ||
}; | ||
|
||
const initPackage = injectr('../../src/cli/domain/init-template/initPackage.js', deps, {}); |
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 is a minor one, but I think we usually follow conventions of init-package
for filenames. Are you able to bring all the new files in this PR back to follow the same convention?
it('should return the unaltered package name if alrady given', () => { | ||
expect(getPackageName('oc-template-jade')).to.equal('oc-template-jade'); | ||
expect(getPackageName('are-we-there-yet-1.1.2.tgz')).to.equal('are-we-there-yet'); | ||
expect(getPackageName('oc-template-jade@next')).to.equal('oc-template-jade'); |
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.
well done on testing all of these scenarios
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.
😎
38ea952
to
f8101a5
Compare
@matteofigus I've change pr base so that now this will merge to master (as the |
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 is a second round of review. There may be more to come but I think this is good to start
src/resources/index.js
Outdated
installCompiler: (compiler, fromLocal) => | ||
`Installing ${compiler} from ${fromLocal ? 'local' : 'npm'}...`, | ||
installCompilerSuccess: (template, compiler, version) => | ||
`${colors.green('✔')} Installed ${compiler} [${template.replace( |
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 template.replace is not something I would put here. I prefer this to have simple text replacements and this to be done to however calls this (template should already be without -compiler
)
@@ -0,0 +1,20 @@ | |||
module.exports = (logger, componentName, componentPath) => { |
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.
can we use a multiline template literal and actually move this to the resources
file?
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.
Cause multiline is space sensitive, it will look a bit ugly on that file. I've commited it so that you can see. I think is ok for now as we need to rethink that part anyway.
const { | ||
componentName, | ||
templateType, | ||
logger = console, |
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.
logger will be sent by the facade, so we don't need to fallback to console
logger = console, | ||
cli = 'npm' | ||
} = options; | ||
const componentPath = path.join(process.cwd(), componentName); |
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.
can we generate componentPath in the facade, and pass it through each call? so that process-cwd()
is not repeated in multiple places.
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.
It actually happen in one place. The other calls to process-cwd()
are for different matters (local compiler, resolve for path being passed for template). But agree on hoisting it up in the facade. 👍
|
||
module.exports = function(options) { | ||
const { cli, componentPath } = options; | ||
spawn.sync(cli, ['init', '--yes'], { cwd: componentPath }); |
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's the point on abstracting cli
into a separate variable if we support only npm? I would rather explicitly have npm
here and abstract only if we add support to yarn or other tools in the future.
|
||
fs.copySync(baseComponentFiles, componentPath); | ||
|
||
const componentPackage = require(componentPath + '/package.json'); |
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 use readJsonSync as you are requiring something and then overriding its own cache by changing the file immediately after...
}); | ||
|
||
scaffold.stop(); | ||
// logger.log(strings.messages.cli.scaffoldSuccess(componentPath)); |
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 is this comment?
src/cli/domain/local.js
Outdated
fs.outputJsonSync(componentPath, component, { spaces: 2 }); | ||
|
||
return callback(null, { ok: true }); | ||
initTemplate({ componentName, templateType, logger }, callback); |
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.
initTemplate looks asynchronous to me. So this try/catch should be converted to an async callback check
src/resources/index.js
Outdated
@@ -135,9 +138,24 @@ module.exports = { | |||
}, | |||
messages: { | |||
cli: { | |||
installCompiler: (compiler, fromLocal) => |
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.
can we keep those alphabetic. Perhaps first all lower case (new format) then all upper case (old format to be converted to new)
src/resources/index.js
Outdated
`${colors.green('✔')} Files created at ${componentPath}`, | ||
creatingDir: () => `Creating directory...`, | ||
createdDir: dirName => | ||
`${colors.green('✔')} Created directory "${dirName}"`, |
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 am not sure I like the ${colors.green('✔')}
been here. The responsibility of this file should not be to have colors. I would rather create a new method in the logger, like logger.okV('message')
which does this for you?
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'll suggest we do this afterward as we rethink/rearchitect the facade part
@matteofigus Thanks for the great review/comments.
|
8fb76ee
to
490fadb
Compare
shrinkwrap ora replacement blueprint and error handling shwrinkrap test wip dependency injection for logger fixed init.js tests init-template cleanup
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.
couple of little things. Also, can you qa doing oc init hello jade|handlebars to test if all works without breaking changes compared to the past? (testing that then both dev and publish work as expected)? Thanks
describe('when invoked', () => { | ||
const options = { | ||
componentPath: 'path/to/component', | ||
cli: 'npm' |
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 we can remove this line
describe('when invoked', () => { | ||
const config = { | ||
templateType: 'oc-template-jade', | ||
cli: 'npm', |
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.
here too
templateType: 'oc-template-jade', | ||
cli: 'npm', | ||
componentPath: 'path/to/component', | ||
local: false, |
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.
same
componentName, | ||
logger, | ||
componentPath, | ||
compiler |
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.
alphabetic
templateType, | ||
compiler, | ||
componentPath, | ||
logger |
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.
alphabetic
componentPath, | ||
compiler, | ||
compilerPath, | ||
logger |
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.
alphabetic
src/cli/facade/init.js
Outdated
templateType, | ||
logger, | ||
componentPath, | ||
compiler: `${templateType}-compiler` |
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.
alphabetic
@matteofigus addressed the reviewed points. Some context for you when you'll review it again:
I've QA the following scenarios (both with the compiler already installed on the dev registry or not):
All seems good now |
LGTM. Let's merge and release tomorrow first thing 👍 |
If the templatetype passed to the init comand is not 'jade' or 'handlebars' (default) but a valid oc-template module, the cli will download it and use it to generate boilerplate.
Example of boilerplate code used by the cli to generate a component
A couple of extra notes:
For the moment templates defines "compileDependencies" in their package.json. Those are required and will be installed in order to compile template-specific components and therefore templates to work rely on being initialized through the
oc init
command. The rationale was to avoid having to install all such dependencies on the registry or in places where are not needed at all. Down-size is that for a component creator point of view the api is not too ergonomic as it won't be possible to simply create a component with the right template type and dependencies to work without runningoc init
or manually installingcompileDependencies
. To address this in the near future we might split templates in two modules, aclient
modules and acompile
module.