diff --git a/lib/utils/fonts/fonts.conf b/lib/utils/fonts/fonts.conf
new file mode 100644
index 000000000..53aad4e2a
--- /dev/null
+++ b/lib/utils/fonts/fonts.conf
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+ /usr/share/fonts
+ /usr/X11R6/lib/X11/fonts
+ /usr/local/share/fonts
+ /code/fonts
+
+ fonts
+
+ ~/.fonts
+
+
+
+
+ mono
+
+
+ monospace
+
+
+
+
+
+
+ sans serif
+
+
+ sans-serif
+
+
+
+
+
+
+ sans
+
+
+ sans-serif
+
+
+
+
+ conf.d
+
+
+
+ /var/cache/fontconfig
+ fontconfig
+
+ ~/.fontconfig
+
+
+
+
+ 0x0020
+ 0x00A0
+ 0x00AD
+ 0x034F
+ 0x0600
+ 0x0601
+ 0x0602
+ 0x0603
+ 0x06DD
+ 0x070F
+ 0x115F
+ 0x1160
+ 0x1680
+ 0x17B4
+ 0x17B5
+ 0x180E
+ 0x2000
+ 0x2001
+ 0x2002
+ 0x2003
+ 0x2004
+ 0x2005
+ 0x2006
+ 0x2007
+ 0x2008
+ 0x2009
+ 0x200A
+ 0x200B
+ 0x200C
+ 0x200D
+ 0x200E
+ 0x200F
+ 0x2028
+ 0x2029
+ 0x202A
+ 0x202B
+ 0x202C
+ 0x202D
+ 0x202E
+ 0x202F
+ 0x205F
+ 0x2060
+ 0x2061
+ 0x2062
+ 0x2063
+ 0x206A
+ 0x206B
+ 0x206C
+ 0x206D
+ 0x206E
+ 0x206F
+ 0x2800
+ 0x3000
+ 0x3164
+ 0xFEFF
+ 0xFFA0
+ 0xFFF9
+ 0xFFFA
+ 0xFFFB
+
+
+
+ 30
+
+
+
+
\ No newline at end of file
diff --git a/src/bin/fun-install.js b/src/bin/fun-install.js
index 687ca593c..894e8b0ef 100755
--- a/src/bin/fun-install.js
+++ b/src/bin/fun-install.js
@@ -37,6 +37,8 @@ program
.description('install dependencies which are described in fun.yml file.')
.action(async (packageNames, program) => {
+ if (_.isEmpty(packageNames)) { return; }
+
const options = convertOptions(program);
// merge options default values.
@@ -181,7 +183,6 @@ program.parse(process.argv);
notifier.notify();
-
if (!program.args.length) {
if (program.packageType) {
diff --git a/src/lib/deploy/deploy-by-tpl.js b/src/lib/deploy/deploy-by-tpl.js
index f209ff7bf..99283dc5a 100644
--- a/src/lib/deploy/deploy-by-tpl.js
+++ b/src/lib/deploy/deploy-by-tpl.js
@@ -703,7 +703,7 @@ async function partialDeployment(sourceName, tpl) {
}
if (nameArray.length === 2) {
-
+
const funcRes = definition.findServiceByCertainServiceAndFunctionName(tpl.Resources, _.first(nameArray), _.last(nameArray));
return {
@@ -819,16 +819,9 @@ async function deployByApi(baseDir, tpl, tplPath, context) {
const { Type: resourceType = '' } = resourceRes;
if (resourceType === definition.SERVICE_RESOURCE) {
- await showResourcesChanges({
- Resources: {
- [resourceName]: resourceRes
- }
- }, remoteYml);
+ await showResourcesChanges({ Resources: { [resourceName]: resourceRes } }, remoteYml);
- if (!context.assumeYes
- && !await promptForConfirmContinue('Please confirm to continue.')) {
- return;
- }
+ if (!context.assumeYes && !await promptForConfirmContinue('Please confirm to continue.')) { return; }
await deployTplService({ baseDir, tplPath,
serviceName: resourceName,
@@ -846,10 +839,7 @@ async function deployByApi(baseDir, tpl, tplPath, context) {
await showResourcesChanges(tpl, remoteYml);
- if (!context.assumeYes
- && !await promptForConfirmContinue('Please confirm to continue.')) {
- return;
- }
+ if (!context.assumeYes && !await promptForConfirmContinue('Please confirm to continue.')) { return; }
await deployLogs(tpl.Resources);
diff --git a/src/lib/fc.js b/src/lib/fc.js
index d28e2c0f9..83e198366 100644
--- a/src/lib/fc.js
+++ b/src/lib/fc.js
@@ -23,6 +23,7 @@ const getUuid = require('uuid-by-string');
const { sleep } = require('./time');
const { makeTrigger } = require('./trigger');
const { makeSlsAuto } = require('./deploy/deploy-support');
+const { isNotEmptyDir } = require('./nas/cp/file');
const { updateTimestamps } = require('./utils/file');
const { green, red, yellow } = require('colors');
const { getFcClient, getEcsPopClient, getNasPopClient } = require('./client');
@@ -171,14 +172,19 @@ const CUSTOM_RUNTIME_JAVA_MAPPING = {
'pathSuffix': '*'
};
+const FONTS_MAPPING = {
+ 'localDir': 'fonts',
+ 'remoteDir': 'fonts'
+};
+
const runtimeDependencyMappings = {
- 'nodejs6': [NODE_RUNTIME_MAPPING],
- 'nodejs8': [NODE_RUNTIME_MAPPING],
- 'nodejs10': [NODE_RUNTIME_MAPPING],
- 'python2.7': [PYTHON_RUNTIME_MAPPING],
- 'python3': [PYTHON_RUNTIME_MAPPING],
- 'java8': [JAVA_RUNTIME_MAPPING],
- 'custom': [NODE_RUNTIME_MAPPING, PYTHON_RUNTIME_MAPPING, CUSTOM_RUNTIME_JAVA_MAPPING]
+ 'nodejs6': [NODE_RUNTIME_MAPPING, FONTS_MAPPING],
+ 'nodejs8': [NODE_RUNTIME_MAPPING, FONTS_MAPPING],
+ 'nodejs10': [NODE_RUNTIME_MAPPING, FONTS_MAPPING],
+ 'python2.7': [PYTHON_RUNTIME_MAPPING, FONTS_MAPPING],
+ 'python3': [PYTHON_RUNTIME_MAPPING, FONTS_MAPPING],
+ 'java8': [JAVA_RUNTIME_MAPPING, FONTS_MAPPING],
+ 'custom': [NODE_RUNTIME_MAPPING, PYTHON_RUNTIME_MAPPING, CUSTOM_RUNTIME_JAVA_MAPPING, FONTS_MAPPING]
};
async function saveNasMappings(nasYmlPath, nasMappings) {
@@ -195,9 +201,10 @@ async function saveNasMappings(nasYmlPath, nasMappings) {
return mergedNasMappings;
}
-async function updateEnvironmentsInTpl({ tplPath, tpl, envs,
+function updateEnvironmentsInTpl({ tplPath, tpl, envs,
serviceName,
- functionName
+ functionName,
+ displayLog = true
}) {
const updatedTplContent = _.cloneDeep(tpl);
@@ -215,7 +222,9 @@ async function updateEnvironmentsInTpl({ tplPath, tpl, envs,
util.outputTemplateFile(tplPath, updatedTplContent);
- console.log(green(`Fun add environment variables to '${serviceName}/${functionName}' in ${tplPath}`));
+ if (displayLog) {
+ console.log(green(`Fun add environment variables to '${serviceName}/${functionName}' in ${tplPath}`));
+ }
return updatedTplContent;
}
@@ -347,9 +356,8 @@ async function generateNasMappingsAndEnvs({
remoteNasDir: remoteDir
});
- Object.assign(envs, {
- [mapping.env]: generateNasEnv(mapping.defaultEnv, mapping.pathSuffix ? remoteDir + '/' + mapping.pathSuffix : remoteDir)
- });
+ const resolveNasDir = mapping.pathSuffix ? remoteDir + '/' + mapping.pathSuffix : remoteDir;
+ Object.assign(envs, generateNasEnv(mapping.defaultEnv, resolveNasDir, mapping.env));
outputNasMappingLog(baseDir, nasMappingPath, localDir);
}
@@ -364,15 +372,16 @@ async function generateNasMappingsAndEnvs({
};
}
-function generateNasEnv(defaultEnv, remoteNasDir) {
- let nasEnv;
+function generateNasEnv(defaultEnvValue, remoteNasDir, envKey) {
+ const env = {};
- if (defaultEnv) {
- nasEnv = `${remoteNasDir}:${defaultEnv}`;
- } else {
- nasEnv = remoteNasDir;
+ if (!envKey) {
+ return env;
}
- return nasEnv;
+
+ env[envKey] = defaultEnvValue ? `${remoteNasDir}:${defaultEnvValue}` : remoteNasDir;
+
+ return env;
}
function resolveLocalNasDir(runtime, baseDir, codeUri, localDirInNasMappings, serviceName, functionName) {
@@ -450,7 +459,7 @@ async function processOtherFunctionsUnderServiceIfNecessary({
for (const pendingFuntion of pendingFuntions) {
- tpl = await updateEnvironmentsInTpl({
+ tpl = updateEnvironmentsInTpl({
tplPath, tpl, envs,
serviceName: originServiceName,
functionName: pendingFuntion.functionName
@@ -472,14 +481,15 @@ async function processNasMappingsAndEnvs({ tpl, tplPath, runtime, codeUri, baseD
const { serviceRes } = definition.findFunctionByServiceAndFunctionName(tpl.Resources, serviceName, functionName);
const { envs, nasMappings, remoteNasDirPrefix } = await generateNasMappingsAndEnvs({
- baseDir,
+ baseDir, runtime, codeUri,
serviceName: serviceName,
functionName: functionName,
- runtime,
- codeUri,
nasConfig: convertedNasConfig || (serviceRes.Properties || {}).NasConfig
});
+ const appendContet = `
${remoteNasDirPrefix}${FONTS_MAPPING.remoteDir}`;
+ await generateFontsConfAndEnv(baseDir, codeUri, appendContet);
+
const localDirs = _.map(runtimeDependencyMappings[runtime], mapping => path.join(codeUri, mapping.localDir));
if (_.isEmpty(nasMappings[serviceName])) {
@@ -665,7 +675,6 @@ async function processNasAutoConfiguration({ tpl, tplPath, runtime, codeUri, con
console.log(yellow(`\nFun has automatically uploaded your code dependency to NAS, then fun will use 'fun deploy ${serviceName}/${functionName}' to redeploy.`));
console.log(`Waiting for service ${serviceName} to be deployed...`);
-
const partialDeploy = await require('./deploy/deploy-by-tpl').partialDeployment(`${serviceName}/${functionName}`, updatedTplContent);
if (partialDeploy.resourceName) {
@@ -686,7 +695,7 @@ async function updateEnvironments({
serviceName, functionName
}) {
- const updatedTplContent = await updateEnvironmentsInTpl({ envs, tpl, tplPath, serviceName, functionName });
+ const updatedTplContent = updateEnvironmentsInTpl({ envs, tpl, tplPath, serviceName, functionName });
return await processOtherFunctionsUnderServiceIfNecessary({
tpl: updatedTplContent, tplPath,
@@ -983,6 +992,38 @@ function generateNasAndVpcConfig(mountTarget, securityGroupId, serviceName) {
};
}
+function writeFileToLine(filePath, content, lineNum) {
+ let data = fs.readFileSync(filePath, 'utf8').split(/\r?\n/gm);
+ data.splice(lineNum, 0, content);
+ fs.writeFileSync(filePath, data.join('\n'), {
+ encoding: 'utf8'
+ });
+}
+
+const DEFAULT_FONTS_CONFIG_ENV = {
+ 'FONTCONFIG_FILE': '/code/.fonts.conf'
+};
+
+async function generateFontsConfAndEnv(baseDir, codeUri, appendContet) {
+ const absCodeUri = path.resolve(baseDir, codeUri);
+ const fontsDir = path.join(absCodeUri, 'fonts');
+
+ if (!await fs.pathExists(fontsDir) || !await isNotEmptyDir(fontsDir)) { return {}; }
+
+ const fontsConfPath = path.join(absCodeUri, '.fonts.conf');
+
+ if (!await fs.pathExists(fontsConfPath)) {
+ const sourcePath = path.resolve(__dirname, './utils/fonts/fonts.conf');
+ await fs.copyFile(sourcePath, fontsConfPath);
+ }
+
+ if (appendContet) {
+ writeFileToLine(fontsConfPath, appendContet, 29);
+ }
+
+ return DEFAULT_FONTS_CONFIG_ENV;
+}
+
async function makeFunction(baseDir, {
serviceName,
functionName,
@@ -1021,6 +1062,17 @@ async function makeFunction(baseDir, {
if (codeUri && codeUri.startsWith('oss://')) { // oss://my-bucket/function.zip
code = extractOssCodeUri(codeUri);
} else {
+
+ const fontsConfEnv = await generateFontsConfAndEnv(baseDir, codeUri);
+ if (!_.isEmpty(fontsConfEnv)) {
+
+ updateEnvironmentsInTpl({ serviceName, functionName, tplPath,
+ displayLog: false,
+ tpl: await getTpl(tplPath),
+ envs: DEFAULT_FONTS_CONFIG_ENV
+ });
+ }
+
console.log(`\t\tWaiting for packaging function ${functionName} code...`);
const { base64, count, compressedSize } = await zipCode(baseDir, codeUri, runtime, functionName);
diff --git a/src/lib/nas/cp/file.js b/src/lib/nas/cp/file.js
index 56ff9086a..9dc0dc26f 100644
--- a/src/lib/nas/cp/file.js
+++ b/src/lib/nas/cp/file.js
@@ -54,6 +54,18 @@ async function isEmptyDir(path) {
return false;
}
+// only if the path is directory and there are files in the directory, will true be returned
+async function isNotEmptyDir(path) {
+ const lstat = await fs.lstat(path);
+ if (lstat.isDirectory()) {
+ const dirs = await fs.readdir(path);
+ if (!_.isEmpty(dirs)) {
+ return true;
+ }
+ }
+ return false;
+}
+
async function getFileSize(filePath) {
const stat = await fs.lstat(filePath);
return stat.size;
@@ -91,7 +103,7 @@ function writeBufToFile(dstPath, buf) {
}
module.exports = {
- isDir, isFile, isEmptyDir,
+ isDir, isFile, isEmptyDir, isNotEmptyDir,
getFileHash, getFileSize, getFilePermission,
zipWithArchiver, readFileChunk, writeBufToFile
};
\ No newline at end of file