Skip to content

Conversation

@azaan-sherani
Copy link

@azaan-sherani azaan-sherani commented May 3, 2023

Description of changes:

Added two new commands:
ask install --component-name - installs the specified skill component in the alexa skill
ask uninstall --component-name - removes the specified skill component from the alexa skill, if it is installed.

These changes are in beta and will require testing and additions before merging it to develop in the future.

@azaan-sherani azaan-sherani requested review from doiron and tydonelson May 3, 2023 19:12
@azaan-sherani azaan-sherani self-assigned this May 3, 2023
@tydonelson
Copy link
Contributor

tydonelson commented May 3, 2023

Unit tests are missing. At a minimum we should have unit tests for the two new commands in /test/unit/commands/install/index-test.ts and test/unit/commands/uninstall/index-test.ts

throw err;
}

let skillPackageSrc = ResourcesConfig.getInstance().getSkillMetaSrc(profile);
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this can be const as well

throw err;
}

let skillPackageSrc = ResourcesConfig.getInstance().getSkillMetaSrc(profile);
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this can be const

path.join(componentDirPath, "README.md")
);

spinner.terminate(TERMINATE_STYLE.SUCCEED, `${componentName} installed successfully! \n \u001b[1mPlease edit the README.md file copied at ${skillPackageSrc}/components/${componentName} to configure the component\n`);
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 make this more explicit that they must edit the README.md to configure the component in order to use it? This is very weakly worded as-is.

Also it seems weird to have a configuration living in a README file, those are usually informational or instructional files, not something that's functionally important to the application...

Copy link
Author

Choose a reason for hiding this comment

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

This was a silly mistake from me.
Since, right now we don't have a component on npm with the "config.jsonc" file, I was testing with the components already present on npm. For this, I temporarily used for the "README.md" instead of "config.jsonc"(to check if it's being copied/removed correctly). I forgot to change the file name back to "config.jsonc", will do it right now.

@tydonelson tydonelson self-requested a review May 3, 2023 19:46
const spinner = new SpinnerView({ color: "yellow" });
spinner.start(`Installing ${componentName}...`);

const installCommand = spawn("npm", ["install", componentName], {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this PR doing an npm install on the --component-name ? If so, I failed to see the target audience that needs help with npm install.

Copy link
Author

Choose a reason for hiding this comment

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

It's also copying the config.jsonc file to the skillPackage. This config.jsonc file needs to be configured(adding intents, for example) by the skill developer to use the component.

Copy link
Contributor

@tydonelson tydonelson left a comment

Choose a reason for hiding this comment

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

Requesting address of comments, accidentally approved before

@azaan-sherani azaan-sherani changed the base branch from develop to feature/im-componentization May 4, 2023 21:05
@github-actions github-actions bot requested a review from LucioMS May 4, 2023 21:35
Copy link
Contributor

@doiron doiron left a comment

Choose a reason for hiding this comment

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

should may add something in the README.md file to explain what these commands are and what they do.

async handle(cmd: Record<string, any>): Promise<void> {
let profile: string;
try {
profile = profileHelper.runtimeProfile(cmd.profile);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit indentation


const skillPackageSrc = ResourcesConfig.getInstance().getSkillMetaSrc(profile);
if (!stringUtils.isNonBlankString(skillPackageSrc)) {
Messenger.getInstance().error("Skill package src is not found in ask-resources.json.");
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: indentation

Copy link
Contributor

Choose a reason for hiding this comment

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

also suggest

The skill package source directory was not found in the ask-resource.json file.

Copy link
Contributor

Choose a reason for hiding this comment

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

One further edit, since this can occur due to a profile mismatch:

`The skill package source directory was not found in the ask-resources.json file under the profile '${profile}'.`

return;
}
if (!fs.existsSync(skillPackageSrc)) {
Messenger.getInstance().error(`File ${skillPackageSrc} does not exist.`);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: indentation

Copy link
Contributor

Choose a reason for hiding this comment

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

also skillPackageSrc is a directory right, not a file?

Copy link
Author

Choose a reason for hiding this comment

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

also skillPackageSrc is a directory right, not a file?

I think it's the skillMetadata src file. Also used here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that skillPackageSrc from the ask-resource.json file
https://github.com/alexa/ask-cli/blob/develop/lib/model/resources-config/ask-resources.js#L56

is referencing the ./skill-package/ folder. the root of the skill files that are uploaded to Alexa during creation/updates to the skill.

installCommand.on("error", (err) => {
spinner.terminate(TERMINATE_STYLE.FAIL, `Failed to install ${componentName}.`);
throw new CliError(
`An error occurred while installing component ${componentName}: ${err.message}`
Copy link
Contributor

Choose a reason for hiding this comment

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

do we know what state we should be in here? what kind of errors does npm install throw and what are the mitigations?

if (code !== 0) {
spinner.terminate(TERMINATE_STYLE.FAIL, `Failed to install ${componentName}.`);
throw new CliError(
`An error occurred while installing component ${componentName}. Please try again.`
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe print out the error npm code and mention that npm threw this error code

);

if (!fs.existsSync(componentDirPath)) {
fs.mkdirSync(componentDirPath, { recursive: true });
Copy link
Contributor

Choose a reason for hiding this comment

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

not catching any errors here?

fs.mkdirSync(componentDirPath, { recursive: true });
}

fs.copyFileSync(
Copy link
Contributor

Choose a reason for hiding this comment

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

also not catching any io errors?

path.join(componentDirPath, "config.jsonc")
);

spinner.terminate(TERMINATE_STYLE.SUCCEED, `${componentName} installed successfully! \n \u001b[1mPlease edit the config.jsonc file copied at ${skillPackageSrc}/components/${componentName} to configure the component. This step is necessary for the component to function properly within your Alexa skill.\n`);

This comment was marked as resolved.

This comment was marked as resolved.

},
"component-name": {
"name": "component-name",
"description": "Name of the component to be installed.",
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure where we landed on terminology but component here seems very generic.

Copy link
Contributor

Choose a reason for hiding this comment

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

suggest to use whatever word nomenclature used elsewhere like Alexa Skill reusable component...

}

description() {
return "uninstall alexa skill components from your alexa skill";
Copy link
Contributor

Choose a reason for hiding this comment

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

I think Alexa should be capitalized

Comment on lines +66 to +79
// Check if the component is already installed
const componentDirPath = path.join(
skillPackageSrc,
"skillComponents",
componentName
);
const configFilePath = path.join(componentDirPath, "config.jsonc");

if (!fs.existsSync(configFilePath)) {
Messenger.getInstance().info(
`Component ${componentName} is not installed.`
);
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

separate function

return;
}

// Uninstall the component using npm with spinner
Copy link
Contributor

Choose a reason for hiding this comment

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

also move to separate function

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe move all the NPM stuff inside it's own module in the clients directory
https://github.com/alexa/ask-cli/tree/develop/lib/clients

interface npmClient {
installPackage(packageName)
unInstallPackage(packageName)
}

uninstallCommand.on("error", (err) => {
spinner.terminate(
TERMINATE_STYLE.FAIL,
`Failed to uninstall ${componentName}.`
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: add mitigations like
"... Manually uninstall the Alexa skill component by running: npm uninstall ${componentName}"

Copy link
Contributor

Choose a reason for hiding this comment

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

Big +1 here, this goes for all error messages. Non-actionable error messages are not very useful.

`Failed to uninstall ${componentName}.`
);
throw new CliError(
`An error occurred while uninstalling component ${componentName}: ${err.message}`
Copy link
Contributor

Choose a reason for hiding this comment

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

same add mitigation message

path.join(componentDirPath, "config.jsonc")
);

spinner.terminate(TERMINATE_STYLE.SUCCEED, `${componentName} installed successfully! \n \u001b[1mPlease edit the config.jsonc file copied at ${skillPackageSrc}/components/${componentName} to configure the component. This step is necessary for the component to function properly within your Alexa skill.\n`);
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the message update here, makes the necessity of this step much more apparent :)


const skillPackageSrc = ResourcesConfig.getInstance().getSkillMetaSrc(profile);
if (!stringUtils.isNonBlankString(skillPackageSrc)) {
Messenger.getInstance().error("Skill package src is not found in ask-resources.json.");
Copy link
Contributor

Choose a reason for hiding this comment

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

One further edit, since this can occur due to a profile mismatch:

`The skill package source directory was not found in the ask-resources.json file under the profile '${profile}'.`

uninstallCommand.on("error", (err) => {
spinner.terminate(
TERMINATE_STYLE.FAIL,
`Failed to uninstall ${componentName}.`
Copy link
Contributor

Choose a reason for hiding this comment

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

Big +1 here, this goes for all error messages. Non-actionable error messages are not very useful.

@github-actions github-actions bot requested a review from tydonelson May 15, 2023 22:24
@azaan-sherani azaan-sherani merged commit 26d598a into feature/im-componentization May 15, 2023
@azaan-sherani azaan-sherani deleted the im-componentization branch May 15, 2023 22:35
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.

4 participants