Skip to content
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: adapt build plugin implementation to new API #319

Merged
merged 10 commits into from
Nov 6, 2023
9 changes: 5 additions & 4 deletions postgres/cds-plugin.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const cds = require('@sap/cds/lib')
const cds = require('@sap/cds')

if (!cds.env.fiori.lean_draft) {
throw new Error('"@cap-js/postgres" only works if cds.fiori.lean_draft is enabled. Please adapt your configuration.')
}

if (cds.cli.command === 'build') {
module.exports = require('./lib/build')
}
cds.build?.register?.('postgres', {
impl: __dirname + '/lib/build.js',
LotharBender marked this conversation as resolved.
Show resolved Hide resolved
taskDefaults: { src: cds.env.folders.db, dest: 'pg' }
LotharBender marked this conversation as resolved.
Show resolved Hide resolved
})
31 changes: 3 additions & 28 deletions postgres/lib/build.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,12 @@
const cds = require('@sap/cds')

let BuildPlugin
try {
({ BuildPlugin } = require('@sap/cds-dk/lib/build'))
} catch (e) {
if (e.code === 'ENOTFOUND') throw `No build plugin mechanism for @sap/cds-dk found. Please install @sap/cds-dk for development using 'npm i -D @sap/cds-dk@^7.3.0'`
else throw e
}

const { fs, path, rimraf } = cds.utils

module.exports = class PostgresBuildPlugin extends BuildPlugin {
static hasTask() { // REVISIT: should be unnecessary -> plugin mechanism knows what to pull
Copy link
Contributor

@LotharBender LotharBender Oct 23, 2023

Choose a reason for hiding this comment

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

The hasTask impl has ensured that a postgres build task is only executed if a postgres database is used according to the effective cds configuration. E.g. a sqlite database might have been configured for the development profile.
Of course, this might be an edge case, but on the other hand the check is simple and ensures that users don't get surprised if cds build is executed with development profile ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, unfortunately I also don't see another way to make it work properly w/ the profile technique where you switch between HANA/Postgres based on config profiles. I re-added the hasTask again.

Copy link
Contributor

Choose a reason for hiding this comment

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

...unfortunately? - I think this is a perfect solution :)

Copy link
Contributor Author

@swaldmann swaldmann Oct 27, 2023

Choose a reason for hiding this comment

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

I think it's close to perfect, but ideally the plugin doesn't handle what the plugin orchestrator in cap/cds should do, deciding which plugins to pull.

I'd rather have an opt-out mechanism like this instead, which is then also combinable with profiles:

"cds": {
  "requires": {
      "plugins": {
        "[pg]":  {
          "@sap/cds-hana": false
        },
        "[hana]": {
          "@cap-js/postgres": false
        }
     }
  }
}

Opting out in non-centralized places like the build plugin introduces inconsistent behavior, e.g. the plugin will still show up as loaded with DEBUG=plugins.

Also, it reduces the number of functions you have to implement from 2 to 1, which is huge imo.

@danjoa What's your take on this?

Copy link
Contributor

@LotharBender LotharBender Oct 30, 2023

Choose a reason for hiding this comment

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

But isn't this more a question of different lifecycles for cds plugin versus cds build task. Loading the cds plugin does not necessarily mean that a corresponding build task respectively its BuildPlugin counterpart will get executed.

I think the cds add plugin would behave similar. A cds plugin will be loaded, but the concrete cds facet implementation might not, as this is determined using the concrete cds add command line parameters or some other facet dependencies.

return cds.requires.db.kind === 'postgres'
}

static getTaskDefaults() {
return { src: cds.env.folders.db }
}
const { fs, path } = cds.utils

init() {
this.task.dest = cds.env.build.target === '.' ? path.join('gen','pg') : path.join('gen', 'pg')
}

async clean() {
await rimraf(this.task.dest)
}
module.exports = class PostgresBuildPlugin extends cds.build.BuildPlugin {

async build() {
const model = await this.model()
if (!model) {
return
}
if (!model) return

const promises = []
promises.push(this.write({
Expand Down