Skip to content

Commit

Permalink
Merge pull request #90 from ui5-community/feat/capAdd
Browse files Browse the repository at this point in the history
feat(cap): Allow for dynamic choice of CAP capabilities
  • Loading branch information
nicoschoenteich authored Oct 18, 2024
2 parents 47c2f91 + b0e6afa commit 1f054b8
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 23 deletions.
51 changes: 51 additions & 0 deletions generators/cap/capabilities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export default [
// Databases
{ name: "sqlite", checked: false },
{ name: "hana", checked: false },
{ name: "postgres", checked: true },
// Runtime
{ name: "approuter", checked: false },
{ name: "html5-repo", checked: true },
{ name: "portal", checked: false },
// Deployment
{ name: "helm", checked: false },
{ name: "helm-unified-runtime", checked: false },
{ name: "containerize", checked: false },
{ name: "pipeline", checked: false },
// Security
{ name: "xsuaa", checked: true },
// Lintin
{ name: "lint", checked: false },
// Typing
{ name: "typer", checked: false },
{ name: "typescript", checked: false },
// Samples & Sample Data
{ name: "tiny-sample", checked: true },
{ name: "sample", checked: false },
{ name: "data", checked: true },
// HTTP
{ name: "http", checked: true },
// Connectivity
{ name: "connectivity", checked: false },
{ name: "destination", checked: false },
// Logging
{ name: "application-logging", checked: false },
{ name: "audit-logging", checked: false },
// Messaging
{ name: "local-messaging", checked: false },
{ name: "file-based-messaging", checked: false },
{ name: "enterprise-messaging", checked: false },
{ name: "enterprise-messaging-shared", checked: false },
{ name: "redis-messaging", checked: false },
{ name: "kafka", checked: false },
// Notifications
{ name: "notifications", checked: false },
// Attachments
{ name: "attachments", checked: false },
// Feature Toggles
{ name: "toggles", checked: false },
// Multitenancy
{ name: "multitenancy", checked: false },
// Extensibility
{ name: "extensibility" , checked: false }
];
64 changes: 44 additions & 20 deletions generators/cap/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ export default class extends Generator {
async writing() {
this.log(chalk.green(`✨ creating new SAP CAP module for ${this.options.config.projectName}`))

// mta is not an option in the prompts, but it is required for the root mta.yaml
const capCapabilities = [...this.options.config.capCapabilities, 'mta']

// TO-DO: check for typescript and configure cap project accordingly
this.spawnCommandSync("npx", ["-p", "@sap/cds-dk", "cds", "init", `${this.options.config.capName}`, "--add", "tiny-sample, data, xsuaa, mta, postgres"],
this.spawnCommandSync("npx", ["-p", "@sap/cds-dk", "cds", "init", `${this.options.config.capName}`, "--add", capCapabilities.join(",")],
this.destinationPath()
)

Expand All @@ -55,8 +58,9 @@ export default class extends Generator {
if (!rootMtaYaml.resources) rootMtaYaml.resources = []

const authName = `${this.options.config.projectId}-auth`
const xsuaaCapability = this.options.config.capCapabilities.includes("xsuaa")
// use auth and xs-security.json from cap module
if (["Static webserver", "Application Router"].includes(this.options.config.platform)) {
if (xsuaaCapability && ["Static webserver", "Application Router"].includes(this.options.config.platform)) {
const capAuth = capMtaYaml.resources.find(resource => resource.name === `${this.options.config.capName}-auth`)
capAuth.name = authName
capAuth.parameters.path = `${this.options.config.capName}/xs-security.json`
Expand All @@ -73,31 +77,51 @@ export default class extends Generator {
rootMtaYaml.resources.push(capAuth)
}
// use auth and xs-security.json from root
else if (["SAP HTML5 Application Repository Service", "SAP Build Work Zone, standard edition"].includes(this.options.config.platform)) {
else if (xsuaaCapability && ["SAP HTML5 Application Repository Service", "SAP Build Work Zone, standard edition"].includes(this.options.config.platform)) {
fs.rename(this.destinationPath("xs-security.json"), `${this.options.config.capName}/xs-security.json`, err => { })
const rootAuth = rootMtaYaml.resources.find(resource => resource.name === authName)
rootAuth.parameters.path = `${this.options.config.capName}/xs-security.json`
}

const capPostgres = capMtaYaml.resources.find(resource => resource.name === `${this.options.config.capName}-postgres`)
capPostgres.name = `${this.options.config.projectId}-${capPostgres.name}`
rootMtaYaml.resources.push(capPostgres)

const capDeployer = capMtaYaml.modules.find(module => module.name === `${this.options.config.capName}-postgres-deployer`)
capDeployer.path = this.options.config.capName + "/" + capDeployer.path
capDeployer.name = `${this.options.config.projectId}-${capDeployer.name}`
capDeployer.requires = [
{ name: capPostgres.name }
]
rootMtaYaml.modules.push(capDeployer)

const postgresCapability = this.options.config.capCapabilities.includes("postgres")
let capPostgres = null
if(postgresCapability) {
capPostgres = capMtaYaml.resources.find(resource => resource.name === `${this.options.config.capName}-postgres`)
capPostgres.name = `${this.options.config.projectId}-${capPostgres.name}`
rootMtaYaml.resources.push(capPostgres)


const capDeployer = capMtaYaml.modules.find(module => module.name === `${this.options.config.capName}-postgres-deployer`)
capDeployer.path = this.options.config.capName + "/" + capDeployer.path
capDeployer.name = `${this.options.config.projectId}-${capDeployer.name}`
capDeployer.requires = [
{ name: capPostgres.name }
]
rootMtaYaml.modules.push(capDeployer)
}

const capSrv = capMtaYaml.modules.find(module => module.name === `${this.options.config.capName}-srv`)
capSrv.path = this.options.config.capName + "/" + capSrv.path
capSrv.path = `${this.options.config.capName}/${capSrv.path}`;
capSrv.name = `${this.options.config.projectId}-${capSrv.name}`
capSrv.requires = [
{ name: capPostgres.name },
{ name: authName }
]
capSrv.requires = capSrv.requires ?? []
if (xsuaaCapability) {
const xsuaaDependency = capSrv.requires.find(dependency => dependency.name === `${this.options.config.capName}-auth`)
if(xsuaaDependency) {
xsuaaDependency.name = authName
} else {
capSrv.requires.push({ name: authName })
}
}
if (postgresCapability) {
const postgresServiceName = `${this.options.config.capName}-postgres`
const postgresDependency = capSrv.requires.find(dependency => dependency.name === postgresServiceName)
if(postgresDependency) {
postgresDependency.name = capPostgres.name
} else {
capSrv.requires.push({ name: `${this.options.config.projectId}-${capPostgres.name}` })
}
}

rootMtaYaml.modules.push(capSrv)

fs.unlinkSync(this.destinationPath(`${this.options.config.capName}/mta.yaml`))
Expand Down
8 changes: 8 additions & 0 deletions generators/cap/prompts.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
validateAlphaNumericStartingWithLetterNonEmpty
} from "../helpers.js"
import capabilities from "./capabilities.js"

export default async function prompts() {

Expand All @@ -11,6 +12,13 @@ export default async function prompts() {
default: "server",
validate: validateAlphaNumericStartingWithLetterNonEmpty
})).capName

this.options.config.capCapabilities = (await this.prompt({
type: "checkbox",
name: "capCapabilities",
message: "Which CAP capabilities do you want to add?",
choices: capabilities.map(capability => ({ name: capability.name, value: capability.name, checked: capability.checked })),
})).capCapabilities

this.options.config.runModelSubgenerator = (await this.prompt({
type: "confirm",
Expand Down
9 changes: 6 additions & 3 deletions test/after-project-generation.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const testCases = [
setupRouteTarget: true,
controlName: "CustomControl",
testName: "Second",
capName: "server"
capName: "server",
capCapabilities: ["postgres", "mta", "xsuaa", "data", "tiny-sample"]
},
{
additionalSubgenerators: ["model", "view", "customcontrol", "qunit", "opa5", "cap", "uimodule"], // run uimodule last to avoid prompts to select between uimodules
Expand All @@ -30,7 +31,8 @@ export const testCases = [
setupRouteTarget: false,
controlName: "CustomControl",
testName: "Second",
capName: "server"
capName: "server",
capCapabilities: ["postgres", "mta", "xsuaa", "data", "tiny-sample"]
},
{
additionalSubgenerators: ["model", "view", "customcontrol", "qunit", "opa5", "cap", "uimodule"], // run uimodule last to avoid prompts to select between uimodules
Expand All @@ -44,7 +46,8 @@ export const testCases = [
setupRouteTarget: false,
controlName: "CustomControl",
testName: "Second",
capName: "server"
capName: "server",
capCapabilities: ["postgres", "mta", "xsuaa", "data", "tiny-sample"]
},
{
additionalSubgenerators: ["model", "view", "customcontrol", "qunit", "opa5", "cap", "uimodule"], // run uimodule last to avoid prompts to select between uimodules
Expand Down

0 comments on commit 1f054b8

Please sign in to comment.