-
-
Notifications
You must be signed in to change notification settings - Fork 179
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
feat: improve glee command #890
Changes from all commits
14cbd0c
03c0146
0c7dc9a
972cef0
013599d
0bb6b5d
002952f
c673263
3750452
6665cd9
16d845c
84162fc
29b2df3
9b42245
6a53b61
a1afe8b
6a82b6c
2a28d11
51d1a6f
fa80b7c
f8cdf92
aabac41
0fc7b9f
98a25ec
aa01244
7e0803f
5b3d0d6
e78d376
fe226df
9b71196
332272a
a1b94b8
25b03ce
4b35b4c
286d695
ed68eae
d8dd534
d7f3cb7
f81c02c
2cc23ec
10d051e
9b906a0
456f94d
ce3b64b
3fb37b5
5331813
5126039
985b99a
b35ff1d
3f13a1d
4db28fd
79e36d9
093cac3
b81b9e8
5fd4080
8866706
1336bd1
cd37b67
7e9de8b
79c7aad
cbeba16
c5cc299
be9e5a1
6a4d4a1
1f7065b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,247 @@ | ||
import {Flags} from '@oclif/core'; | ||
import { Flags } from '@oclif/core'; | ||
import { promises as fPromises } from 'fs'; | ||
import Command from '../../base'; | ||
import { resolve, join } from 'path'; | ||
import path, { resolve, join } from 'path'; | ||
import fs from 'fs-extra'; | ||
import { Specification, load } from '../../models/SpecificationFile'; | ||
import yaml from 'js-yaml'; | ||
import { prompt } from 'inquirer'; | ||
// eslint-disable-next-line | ||
// @ts-ignore | ||
import Generator from '@asyncapi/generator'; | ||
|
||
export default class NewGlee extends Command { | ||
static description = 'Creates a new Glee project'; | ||
|
||
protected commandName = 'glee'; | ||
|
||
static flags = { | ||
help: Flags.help({ char: 'h' }), | ||
name: Flags.string({ char: 'n', description: 'name of the project', default: 'project' }), | ||
template: Flags.string({ char: 't', description: 'name of the template', default: 'default' }), | ||
name: Flags.string({ | ||
char: 'n', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is a requirement by the generator. you can't generate on a git repository with upstaged changes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, but can't we pass in the flag from our CLI, since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok sure will do that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @KhudaDad414 Added the required changes. please review. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /rtm There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @KhudaDad414 i have Added force-write flag. please review. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AyushNautiyalDeveloper |
||
description: 'Name of the Project', | ||
default: 'project', | ||
}), | ||
template: Flags.string({ | ||
char: 't', | ||
description: 'Name of the Template', | ||
default: 'default', | ||
}), | ||
file: Flags.string({ | ||
char: 'f', | ||
description: | ||
'The path to the AsyncAPI file for generating a Glee project.', | ||
}), | ||
'force-write': Flags.boolean({ | ||
default: false, | ||
description: | ||
'Force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir (defaults to false)', | ||
}), | ||
}; | ||
|
||
async run() { | ||
const { flags } = await this.parse(NewGlee); // NOSONAR | ||
async getFilteredServers(serversObject: any) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't want to remove the template support. Users should still be able to create a glee project from one of the templates. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
console.log({ serversObject }); | ||
const servers = Object.keys(serversObject); | ||
|
||
const projectName = flags.name; | ||
const templateName = flags.template; | ||
const localServers = await prompt([ | ||
{ | ||
name: 'LOCAL_SERVERS', | ||
message: | ||
'Select all of the servers that you want glee to set up and run a server for (local servers):', | ||
type: 'checkbox', | ||
choices() { | ||
return servers; | ||
}, | ||
}, | ||
]); | ||
|
||
const PROJECT_DIRECTORY = join(process.cwd(), projectName); | ||
const GLEE_TEMPLATES_DIRECTORY = resolve(__dirname, '../../../assets/create-glee-app/templates/', templateName); | ||
return servers.filter( | ||
(server) => !localServers.LOCAL_SERVERS.includes(server) | ||
); | ||
} | ||
async createTemporaryFile( | ||
asyncapiInput: Specification, | ||
filteredRemoteServers: string[], | ||
file: any | ||
) { | ||
const asyncapiObject = asyncapiInput.toJson(); | ||
asyncapiObject['x-remoteServers'] = filteredRemoteServers; | ||
|
||
delete asyncapiObject.filePath; | ||
delete asyncapiObject.kind; | ||
|
||
const updatedAsyncApiContent = yaml.dump(asyncapiObject, { | ||
lineWidth: -1, | ||
}); | ||
|
||
const currentFileDirectory = path.join(__dirname, file); | ||
|
||
fs.writeFileSync(currentFileDirectory, updatedAsyncApiContent); | ||
return { currentFileDirectory, updatedAsyncApiContent }; | ||
} | ||
async validateFile(file: any, projectName: any, PROJECT_DIRECTORY: any) { | ||
try { | ||
await fPromises.mkdir(PROJECT_DIRECTORY); | ||
const validExtensions = ['.yaml', '.yml', '.json']; | ||
const fileExtension = path.extname(file); | ||
|
||
if (!validExtensions.includes(fileExtension)) { | ||
throw new Error( | ||
'CLI Support only yml, yaml, and json extension for file' | ||
); | ||
} | ||
|
||
if ( | ||
fs.existsSync(PROJECT_DIRECTORY) && | ||
fs.readdirSync(PROJECT_DIRECTORY).length > 0 | ||
) { | ||
throw new Error( | ||
`Unable to create the project. We tried to use "${projectName}" as the directory of your new project but it already exists (${PROJECT_DIRECTORY}). Please specify a different name for the new project. For example, run the following command instead:\n\n asyncapi new ${this.commandName} -f ${file} --name ${projectName}-1\n` | ||
); | ||
} | ||
} catch (error: any) { | ||
this.error(error.message); | ||
} | ||
} | ||
|
||
async handleGenerateProjectWithFile( | ||
file: any, | ||
CURRENT_GLEE_TEMPLATE: any, | ||
projectName: string, | ||
forceWrite: boolean | ||
) { | ||
const PROJECT_DIRECTORY = path.join(process.cwd(), projectName); | ||
await this.validateFile(file, projectName, PROJECT_DIRECTORY); | ||
|
||
try { | ||
console.log(file); | ||
const asyncapiInput = (await load(file)) || (await load()); | ||
console.log(asyncapiInput); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ayushnau There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. now it is working. |
||
|
||
const serversObject = asyncapiInput.toJson()?.servers; | ||
let filteredRemoteServers: any[] = []; | ||
if (serversObject) { | ||
filteredRemoteServers = await this.getFilteredServers(serversObject); | ||
} | ||
|
||
const temporaryFileDirectory = 'asyncapi.yaml'; | ||
const { currentFileDirectory, updatedAsyncApiContent } = | ||
await this.createTemporaryFile( | ||
asyncapiInput, | ||
filteredRemoteServers, | ||
temporaryFileDirectory | ||
); | ||
|
||
const generator = new Generator( | ||
CURRENT_GLEE_TEMPLATE, | ||
PROJECT_DIRECTORY, | ||
{ forceWrite } | ||
); | ||
await generator.generateFromString(updatedAsyncApiContent); | ||
fs.unlinkSync(currentFileDirectory); | ||
|
||
this.log( | ||
`Success! Created ${projectName} at ${PROJECT_DIRECTORY}\n\nNext steps:\n\n cd ${projectName}\n npm install --ignore-scripts\n\nImplement the function in functions and auth folder and run the project with:\n npm run dev` | ||
); | ||
} catch (err: any) { | ||
switch (err.code) { | ||
case 'EEXIST': | ||
this.error(`Unable to create the project. We tried to use "${projectName}" as the directory of your new project but it already exists (${PROJECT_DIRECTORY}). Please specify a different name for the new project. For example, run the following command instead:\n\n asyncapi new ${this.commandName} --name ${projectName}-1\n`); | ||
break; | ||
case 'EACCES': | ||
this.error(`Unable to create the project. We tried to access the "${PROJECT_DIRECTORY}" directory but it was not possible due to file access permissions. Please check the write permissions of your current working directory ("${process.cwd()}").`); | ||
this.error( | ||
`Unable to create the project. We tried to access the "${PROJECT_DIRECTORY}" directory but it was not possible due to file access permissions. Please check the write permissions of your current working directory ("${process.cwd()}").` | ||
); | ||
break; | ||
case 'EPERM': | ||
this.error(`Unable to create the project. We tried to create the "${PROJECT_DIRECTORY}" directory but the operation requires elevated privileges. Please check the privileges for your current user.`); | ||
this.error( | ||
`Unable to create the project. We tried to create the "${PROJECT_DIRECTORY}" directory but the operation requires elevated privileges. Please check the privileges for your current user.` | ||
); | ||
break; | ||
default: | ||
this.error(`Unable to create the project. Please check the following message for further info about the error:\n\n${err}`); | ||
this.error( | ||
`Unable to create the project. Please check the following message for further info about the error:\n\n${err}` | ||
); | ||
} | ||
} | ||
} | ||
async run() { | ||
const { flags } = await this.parse(NewGlee); // NOSONAR | ||
|
||
try { | ||
await fs.copy(GLEE_TEMPLATES_DIRECTORY, PROJECT_DIRECTORY); | ||
await fPromises.rename(`${PROJECT_DIRECTORY}/env`, `${PROJECT_DIRECTORY}/.env`); | ||
await fPromises.rename(`${PROJECT_DIRECTORY}/gitignore`, `${PROJECT_DIRECTORY}/.gitignore`); | ||
await fPromises.rename(`${PROJECT_DIRECTORY}/README-template.md`, `${PROJECT_DIRECTORY}/README.md`); | ||
this.log(`Your project "${projectName}" has been created successfully!\n\nNext steps:\n\n cd ${projectName}\n npm install\n npm run dev\n\nAlso, you can already open the project in your favorite editor and start tweaking it.`); | ||
} catch (err) { | ||
this.error(`Unable to create the project. Please check the following message for further info about the error:\n\n${err}`); | ||
const { | ||
name: projectName, | ||
template: templateName, | ||
file, | ||
'force-write': forceWrite, | ||
} = flags; | ||
|
||
const PROJECT_DIRECTORY = join(process.cwd(), projectName); | ||
|
||
const GLEE_TEMPLATES_DIRECTORY = resolve( | ||
__dirname, | ||
'../../../assets/create-glee-app/templates/', | ||
templateName | ||
); | ||
|
||
const CURRENT_GLEE_TEMPLATE = | ||
'https://github.com/KhudaDad414/glee-generator-template'; | ||
|
||
if (file && templateName && templateName !== 'default') { | ||
this.error('You cannot use both --t and --f in the same command.'); | ||
} | ||
|
||
if (file) { | ||
console.log('file running'); | ||
await this.handleGenerateProjectWithFile( | ||
file, | ||
CURRENT_GLEE_TEMPLATE, | ||
projectName, | ||
forceWrite | ||
); | ||
} else { | ||
try { | ||
await fPromises.mkdir(PROJECT_DIRECTORY); | ||
} catch (err: any) { | ||
switch (err.code) { | ||
case 'EEXIST': | ||
this.error( | ||
`Unable to create the project. We tried to use "${projectName}" as the directory of your new project but it already exists (${PROJECT_DIRECTORY}). Please specify a different name for the new project. For example, run the following command instead:\n\n asyncapi new ${this.commandName} --name ${projectName}-1\n` | ||
); | ||
break; | ||
case 'EACCES': | ||
this.error( | ||
`Unable to create the project. We tried to access the "${PROJECT_DIRECTORY}" directory but it was not possible due to file access permissions. Please check the write permissions of your current working directory ("${process.cwd()}").` | ||
); | ||
break; | ||
case 'EPERM': | ||
this.error( | ||
`Unable to create the project. We tried to create the "${PROJECT_DIRECTORY}" directory but the operation requires elevated privileges. Please check the privileges for your current user.` | ||
); | ||
break; | ||
default: | ||
this.error( | ||
`Unable to create the project. Please check the following message for further info about the error:\n\n${err}` | ||
); | ||
} | ||
} | ||
|
||
try { | ||
await fs.copy(GLEE_TEMPLATES_DIRECTORY, PROJECT_DIRECTORY); | ||
await fPromises.rename( | ||
`${PROJECT_DIRECTORY}/env`, | ||
`${PROJECT_DIRECTORY}/.env` | ||
); | ||
await fPromises.rename( | ||
`${PROJECT_DIRECTORY}/gitignore`, | ||
`${PROJECT_DIRECTORY}/.gitignore` | ||
); | ||
await fPromises.rename( | ||
`${PROJECT_DIRECTORY}/README-template.md`, | ||
`${PROJECT_DIRECTORY}/README.md` | ||
); | ||
this.log( | ||
`Your project "${projectName}" has been created successfully!\n\nNext steps:\n\n cd ${projectName}\n npm install\n npm run dev\n\nAlso, you can already open the project in your favorite editor and start tweaking it.` | ||
); | ||
} catch (err) { | ||
this.error( | ||
`Unable to create the project. Please check the following message for further info about the error:\n\n${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.
can you reset the formatting changes? it makes it hard to review.
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.
Actually this was my default setting.