diff --git a/dist/index.js b/dist/index.js index 0492fcf..61d1141 100644 --- a/dist/index.js +++ b/dist/index.js @@ -44765,6 +44765,176 @@ class Keyv extends EventEmitter { module.exports = Keyv; +/***/ }), + +/***/ 8811: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +const fs = __nccwpck_require__(7147) +const os = __nccwpck_require__(2037) + +/** + * Get OS release info from the node os module and augment that with information + * from '/etc/os-release', '/usr/lib/os-release', or '/etc/alpine-release'. The + * information in that file is distribution-dependent. If not Linux return only + * the node os module info. + * + * @returns info {object} via Promise | callback | return value + * + * the file property in the info object will be filled in with one of: + * - undefined, if not Linux + * - the file path (above) used + * - an Error instance if no file could be read + */ +function linuxOsInfo (opts) { + let outputData = { + type: os.type(), + platform: os.platform(), + hostname: os.hostname(), + arch: os.arch(), + release: os.release(), + file: undefined, + } + + let mode = 'promise' + opts = opts || {} + + + + const list = Array.isArray(opts.list) ? opts.list : defaultList + + if (typeof opts.mode === 'function') { + mode = 'callback' + } else if (opts.mode === 'sync') { + mode = 'sync' + } + + if (os.type() !== 'Linux') { + if (mode === 'promise') { + return Promise.resolve(outputData) + } else if (mode === 'callback') { + return opts.mode(null, outputData) + } else { + return outputData + } + } + + if (mode === 'sync') { + return synchronousRead() + } else { + // return a Promise that can be ignored if caller expects a callback + return new Promise(asynchronousRead) + } + + // loop through the file list synchronously + function synchronousRead () { + for (let i = 0; i < list.length; i++) { + let data + try { + data = fs.readFileSync(list[i].path, 'utf8') + list[i].parser(data, outputData) + outputData.file = list[i].path + return outputData + } catch (e) { + // accumulate errors? + } + } + outputData.file = new Error('linux-os-info - no file found') + return outputData + } + + // loop through the file list on completion of async reads + function asynchronousRead (resolve, reject) { + let i = 0 + + function tryRead () { + if (i >= list.length) { + const e = new Error('linux-os-info - no file found') + outputData.file = e + mode === 'promise' ? resolve(outputData) : opts.mode(null, outputData) + } else { + // try to read the file. + let file = list[i].path + fs.readFile(file, 'utf8', (err, data) => { + if (err) { + i += 1 + tryRead() + } else { + list[i].parser(data, outputData) + outputData.file = file + mode === 'promise' ? resolve(outputData) : opts.mode(null, outputData) + } + }) + } + } + + tryRead() + } +} + +// +// the default list of files to try to read and their parsers. +// in theory this can be replaced, especially for testing purposes. +// but it's not documented at this time unless one is reading this. +// +const defaultList = [ + {path: '/etc/os-release', parser: etcOsRelease}, + {path: '/usr/lib/os-release', parser: usrLibOsRelease}, + {path: '/etc/alpine-release', parser: etcAlpineRelease} +] + +// +// helper functions to parse file data +// + +function etcOsRelease(data, outputData) { + addOsReleaseToOutputData(data, outputData) +} + +function usrLibOsRelease(data, outputData) { + addOsReleaseToOutputData(data, outputData) +} + +// the alpine-release file only contains the version string +// so fill in the basics based on that. +function etcAlpineRelease(data, outputData) { + outputData.name = 'Alpine' + outputData.id = 'alpine' + outputData.version = data + outputData.version_id = data +} + +function addOsReleaseToOutputData(data, outputData) { + const lines = data.split('\n') + + lines.forEach(line => { + let index = line.indexOf('=') + // only look at lines with at least a one character key + if (index >= 1) { + // lowercase key and remove quotes on value + let key = line.slice(0, index).toLowerCase() + let value = line.slice(index + 1).replace(/"/g, '') + + Object.defineProperty(outputData, key, { + value: value, + writable: true, + enumerable: true, + configurable: true + }) + } + }); +} + +module.exports = linuxOsInfo + +// +// a tiny bit of testing +// +if (false) {} + + /***/ }), /***/ 4015: @@ -95129,11 +95299,14 @@ function mungeDiagnosticEndpoint(inputUrl) { var external_os_ = __nccwpck_require__(2037); // EXTERNAL MODULE: ./node_modules/.pnpm/@actions+exec@1.1.1/node_modules/@actions/exec/lib/exec.js var exec = __nccwpck_require__(7775); +// EXTERNAL MODULE: ./node_modules/.pnpm/linux-os-info@2.0.0/node_modules/linux-os-info/index.js +var linux_os_info = __nccwpck_require__(8811); ;// CONCATENATED MODULE: ./dist/platform.js // MIT, lifted from https://github.com/actions/toolkit/blob/5a736647a123ecf8582376bdaee833fbae5b3847/packages/core/src/platform.ts // since it isn't in @actions/core 1.10.1 which is their current release as 2024-04-19 + const getWindowsInfo = async () => { const { stdout: version } = await exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, { silent: true, @@ -95158,6 +95331,9 @@ const getMacOsInfo = async () => { }; }; const getLinuxInfo = async () => { + const data = await linux_os_info({ mode: "async" }); + // eslint-disable-next-line no-console + console.log(data); const { stdout } = await exec.getExecOutput("lsb_release", ["-i", "-r", "-s"], { silent: true, }); diff --git a/dist/platform.js b/dist/platform.js index 4c3c322..446b6f8 100644 --- a/dist/platform.js +++ b/dist/platform.js @@ -2,6 +2,7 @@ // since it isn't in @actions/core 1.10.1 which is their current release as 2024-04-19 import os from "os"; import * as exec from "@actions/exec"; +import osInfo from "linux-os-info"; const getWindowsInfo = async () => { const { stdout: version } = await exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, { silent: true, @@ -26,6 +27,9 @@ const getMacOsInfo = async () => { }; }; const getLinuxInfo = async () => { + const data = await osInfo({ mode: "async" }); + // eslint-disable-next-line no-console + console.log(data); const { stdout } = await exec.getExecOutput("lsb_release", ["-i", "-r", "-s"], { silent: true, }); diff --git a/package.json b/package.json index c602600..168c4fd 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "detsys-ts": "github:DeterminateSystems/detsys-ts", "fetch-retry": "^5.0.6", "got": "^14.2.1", + "linux-os-info": "^2.0.0", "string-argv": "^0.3.2", "tail": "^2.2.6" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89a9ef1..8c97df7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ dependencies: got: specifier: ^14.2.1 version: 14.2.1 + linux-os-info: + specifier: ^2.0.0 + version: 2.0.0 string-argv: specifier: ^0.3.2 version: 0.3.2 @@ -3342,6 +3345,13 @@ packages: type-check: 0.4.0 dev: true + /linux-os-info@2.0.0: + resolution: + { + integrity: sha512-ZopyH4kT2Ehnmix8iUgS/41pfv7fSlUV1JukIn3DB3qD3byvhBNtgCbUApoAtiqcHRLKXCY3zakXlJgiExm2Qg==, + } + dev: false + /locate-path@6.0.0: resolution: { diff --git a/src/linus-os-info.d.ts b/src/linus-os-info.d.ts new file mode 100644 index 0000000..cd8b572 --- /dev/null +++ b/src/linus-os-info.d.ts @@ -0,0 +1 @@ +declare module "linux-os-info"; diff --git a/src/platform.ts b/src/platform.ts index b04befc..0c52aae 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -3,6 +3,7 @@ import os from "os"; import * as exec from "@actions/exec"; +import osInfo from "linux-os-info"; const getWindowsInfo = async (): Promise<{ name: string; version: string }> => { const { stdout: version } = await exec.getExecOutput( @@ -48,6 +49,10 @@ const getLinuxInfo = async (): Promise<{ name: string; version: string; }> => { + const data = await osInfo({ mode: "async" }); + // eslint-disable-next-line no-console + console.log(data); + const { stdout } = await exec.getExecOutput( "lsb_release", ["-i", "-r", "-s"],