Skip to content

Commit dbb505a

Browse files
committed
bugfix: catch io.cp error
In ubuntu:22.04 docker man dpkg contains followng: "-L|--listfiles <package>... List files 'owned' by package(s)." dpkg -L cmake mentions file /usr/share/doc/cmake/NEWS.Debian.gz, which is not present in the system after successful apt-get -y install cmake. This led to setup-tarantool failing during packaging cache. This patch catches error while calling io.cp and prints it as a warning.
1 parent 331fadb commit dbb505a

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

src/main.ts

+91
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ interface CaptureOptions {
1616
silent?: boolean
1717
}
1818

19+
interface DpkgConfig {
20+
excludes: RegExp[];
21+
includes: RegExp[];
22+
}
23+
1924
async function capture(cmd: string, options?: CaptureOptions): Promise<string> {
2025
let output = ''
2126

@@ -170,6 +175,90 @@ export async function latest_version(version_prefix: string): Promise<string> {
170175
})
171176
}
172177

178+
function glob_to_regex(glob: string): RegExp {
179+
return new RegExp(glob
180+
.replace(/\./g, '\\.')
181+
.replace(/\*/g, '.*')
182+
.replace(/\?/g, '.')
183+
);
184+
}
185+
186+
function list_files_in_dir(directory: string, files: string[] = []): string[] {
187+
fs.readdirSync(directory).forEach(file => {
188+
const p = path.join(directory, file);
189+
if (fs.statSync(p).isDirectory()) {
190+
return list_files_in_dir(p, files);
191+
} else {
192+
return files.push(p);
193+
}
194+
});
195+
196+
return files;
197+
}
198+
199+
function dpkg_read_config(): DpkgConfig {
200+
const dpkgConfigFilepath = 'excludes';
201+
const dpkgConfigDirPath = 'excludes.d';
202+
203+
const configs = list_files_in_dir(dpkgConfigDirPath, [dpkgConfigFilepath]);
204+
205+
const dpkgConfig: DpkgConfig = {
206+
excludes: [],
207+
includes: [],
208+
};
209+
210+
configs.forEach((config) => {
211+
try {
212+
const dpkgExcludesFile = fs.readFileSync(config, 'utf8');
213+
dpkgExcludesFile.split('\n').forEach((line) => {
214+
// Exclude
215+
const excludePattern = 'path-exclude=';
216+
if (line.startsWith(excludePattern)) {
217+
const regex = glob_to_regex(line.substring(excludePattern.length));
218+
dpkgConfig.excludes.push(regex);
219+
return;
220+
}
221+
222+
// Include
223+
const includePattern = 'path-include=';
224+
if (line.startsWith(includePattern)) {
225+
const regex = glob_to_regex(line.substring(includePattern.length));
226+
dpkgConfig.includes.push(regex);
227+
return;
228+
}
229+
});
230+
} catch (err) {
231+
core.info(`dpkg excludes file not available: ${err}`);
232+
}
233+
});
234+
235+
return dpkgConfig;
236+
}
237+
238+
function dpkg_is_file_included(dpkgConfig: DpkgConfig, filepath: string): boolean {
239+
var included = true;
240+
241+
dpkgConfig.excludes.forEach((exclude) => {
242+
if (exclude.test(filepath)) {
243+
included = false;
244+
return;
245+
}
246+
});
247+
248+
if (included) {
249+
return true;
250+
}
251+
252+
dpkgConfig.includes.forEach((include) => {
253+
if (include.test(filepath)) {
254+
included = true;
255+
return;
256+
}
257+
});
258+
259+
return included;
260+
};
261+
173262
async function run_linux(): Promise<void> {
174263
try {
175264
const distro = await lsb_release()
@@ -234,10 +323,12 @@ async function run_linux(): Promise<void> {
234323
core.info('Caching APT packages: ' + dpkg_diff.join(', '))
235324

236325
for (const pkg of dpkg_diff) {
326+
const dpkgConfig = dpkg_read_config();
237327
const output = await capture(`sudo dpkg -L ${pkg}`, {silent: true})
238328
const files: Array<string> = output
239329
.split('\n')
240330
.filter(f => fs.statSync(f).isFile())
331+
.filter(f => dpkg_is_file_included(dpkgConfig, f))
241332
for (const f of files) {
242333
const dest = path.join(cache_dir, path.dirname(f))
243334
await io.mkdirP(dest)

0 commit comments

Comments
 (0)