mirror of https://github.com/aminya/setup-cpp
Merge pull request #38 from aminya/dot [skip ci]
This commit is contained in:
commit
e2d3378c89
|
@ -17,7 +17,10 @@ jobs:
|
||||||
os:
|
os:
|
||||||
- windows-2022
|
- windows-2022
|
||||||
- windows-2019
|
- windows-2019
|
||||||
|
- windows-2016
|
||||||
- ubuntu-20.04
|
- ubuntu-20.04
|
||||||
|
- ubuntu-18.04
|
||||||
|
- macos-11
|
||||||
- macos-10.15
|
- macos-10.15
|
||||||
node:
|
node:
|
||||||
- 14 # installed on the images
|
- 14 # installed on the images
|
||||||
|
@ -56,10 +59,12 @@ jobs:
|
||||||
|
|
||||||
# Create self-contained executable that bundles Nodejs
|
# Create self-contained executable that bundles Nodejs
|
||||||
- name: Create Executable
|
- name: Create Executable
|
||||||
|
if: "contains(matrix.os, 'windows-2022') || contains(matrix.os, 'ubuntu-20.04') || contains(matrix.os, 'macos-11')"
|
||||||
run: |
|
run: |
|
||||||
pnpm run pack.exe
|
pnpm run pack.exe
|
||||||
|
|
||||||
- name: Upload Executable
|
- name: Upload Executable
|
||||||
|
if: "contains(matrix.os, 'windows-2022') || contains(matrix.os, 'ubuntu-20.04') || contains(matrix.os, 'macos-11')"
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -74,6 +79,7 @@ jobs:
|
||||||
if: "!contains(github.event.head_commit.message, '[skip ci test]')"
|
if: "!contains(github.event.head_commit.message, '[skip ci test]')"
|
||||||
run: |
|
run: |
|
||||||
pnpm run test
|
pnpm run test
|
||||||
|
continue-on-error: ${{ contains(matrix.os, 'ubuntu-18.04') }}
|
||||||
|
|
||||||
Docker:
|
Docker:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
|
@ -40,6 +40,7 @@ The package can be used locally or from CI services like GitHub Actions.
|
||||||
- choco
|
- choco
|
||||||
- brew
|
- brew
|
||||||
- sevenzip
|
- sevenzip
|
||||||
|
- graphviz
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
|
@ -133,15 +134,15 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
- windows-2019
|
- windows-2022
|
||||||
- ubuntu-20.04
|
- ubuntu-20.04
|
||||||
- macos-10.15
|
- macos-11
|
||||||
compiler:
|
compiler:
|
||||||
- llvm
|
- llvm
|
||||||
- gcc
|
- gcc
|
||||||
# you can specify the version after `-` like `llvm-13.0.0`.
|
# you can specify the version after `-` like `llvm-13.0.0`.
|
||||||
include:
|
include:
|
||||||
- os: "windows-latest"
|
- os: "windows-2022"
|
||||||
compiler: "msvc"
|
compiler: "msvc"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
|
@ -54,6 +54,9 @@ inputs:
|
||||||
doxygen:
|
doxygen:
|
||||||
description: "The doxygen version to install."
|
description: "The doxygen version to install."
|
||||||
required: false
|
required: false
|
||||||
|
graphviz:
|
||||||
|
description: "The graphviz version to install."
|
||||||
|
required: false
|
||||||
cppcheck:
|
cppcheck:
|
||||||
description: "The cppcheck version to install."
|
description: "The cppcheck version to install."
|
||||||
required: false
|
required: false
|
||||||
|
|
|
@ -6,9 +6,9 @@ ADD "./dist/" "/"
|
||||||
WORKDIR "/"
|
WORKDIR "/"
|
||||||
|
|
||||||
# run installation
|
# run installation
|
||||||
RUN node ./setup_cpp.js --compiler llvm --cmake true --ninja true --ccache true --vcpkg true
|
RUN node ./setup_cpp.js --compiler llvm --cmake true --ninja true --cppcheck true --ccache true --vcpkg true --doxygen true --gcovr true
|
||||||
|
|
||||||
# reload the environment
|
# reload the environment and print the versions
|
||||||
CMD source ~/.profile
|
CMD source ~/.profile && clang --version && cmake --version && ninja --version && ccache --version && cppcheck --version && vcpkg --version && doxygen --version && dot --version && gcovr --version
|
||||||
|
|
||||||
ENTRYPOINT [ "/bin/sh" ]
|
ENTRYPOINT [ "/bin/sh" ]
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -15,7 +15,7 @@
|
||||||
"build": "cross-env NODE_ENV=production parcel build --detailed-report && npm run copy.matchers",
|
"build": "cross-env NODE_ENV=production parcel build --detailed-report && npm run copy.matchers",
|
||||||
"build.docker": "pnpm build && docker build -f ./building/docker/debian_node.dockerfile -t setup_cpp .",
|
"build.docker": "pnpm build && docker build -f ./building/docker/debian_node.dockerfile -t setup_cpp .",
|
||||||
"bump": "ncu -u -x execa",
|
"bump": "ncu -u -x execa",
|
||||||
"clean": "shx rm -rf dist exe",
|
"clean": "shx rm -rf .parcel-cache dist exe",
|
||||||
"copy.matchers": "shx cp ./src/gcc/gcc_matcher.json ./dist/ && shx cp ./src/msvc/msvc_matcher.json ./dist && shx cp ./src/python/python_matcher.json ./dist/ && shx cp ./src/llvm/llvm_matcher.json ./dist/ ",
|
"copy.matchers": "shx cp ./src/gcc/gcc_matcher.json ./dist/ && shx cp ./src/msvc/msvc_matcher.json ./dist && shx cp ./src/python/python_matcher.json ./dist/ && shx cp ./src/llvm/llvm_matcher.json ./dist/ ",
|
||||||
"dev": "cross-env NODE_ENV=development parcel watch",
|
"dev": "cross-env NODE_ENV=development parcel watch",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { setupPipPack } from "../utils/setup/setupPipPack"
|
import { setupPipPack } from "../utils/setup/setupPipPack"
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
export function setupConan(version: string | undefined, _setupDir: string, _arch: string) {
|
export async function setupConan(version: string | undefined, _setupDir: string, _arch: string) {
|
||||||
|
await setupPipPack("setuptools", "")
|
||||||
return setupPipPack("conan", version)
|
return setupPipPack("conan", version)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { setupDoxygen } from "../doxygen"
|
||||||
import { cleanupTmpDir, setupTmpDir, testBin } from "../../utils/tests/test-helpers"
|
import { cleanupTmpDir, setupTmpDir, testBin } from "../../utils/tests/test-helpers"
|
||||||
import { InstallationInfo } from "../../utils/setup/setupBin"
|
import { InstallationInfo } from "../../utils/setup/setupBin"
|
||||||
import { getVersion } from "../../default_versions"
|
import { getVersion } from "../../default_versions"
|
||||||
|
import which from "which"
|
||||||
|
|
||||||
jest.setTimeout(300000)
|
jest.setTimeout(300000)
|
||||||
describe("setup-doxygen", () => {
|
describe("setup-doxygen", () => {
|
||||||
|
@ -10,10 +11,12 @@ describe("setup-doxygen", () => {
|
||||||
directory = await setupTmpDir("doxygen")
|
directory = await setupTmpDir("doxygen")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should setup doxygen", async () => {
|
it("should setup doxygen and dot", async () => {
|
||||||
const installInfo = await setupDoxygen(getVersion("doxygen", undefined), directory, process.arch)
|
const installInfo = await setupDoxygen(getVersion("doxygen", undefined), directory, process.arch)
|
||||||
|
|
||||||
await testBin("doxygen", ["--version"], (installInfo as InstallationInfo | undefined)?.binDir)
|
await testBin("doxygen", ["--version"], (installInfo as InstallationInfo | undefined)?.binDir)
|
||||||
|
|
||||||
|
expect(which.sync("dot")).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { setupChocoPack } from "../utils/setup/setupChocoPack"
|
||||||
import { addBinExtension } from "../utils/extension/extension"
|
import { addBinExtension } from "../utils/extension/extension"
|
||||||
import { extractTar } from "../utils/setup/extract"
|
import { extractTar } from "../utils/setup/extract"
|
||||||
import { warning } from "../utils/io/io"
|
import { warning } from "../utils/io/io"
|
||||||
|
import { setupGraphviz } from "../graphviz/graphviz"
|
||||||
|
import { getVersion } from "../default_versions"
|
||||||
|
|
||||||
/** Get the platform data for cmake */
|
/** Get the platform data for cmake */
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
@ -30,17 +32,13 @@ export async function setupDoxygen(version: string, setupDir: string, arch: stri
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case "win32": {
|
case "win32": {
|
||||||
await setupChocoPack("doxygen.install", version)
|
await setupChocoPack("doxygen.install", version)
|
||||||
try {
|
await setupGraphviz(getVersion("graphviz", undefined), "", arch)
|
||||||
await setupChocoPack("graphviz", undefined)
|
|
||||||
} catch (err) {
|
|
||||||
warning(`${err}`)
|
|
||||||
}
|
|
||||||
const binDir = activateWinDoxygen()
|
const binDir = activateWinDoxygen()
|
||||||
return { binDir }
|
return { binDir }
|
||||||
}
|
}
|
||||||
case "darwin": {
|
case "darwin": {
|
||||||
const installationInfo = setupBrewPack("doxygen", undefined)
|
const installationInfo = setupBrewPack("doxygen", undefined)
|
||||||
setupBrewPack("graphviz", undefined)
|
await setupGraphviz(getVersion("graphviz", undefined), "", arch)
|
||||||
return installationInfo
|
return installationInfo
|
||||||
}
|
}
|
||||||
case "linux": {
|
case "linux": {
|
||||||
|
@ -52,7 +50,7 @@ export async function setupDoxygen(version: string, setupDir: string, arch: stri
|
||||||
warning(`Failed to download doxygen binary. ${err}. Falling back to apt-get.`)
|
warning(`Failed to download doxygen binary. ${err}. Falling back to apt-get.`)
|
||||||
installationInfo = await setupAptPack("doxygen", undefined)
|
installationInfo = await setupAptPack("doxygen", undefined)
|
||||||
}
|
}
|
||||||
await setupAptPack("graphviz", undefined)
|
await setupGraphviz(getVersion("graphviz", undefined), "", arch)
|
||||||
return installationInfo
|
return installationInfo
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -62,8 +60,14 @@ export async function setupDoxygen(version: string, setupDir: string, arch: stri
|
||||||
}
|
}
|
||||||
|
|
||||||
function activateWinDoxygen() {
|
function activateWinDoxygen() {
|
||||||
addPath("C:/Program Files/Graphviz/bin")
|
switch (process.platform) {
|
||||||
|
case "win32": {
|
||||||
const binDir = "C:/Program Files/doxygen/bin"
|
const binDir = "C:/Program Files/doxygen/bin"
|
||||||
addPath(binDir)
|
addPath(binDir)
|
||||||
return binDir
|
return binDir
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error(`Unsupported platform`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { setupGraphviz } from "../graphviz"
|
||||||
|
import { cleanupTmpDir, setupTmpDir, testBin } from "../../utils/tests/test-helpers"
|
||||||
|
import { InstallationInfo } from "../../utils/setup/setupBin"
|
||||||
|
import { getVersion } from "../../default_versions"
|
||||||
|
|
||||||
|
jest.setTimeout(300000)
|
||||||
|
describe("setup-graphviz", () => {
|
||||||
|
let directory: string
|
||||||
|
beforeAll(async () => {
|
||||||
|
directory = await setupTmpDir("graphviz")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should setup graphviz", async () => {
|
||||||
|
const installInfo = await setupGraphviz(getVersion("graphviz", undefined), directory, process.arch)
|
||||||
|
|
||||||
|
await testBin("dot", ["-V"], (installInfo as InstallationInfo | undefined)?.binDir)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await cleanupTmpDir("graphviz")
|
||||||
|
}, 100000)
|
||||||
|
})
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { addPath } from "../utils/path/addPath"
|
||||||
|
import { setupAptPack } from "../utils/setup/setupAptPack"
|
||||||
|
import { InstallationInfo } from "../utils/setup/setupBin"
|
||||||
|
import { setupBrewPack } from "../utils/setup/setupBrewPack"
|
||||||
|
import { setupChocoPack } from "../utils/setup/setupChocoPack"
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
export function setupGraphviz(version: string, _setupDir: string, _arch: string) {
|
||||||
|
switch (process.platform) {
|
||||||
|
case "win32": {
|
||||||
|
setupChocoPack("graphviz", version)
|
||||||
|
return activateGraphviz()
|
||||||
|
}
|
||||||
|
case "darwin": {
|
||||||
|
return setupBrewPack("graphviz", version)
|
||||||
|
}
|
||||||
|
case "linux": {
|
||||||
|
return setupAptPack("graphviz", version)
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error(`Unsupported platform`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function activateGraphviz(): InstallationInfo {
|
||||||
|
switch (process.platform) {
|
||||||
|
case "win32": {
|
||||||
|
const binDir = "C:/Program Files/Graphviz/bin"
|
||||||
|
addPath(binDir)
|
||||||
|
return { binDir }
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error(`Unsupported platform`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,6 +47,7 @@ export async function setupKcov(version: string, setupDir: string, arch: string)
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case "linux": {
|
case "linux": {
|
||||||
const installationInfo = await setupBin("kcov", version, getKcovPackageInfo, setupDir, arch)
|
const installationInfo = await setupBin("kcov", version, getKcovPackageInfo, setupDir, arch)
|
||||||
|
await setupAptPack("libbinutils")
|
||||||
return installationInfo
|
return installationInfo
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -244,17 +244,27 @@ async function getLLVMPackageInfo(version: string, platform: NodeJS.Platform, _a
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setupLLVM(version: string, setupDir: string, arch: string): Promise<InstallationInfo> {
|
export async function setupLLVM(version: string, setupDir: string, arch: string): Promise<InstallationInfo> {
|
||||||
const installationInfo = await setupBin("llvm", version, getLLVMPackageInfo, setupDir, arch)
|
const installationInfo = await _setupLLVM(version, setupDir, arch)
|
||||||
await activateLLVM(installationInfo.installDir ?? setupDir, version)
|
await activateLLVM(installationInfo.installDir ?? setupDir, version)
|
||||||
return installationInfo
|
return installationInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function activateLLVM(directory: string, versionGiven: string) {
|
let didInit = false
|
||||||
|
async function _setupLLVM(version: string, setupDir: string, arch: string) {
|
||||||
|
const installationInfo = await setupBin("llvm", version, getLLVMPackageInfo, setupDir, arch)
|
||||||
|
if (!didInit) {
|
||||||
if (process.platform === "linux") {
|
if (process.platform === "linux") {
|
||||||
// install llvm build dependencies
|
// install llvm build dependencies
|
||||||
await setupAptPack("build-essential") // TODO(question) llvm needs ld. But does it need all the build-essential?
|
await setupAptPack("build-essential") // TODO(question) llvm needs ld. But does it need all the build-essential?
|
||||||
|
await setupAptPack("libtinfo-dev")
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line require-atomic-updates
|
||||||
|
didInit = true
|
||||||
|
}
|
||||||
|
return installationInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function activateLLVM(directory: string, versionGiven: string) {
|
||||||
const version = semverCoerceIfInvalid(versionGiven)
|
const version = semverCoerceIfInvalid(versionGiven)
|
||||||
|
|
||||||
const lib = path.join(directory, "lib")
|
const lib = path.join(directory, "lib")
|
||||||
|
@ -295,7 +305,7 @@ export function setupClangTools(version: string, setupDir: string, arch: string)
|
||||||
if (isGitHubCI()) {
|
if (isGitHubCI()) {
|
||||||
addLLVMLoggingMatcher()
|
addLLVMLoggingMatcher()
|
||||||
}
|
}
|
||||||
return setupBin("llvm", version, getLLVMPackageInfo, setupDir, arch)
|
return _setupLLVM(version, setupDir, arch)
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLLVMLoggingMatcher() {
|
function addLLVMLoggingMatcher() {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import { setupKcov } from "./kcov/kcov"
|
||||||
import { addEnv } from "./utils/env/addEnv"
|
import { addEnv } from "./utils/env/addEnv"
|
||||||
import { setupSevenZip } from "./sevenzip/sevenzip"
|
import { setupSevenZip } from "./sevenzip/sevenzip"
|
||||||
import { endGroup, startGroup } from "@actions/core"
|
import { endGroup, startGroup } from "@actions/core"
|
||||||
|
import { setupGraphviz } from "./graphviz/graphviz"
|
||||||
|
|
||||||
/** The setup functions */
|
/** The setup functions */
|
||||||
const setups = {
|
const setups = {
|
||||||
|
@ -48,6 +49,7 @@ const setups = {
|
||||||
brew: setupBrew,
|
brew: setupBrew,
|
||||||
ccache: setupCcache,
|
ccache: setupCcache,
|
||||||
doxygen: setupDoxygen,
|
doxygen: setupDoxygen,
|
||||||
|
graphviz: setupGraphviz,
|
||||||
cppcheck: setupCppcheck,
|
cppcheck: setupCppcheck,
|
||||||
clangtidy: setupClangTools,
|
clangtidy: setupClangTools,
|
||||||
clangformat: setupClangTools,
|
clangformat: setupClangTools,
|
||||||
|
@ -73,6 +75,7 @@ const tools: Array<keyof typeof setups> = [
|
||||||
"opencppcoverage",
|
"opencppcoverage",
|
||||||
"ccache",
|
"ccache",
|
||||||
"doxygen",
|
"doxygen",
|
||||||
|
"graphviz",
|
||||||
"cppcheck",
|
"cppcheck",
|
||||||
"clangtidy",
|
"clangtidy",
|
||||||
"clangformat",
|
"clangformat",
|
||||||
|
@ -304,6 +307,7 @@ All the available tools:
|
||||||
--choco
|
--choco
|
||||||
--brew
|
--brew
|
||||||
--sevenzip
|
--sevenzip
|
||||||
|
--graphviz
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ export type InstallationInfo = {
|
||||||
binDir: string
|
binDir: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let didInit: boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function that:
|
* A function that:
|
||||||
*
|
*
|
||||||
|
@ -83,12 +85,16 @@ export async function setupBin(
|
||||||
if (!existsSync(binDir) || !existsSync(binFile)) {
|
if (!existsSync(binDir) || !existsSync(binFile)) {
|
||||||
info(`Download and extract ${name} ${version}`)
|
info(`Download and extract ${name} ${version}`)
|
||||||
|
|
||||||
|
if (!didInit) {
|
||||||
if (process.platform === "linux") {
|
if (process.platform === "linux") {
|
||||||
// extraction dependencies
|
// extraction dependencies
|
||||||
await setupAptPack("unzip")
|
await setupAptPack("unzip")
|
||||||
await setupAptPack("tar")
|
await setupAptPack("tar")
|
||||||
await setupAptPack("xz-utils")
|
await setupAptPack("xz-utils")
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line require-atomic-updates
|
||||||
|
didInit = true
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const downloaded = await downloadTool(url)
|
const downloaded = await downloadTool(url)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { isBinUptoDate } from "./version"
|
||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
import { getVersion } from "../../default_versions"
|
import { getVersion } from "../../default_versions"
|
||||||
import { InstallationInfo } from "./setupBin"
|
import { InstallationInfo } from "./setupBin"
|
||||||
|
import { setupAptPack } from "./setupAptPack"
|
||||||
|
|
||||||
let python: string | undefined
|
let python: string | undefined
|
||||||
let binDir: string | undefined
|
let binDir: string | undefined
|
||||||
|
@ -35,10 +36,14 @@ export async function setupPipPack(name: string, version?: string): Promise<Inst
|
||||||
tried = true
|
tried = true
|
||||||
return setupPipPack(name, version)
|
return setupPipPack(name, version)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
|
// downgrade pip on Windows
|
||||||
// https://github.com/pypa/pip/issues/10875#issuecomment-1030293005
|
// https://github.com/pypa/pip/issues/10875#issuecomment-1030293005
|
||||||
execa.sync(python, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
|
execa.sync(python, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
|
||||||
|
} else if (process.platform === "linux") {
|
||||||
|
// ensure that pip is installed on Linux (happens when python is found but pip not installed)
|
||||||
|
await setupAptPack("python3-pip")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
execa.sync(python, ["-m", "pip", "install", version !== undefined && version !== "" ? `${name}==${version}` : name], {
|
execa.sync(python, ["-m", "pip", "install", version !== undefined && version !== "" ? `${name}==${version}` : name], {
|
||||||
|
|
Loading…
Reference in New Issue