balena-cli
Version:
The official balena Command Line Interface
140 lines • 5.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDockerIgnoreInstance = getDockerIgnoreInstance;
exports.filterFilesWithDockerignore = filterFilesWithDockerignore;
exports.getDockerignoreByService = getDockerignoreByService;
const _ = require("lodash");
const fs_1 = require("fs");
const path = require("path");
const errors_1 = require("../errors");
async function listFiles(projectDir) {
const files = [];
async function walk(currentDirs) {
if (!currentDirs.length) {
return files;
}
const foundDirs = [];
const chunks = _.chunk(currentDirs, 100);
for (const chunk of chunks) {
await Promise.all(chunk.map(async (dir) => {
const _files = await fs_1.promises.readdir(dir, { withFileTypes: true });
for (const entry of _files) {
const fpath = path.join(dir, entry.name);
const isDirectory = entry.isDirectory() ||
(entry.isSymbolicLink() && (await fs_1.promises.stat(fpath)).isDirectory());
if (isDirectory) {
foundDirs.push(fpath);
}
else {
files.push(fpath);
}
}
}));
}
return walk(foundDirs);
}
return walk([projectDir]);
}
async function readDockerIgnoreFile(projectDir) {
const dockerIgnorePath = path.join(projectDir, '.dockerignore');
let dockerIgnoreStr = '';
try {
dockerIgnoreStr = await fs_1.promises.readFile(dockerIgnorePath, 'utf8');
}
catch (err) {
if (err.code !== 'ENOENT') {
throw new errors_1.ExpectedError(`Error reading file "${dockerIgnorePath}": ${err.message}`);
}
}
return dockerIgnoreStr;
}
async function getDockerIgnoreInstance(directory) {
const dockerIgnoreStr = await readDockerIgnoreFile(directory);
const $dockerIgnore = (await Promise.resolve().then(() => require('@balena/dockerignore'))).default;
const ig = $dockerIgnore({ ignorecase: false });
ig.add(['**/.git']);
if (dockerIgnoreStr) {
ig.add(dockerIgnoreStr);
}
ig.add([
'!**/.balena',
'!**/.resin',
'!**/Dockerfile',
'!**/Dockerfile.*',
'!**/docker-compose.yml',
]);
return ig;
}
async function filterFilesWithDockerignore(projectDir, multiDockerignore, serviceDirsByService) {
projectDir = path.resolve(projectDir);
const root = '.' + path.sep;
const ignoreByService = await getDockerignoreByService(projectDir, multiDockerignore, serviceDirsByService);
const ignoreByDir = {};
for (let [serviceName, dir] of Object.entries(serviceDirsByService)) {
dir = path.normalize(dir);
dir = dir.endsWith(path.sep) ? dir : dir + path.sep;
ignoreByDir[dir] = ignoreByService[serviceName];
}
if (!ignoreByDir[root]) {
ignoreByDir[root] = await getDockerIgnoreInstance(projectDir);
}
const dockerignoreServiceDirs = multiDockerignore
? Object.keys(ignoreByDir).filter((dir) => dir && dir !== root)
: [];
const files = await listFiles(projectDir);
const dockerignoreFiles = [];
const filteredFileList = [];
const chunks = _.chunk(files, 750);
for (const chunk of chunks) {
await Promise.all(chunk.map(async (filePath) => {
const relPath = path.relative(projectDir, filePath);
if (path.basename(relPath) === '.dockerignore') {
const diStats = await fs_1.promises.stat(filePath);
dockerignoreFiles.push({
filePath,
relPath,
stats: diStats,
});
}
const matchingDir = dockerignoreServiceDirs.find((dir) => {
return relPath.startsWith(dir);
});
if (matchingDir) {
if (ignoreByDir[matchingDir].ignores(relPath.substring(matchingDir.length))) {
return;
}
}
else if (ignoreByDir[root].ignores(relPath)) {
return;
}
const stats = await fs_1.promises.stat(filePath);
if (stats.isFile()) {
filteredFileList.push({
filePath,
relPath,
stats,
});
}
}));
}
return { filteredFileList, dockerignoreFiles };
}
let dockerignoreByService = null;
async function getDockerignoreByService(projectDir, multiDockerignore, serviceDirsByService) {
if (dockerignoreByService) {
return dockerignoreByService;
}
const cachedDirs = {};
projectDir = path.resolve(projectDir);
dockerignoreByService = {};
for (let [serviceName, dir] of Object.entries(serviceDirsByService)) {
dir = multiDockerignore ? dir : '.';
const absDir = path.resolve(projectDir, dir);
if (!cachedDirs[absDir]) {
cachedDirs[absDir] = await getDockerIgnoreInstance(absDir);
}
dockerignoreByService[serviceName] = cachedDirs[absDir];
}
return dockerignoreByService;
}
//# sourceMappingURL=ignore.js.map