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
Support template-path
and name
CLI options for interactive CLI
#9471
Support template-path
and name
CLI options for interactive CLI
#9471
Conversation
5c25c7a
to
2b7ba82
Compare
lib/cli/interactive-setup/service.js
Outdated
if (options['template-path']) { | ||
projectName = await resolveProjectNameInput(options, workingDir); | ||
projectDir = join(workingDir, projectName); | ||
createFromLocalTemplate({ |
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've went with the approach of throwing errors in cases where the invalid options were supplied (name
and template-path
), but I'm not 100% sure about this approach of presenting errors to users
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.
IMO good call, I think we should validate CLI options with real thrown errors, as those are forced settings (we're not re-asking user to pass fixed CLI option), and via CLI options we also want to support non interactive usage, and in such scenario it's very important that processes exit with non zero code.
Codecov Report
@@ Coverage Diff @@
## master #9471 +/- ##
==========================================
+ Coverage 86.77% 86.80% +0.03%
==========================================
Files 327 328 +1
Lines 11985 12022 +37
==========================================
+ Hits 10400 10436 +36
- Misses 1585 1586 +1
Continue to review full report at Codecov.
|
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.
@pgrzesik looks great ! I have just few minor suggestions, and we should be good to go
lib/cli/interactive-setup/service.js
Outdated
module.exports = { | ||
isApplicable({ serviceDir }) { | ||
return !serviceDir; | ||
}, | ||
async run(context) { | ||
const workingDir = context.cwd || process.cwd(); | ||
const options = context.options || {}; |
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.
Options are assumed to be provided unconditionally here
const sourcePath = untildify(templatePath); | ||
|
||
try { | ||
copyDirContentsSync(sourcePath, projectDir, { noLinks: true }); |
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.
Let's use fse.copy
instead (we also consider *Sync
functions as deprecated, and they're scheduled to be replaced, and such utils removed -> #8604)
'INVALID_TEMPLATE_PATH' | ||
); | ||
} | ||
throw 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.
I this case I'd also throw ServerlessError
, with message as Cannot copy template path: ${error.message}
lib/cli/interactive-setup/service.js
Outdated
module.exports = { | ||
isApplicable({ serviceDir }) { | ||
return !serviceDir; | ||
}, | ||
async run(context) { | ||
const workingDir = context.cwd || process.cwd(); | ||
const options = context.options || {}; | ||
const isConfirmed = await confirm('No project detected. Do you want to create a new one?', { |
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 question should be skipped if any of those option is passed (it's a clear indication, that intention is to create a new project)
lib/cli/interactive-setup/service.js
Outdated
if (options['template-path']) { | ||
projectName = await resolveProjectNameInput(options, workingDir); | ||
projectDir = join(workingDir, projectName); | ||
createFromLocalTemplate({ |
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.
IMO good call, I think we should validate CLI options with real thrown errors, as those are forced settings (we're not re-asking user to pass fixed CLI option), and via CLI options we also want to support non interactive usage, and in such scenario it's very important that processes exit with non zero code.
|
||
return projectNameInput(workingDir); | ||
}; | ||
|
||
module.exports = { | ||
isApplicable({ serviceDir }) { | ||
return !serviceDir; |
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 should also throw here errors, if given options were passed but user is in service context (we should not silently ignore them)
Thanks for review @medikoo - thanks for raising the point about |
8d386a8
to
af0007e
Compare
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 great 👍 I've just suggested changes to error messaging, let me know what you think
lib/cli/interactive-setup/service.js
Outdated
isApplicable({ options, serviceDir }) { | ||
if (serviceDir && (options.name || options['template-path'])) { | ||
throw new ServerlessError( | ||
'Project already exists in current directory. If you want to continue its setup, run "serverless" without `--name`, `--template-path` options. Otherwise, if you want to setup a new project, run the command in a non-service directory.', |
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'd simplify the message to:
Cannot setup a new service being in context of the other service ("--name" and "--template-path" options cannot be applied)
What do you think?
lib/cli/interactive-setup/service.js
Outdated
if (serviceDir && (options.name || options['template-path'])) { | ||
throw new ServerlessError( | ||
'Project already exists in current directory. If you want to continue its setup, run "serverless" without `--name`, `--template-path` options. Otherwise, if you want to setup a new project, run the command in a non-service directory.', | ||
'INTERACTIVE_SERVICE_ALREADY_EXISTS' |
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.
We do not do INTERACTIVE_
prefix in case of other errors here, so I would probably not set it here.
Maybe let's name it simply NOT_APPLICABLE_SERVICE_OPTIONS
(?) (when processing errors we have information of command being used, so that doesn't have to leak to error codes)
af0007e
to
f876719
Compare
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 great 👍
Addresses: #9367