@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
103 lines (91 loc) • 3.9 kB
JavaScript
const path = require('path')
const cds = require('../../../cds')
const InternalBuildPlugin = require('../internalBuildPlugin')
const { BUILD_TASK_HANA } = require('../../constants')
const fs = require('fs')
const { WARNING } = InternalBuildPlugin
const DEFAULT_TAR_NAME = "resources.tgz"
class ResourcesTarBuilder {
constructor(plugin) {
this._plugin = plugin
}
get plugin() { return this._plugin }
async createTar(dest, model) {
const { root, resources } = await this._getResources(model)
if (resources.length === 0) {
// packTarArchive fails otherwise
this.plugin.pushMessage("No deployment resources found - skip resources.tgz", WARNING)
return
}
await this.writeTarFile(path.join(dest, DEFAULT_TAR_NAME), root, resources)
}
/**
* Creates a TAR file at the given absolute tarPath. An optional resources list holds the files and folders
* that will be added to the TAR. Paths are relative to the passed root directory. If omitted, the entire
* root directory contents will be added.
* @param {*} tarFile Absolute TAR file name.
* @param {*} root The root directory the passed resources are relative to.
* @param {*} resources Optional list of absolute or relative resource paths - relative to the given root directory.
* If omitted all resources contained in the root directory are added to the TAR file.
*/
async writeTarFile(tarFile, root, resources) {
const { tar } = require('../../..').utils
await tar.czfd(tarFile, root, resources)
this.plugin.pushFile(tarFile)
}
async _getResources(model) {
// distinguish HANA and SQLITE deployment
let root = this._getHanaTenantDbPath()
let resources
if (root) {
resources = this._getHanaResources(root)
} else {
root = cds.root
resources = await this._getSqliteResources(model)
}
return { root, resources }
}
/**
* Reads a list of files and folders required for HANA deployment.
* This is a subset of all files contained in the directory.
* - 'db/src', 'db/cfg', 'db/undeploy.json'...
* See '../../../../lib.deploy'
* Note: the hana build task has already been executed
* @param {string} root
* @returns an array containing all resources
*/
_getHanaResources(root) {
return ['src', 'cfg', 'undeploy.json', '.hdiignore'].reduce((acc, res) => {
const resPath = path.join(root, res)
if (fs.existsSync(resPath)) {
acc.push(resPath)
}
return acc
}, [])
}
/**
* Reads all resources for Sqlite deployment - see '../../../../lib.deploy'
*
* @param {object} model
* @returns
*/
async _getSqliteResources(model) {
const { resources } = cds.deploy
return Object.keys(await resources(model))
}
_getHanaTenantDbPath() {
return ResourcesTarBuilder.getHanaTenantDbTask(this.plugin.context.tasks, this.plugin.task)?.dest
}
static getHanaTenantDbTask(tasks, mtxTask) {
const hanaTasks = tasks.filter(task => task.for === BUILD_TASK_HANA)
if (hanaTasks.length === 1) return hanaTasks[0]
return hanaTasks.find(hanaTask => {
// if called from internalBuildTaskProvider, the src folder for the tenant db task might still not set
// while an existing second shared db always requires src to be set
if (!hanaTask.src) return true
const srcFolder = path.isAbsolute(hanaTask.src) ? path.relative(cds.root, hanaTask.src) : hanaTask.src
return mtxTask.options?.model?.includes(srcFolder) || srcFolder === cds.env.folders.db.replace('/', '')
})
}
}
module.exports = ResourcesTarBuilder