@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
178 lines (125 loc) • 5.92 kB
JavaScript
const { options, flags, shortcuts } = require('../../lib/deploy/index.js');
module.exports = Object.assign(deploy, {
options,
flags,
shortcuts,
help: `
# SYNOPSIS
*cds deploy* [ <model> ] [ <options> ]
Deploys the given model to a database. If no model is given it looks up
according configuration from _package.json_ or _.cdsrc.json_ in key
_cds.requires.db_. Same for the database.
Supported databases: sqlite, hana
# OPTIONS
*-2* | *--to* <database> [ : <database specific parameter> ],
Where <database> is 'sqlite' or 'hana', <database specific parameter>
can be a path to the database file (sqlite) or the service name (hana).
*-4* | *--for* <profile> (only in combination with *--to hana*)
Specify the profile to be used to call 'cds bind' after successful deployment.
Refer to the help of 'cds bind' for further information.
The profile *hybrid* is used by default.
*--profile* <profile,...>
Loads the configuration data for the specified profile(s). 'cds build' is executed based on these profile settings,
additionally binding information is resolved based on these profile settings. If a corresponding binding exists its service
name and service key will be used. The *development* profile is used by default.
*--dry*
Just print the SQL statements without executing them.
*--no-build* (only in combination with *--to hana*)
Skip running *cds build*.
*--out* | *-o* <file>
Write the DDL statements to the given file.
Not available in combination with '--to hana'.
*--on* | *-n* cf|k8s
The target platform.
Defaults to *k8s* when Helm charts are present and no *mta.yaml* exists, otherwise *cf*.
*--with-mocks*
Also create tables for all entities from imported models.
*--no-save*
Deprecated. The package.json file is no longer modified.
*--auto-undeploy*
Tell HDI deployer to automatically undeploy deleted resources.
*--tunnel-address*
Deploy through the given address (host:port) rather than the original
database address. The tunnel must have been opened before, e.g. using 'cf ssh'.
*--vcap-file*
Use credentials from the given file when deploying to *SAP HANA*, instead of
creating new credentials. File must be in *cf env* format, with a root
node *VCAP_SERVICES*. The following hdi related entries are supported:
TARGET_CONTAINER, VCAP_SERVICES and SERVICE_REPLACEMENTS.
*--model-only*
Schema evolution: only update the information about the prior cds model.
In combination with *--dry* it writes the CSN to stdout, so you can store it to a file.
Use that to migrate existing databases to auto schema evolution.
*--delta-from* <filename>
Schema evolution: read the information about the prior cds model from the given file,
which has been created by *cds deploy --model-only --dry*. When used with *--dry* it writes
the generated SQL to stdout.
*--script*
Schema evolution: together with *--delta-from* generate a script of SQL
statements to then check and execute manually or for usage with tools such as LiquiBase.
This script might contain potentially lossy statements!
# EXAMPLES
cds deploy --to sqlite:db
cds deploy --to hana
cds deploy --to hana:myService --auto-undeploy
cds deploy --to hana --no-build
`})
async function deploy(_model, options) {
if (process.stdout.isTTY && options['no-save']) {
console.warn('Option --no-save is deprecated. By default, package.json will no longer be modified.')
}
if (_model && _model.length === 0) _model = undefined // empty array (no model args) means default models
// ensure that cds build plugins defined as devDependencies are loaded
if (process.env.NODE_ENV === 'production') delete process.env.NODE_ENV
const cds = require('../../lib/cds')
// IMPORTANT: call plugins before subsequent access to cds.env
await cds.plugins
const { 'to': url } = options
if (!options.mocked && options['with-mocks']) options.mocked = true
if (!url && !cds.env.requires.db) throw new Error(
`Please specify a database kind or url, e.g.:
cds deploy --to sql
cds deploy --to sqlite
cds deploy --to sqlite:db/my-db.sqlite
`)
const conf = cds.env.requires.db || {}
const [, _kind, _db] = /(\w+)?(?::(.*))?/.exec(url || '')
const kind = _kind || conf.dialect || conf.kind
try {
var deployer = require('./to-' + kind)
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND') {
throw new Error(`Didn't find a deployer module for '${kind}'`) // eslint-disable-line preserve-caught-error
}
}
try {
options.messages = []
if (options.script) options.dry = true // to ensure that we don't accidentally execute any SQLs
if (options.out) {
options.schema_log = []
}
await deployer.deploy(_model, _db, options)
const log = this.log || _log
if (options.messages.length) log (options.messages, options)
if (options.out && options.schema_log?.length) {
await cds.utils.write (options.out, options.schema_log.join('\n'))
}
} catch (e) {
if (e.code !== 'MODEL_NOT_FOUND') throw e
if (_model) throw `No cds models found at/in '${_model}'`
if (options.dry && options.out) {
// this is to allow project starts w/o a model with a watcher running
console.error('No .cds models found. Doing nothing in dry mode with specified output file.')
}
else {
throw 'No .cds models found, please specify one as an argument'
}
}
}
function _log (messages, options) {
const cds = require('../../lib/cds')
const { sortMessagesSeverityAware, deduplicateMessages } = cds.compiler
deduplicateMessages(messages)
messages = sortMessagesSeverityAware (messages)
cds._log (messages, options)
}