Skip to content

Commit

Permalink
Merge pull request #294 from aminya/cmakelang [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
aminya authored Sep 19, 2024
2 parents d7f5466 + c9bc540 commit fb2a9a2
Show file tree
Hide file tree
Showing 16 changed files with 324 additions and 80 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Setting up a **cross-platform** environment for building and testing C++/C proje
| category | tools |
| --------------------- | --------------------------------------------------------------------------- |
| compiler and analyzer | llvm, gcc, msvc, apple-clang, vcvarsall, cppcheck, clang-tidy, clang-format |
| build system | cmake, ninja, meson, make, task, bazel |
| build system | cmake, ninja, meson, make, task, bazel, cmakelang, cmake-format, cmake-lint |
| package manager | vcpkg, conan, choco, brew, nala |
| cache | ccache, sccache |
| documentation | doxygen, graphviz |
Expand Down
15 changes: 15 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@ inputs:
cmake:
description: "Wether to install cmake (true/false) or the specific version to install."
required: false
cmakelang:
description: "Wether to install cmakelang (true/false) or the specific version to install."
required: false
cmake-lint:
description: "Wether to install cmake-lint (true/false) or the specific version to install."
required: false
cmakelint:
description: "Wether to install cmake-lint (true/false) or the specific version to install."
required: false
cmake-format:
description: "Wether to install cmake-format (true/false) or the specific version to install."
required: false
cmakeformat:
description: "Wether to install cmake-format (true/false) or the specific version to install."
required: false
ninja:
description: "Wether to install ninja (true/false) or the specific version to install."
required: false
Expand Down
1 change: 1 addition & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ words:
- choco
- clangd
- cmake
- cmakeformat
- cobertura
- copr
- CPATH
Expand Down
2 changes: 1 addition & 1 deletion dist/legacy/setup-cpp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/legacy/setup-cpp.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/modern/setup-cpp.mjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/modern/setup-cpp.mjs.map

Large diffs are not rendered by default.

85 changes: 45 additions & 40 deletions packages/setup-apt/src/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,55 +68,60 @@ const retryErrors = [
* ```
*/
export async function installAptPack(packages: AptPackage[], update = false): Promise<InstallationInfo> {
const apt: string = getApt()

for (const { name, version } of packages) {
info(`Installing ${name} ${version ?? ""} via ${apt}`)
}
try {
const apt: string = getApt()

// Update the repos if needed
if (update) {
updateAptReposMemoized(apt)
}
for (const { name, version } of packages) {
info(`Installing ${name} ${version ?? ""} via ${apt}`)
}

// Add the repos if needed
await addRepositories(apt, packages)
// Update the repos if needed
if (update) {
updateAptReposMemoized(apt)
}

const needToInstall = await filterAndQualifyAptPackages(packages, apt)
// Add the repos if needed
await addRepositories(apt, packages)

if (needToInstall.length === 0) {
info("All packages are already installed")
return { binDir: "/usr/bin/" }
}
const needToInstall = await filterAndQualifyAptPackages(packages, apt)

// Initialize apt if needed
await initAptMemoized(apt)
if (needToInstall.length === 0) {
info("All packages are already installed")
return { binDir: "/usr/bin/" }
}

try {
// Add the keys if needed
await addAptKeys(packages)

// Install
execRootSync(apt, ["install", "--fix-broken", "-y", ...needToInstall], {
...defaultExecOptions,
env: getAptEnv(apt),
})
} catch (err) {
if (isExecaError(err)) {
if (retryErrors.some((error) => err.stderr.includes(error))) {
warning(`Failed to install packages ${needToInstall}. Retrying...`)
execRootSync(
apt,
["install", "--fix-broken", "-y", "-o", aptTimeout, ...needToInstall],
{ ...defaultExecOptions, env: getAptEnv(apt) },
)
// Initialize apt if needed
await initAptMemoized(apt)

try {
// Add the keys if needed
await addAptKeys(packages)

// Install
execRootSync(apt, ["install", "--fix-broken", "-y", ...needToInstall], {
...defaultExecOptions,
env: getAptEnv(apt),
})
} catch (err) {
if (isExecaError(err)) {
if (retryErrors.some((error) => err.stderr.includes(error))) {
warning(`Failed to install packages ${needToInstall}. Retrying...`)
execRootSync(
apt,
["install", "--fix-broken", "-y", "-o", aptTimeout, ...needToInstall],
{ ...defaultExecOptions, env: getAptEnv(apt) },
)
}
} else {
throw err
}
} else {
throw err
}
}

return { binDir: "/usr/bin/" }
return { binDir: "/usr/bin/" }
} catch (err) {
const msg = err instanceof Error ? `${err.message}\n${err.stack}` : String(err)
throw new Error(`Failed to install apt packages: ${msg}`)
}
}

async function addRepositories(apt: string, packages: AptPackage[]) {
Expand Down
4 changes: 3 additions & 1 deletion src/cli-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ All the available tools:
"compiler and analyzer": {
tools: "--llvm, --gcc, --msvc, --apple-clang, --vcvarsall, --cppcheck, --clang-tidy, --clang-format",
},
"build system": { tools: "--cmake, --ninja, --meson, --make, --task, --bazel" },
"build system": {
tools: "--cmake, --ninja, --meson, --make, --task, --bazel, --cmakelang, --cmake-lint, --cmake-format",
},
"package manager": { tools: "--vcpkg, --conan, --choco, --brew, --nala" },
cache: { tools: "--ccache, --sccache" },
documentation: { tools: "--doxygen, --graphviz" },
Expand Down
13 changes: 13 additions & 0 deletions src/cmakelang/__tests__/cmakelang.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ubuntuVersion } from "../../utils/env/ubuntu_version.js"
import { testBin } from "../../utils/tests/test-helpers.js"
import { getVersion } from "../../versions/versions.js"
import { setupCmakelang } from "../cmakelang.js"

jest.setTimeout(300000)
describe("setup-cmakelang", () => {
it("should setup cmakelang", async () => {
const installInfo = await setupCmakelang(getVersion("cmakelang", "true", await ubuntuVersion()), "", process.arch)
await testBin("cmake-lint", ["--version"], installInfo.binDir)
await testBin("cmake-format", ["--version"], installInfo.binDir)
})
})
6 changes: 6 additions & 0 deletions src/cmakelang/cmakelang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { setupPipPack } from "../utils/setup/setupPipPack.js"

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function setupCmakelang(version: string | undefined, _setupDir: string, _arch: string) {
return setupPipPack("cmakelang[YAML]", version)
}
30 changes: 20 additions & 10 deletions src/python/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import { isBinUptoDate } from "../utils/setup/version.js"
import { unique } from "../utils/std/index.js"
import { MinVersions } from "../versions/default_versions.js"

export async function setupPython(version: string, setupDir: string, arch: string): Promise<InstallationInfo> {
export async function setupPython(
version: string,
setupDir: string,
arch: string,
): Promise<InstallationInfo & { bin: string }> {
const installInfo = await findOrSetupPython(version, setupDir, arch)
assert(installInfo.bin !== undefined)
const foundPython = installInfo.bin
Expand All @@ -41,7 +45,7 @@ export async function setupPython(version: string, setupDir: string, arch: strin

await setupWheel(foundPython)

return installInfo
return installInfo as InstallationInfo & { bin: string }
}

async function setupPipx(foundPython: string) {
Expand All @@ -56,12 +60,20 @@ async function setupPipx(foundPython: string) {
}
}
await execa(foundPython, ["-m", "pipx", "ensurepath"], { stdio: "inherit" })
await setupPipPackWithPython(foundPython, "venv", undefined, { upgrade: false, usePipx: false })
await setupVenv(foundPython)
} catch (err) {
warning(`Failed to install pipx: ${(err as Error).toString()}. Ignoring...`)
}
}

async function setupVenv(foundPython: string) {
try {
await setupPipPackWithPython(foundPython, "venv", undefined, { upgrade: false, usePipx: false })
} catch (err) {
warning(`Failed to install venv: ${(err as Error).toString()}. Ignoring...`)
}
}

/** Setup wheel and setuptools */
async function setupWheel(foundPython: string) {
try {
Expand All @@ -70,9 +82,9 @@ async function setupWheel(foundPython: string) {
isLibrary: true,
usePipx: false,
})
await setupPipPackWithPython(foundPython, "wheel", undefined, { upgrade: true, isLibrary: true, usePipx: false })
await setupPipPackWithPython(foundPython, "wheel", undefined, { upgrade: false, isLibrary: true, usePipx: false })
} catch (err) {
warning(`Failed to install setuptools or wheel: ${(err as Error).toString()}. Ignoring...`)
warning(`Failed to install setuptools/wheel: ${(err as Error).toString()}. Ignoring...`)
}
}

Expand Down Expand Up @@ -171,7 +183,7 @@ async function setupPythonSystem(setupDir: string, version: string) {
}

async function findPython(binDir?: string) {
for (const pythonBin of ["python3", "python"]) {
for (const pythonBin of ["python", "python3"]) {
// eslint-disable-next-line no-await-in-loop
const foundPython = await isPythonUpToDate(pythonBin, binDir)
if (foundPython !== undefined) {
Expand Down Expand Up @@ -203,10 +215,8 @@ async function isPythonUpToDate(candidate: string, binDir?: string) {
try {
if (binDir !== undefined) {
const pythonBinPath = join(binDir, addExeExt(candidate))
if (await pathExists(pythonBinPath)) {
if (await isBinUptoDate(pythonBinPath, MinVersions.python!)) {
return pythonBinPath
}
if (await pathExists(pythonBinPath) && await isBinUptoDate(pythonBinPath, MinVersions.python!)) {
return pythonBinPath
}
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
Expand Down
22 changes: 16 additions & 6 deletions src/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { setupBazel } from "./bazel/bazel.js"
import { setupCcache } from "./ccache/ccache.js"
import { setupChocolatey } from "./chocolatey/chocolatey.js"
import { setupCmake } from "./cmake/cmake.js"
import { setupCmakelang } from "./cmakelang/cmakelang.js"
import { setupConan } from "./conan/conan.js"
import { setupCppcheck } from "./cppcheck/cppcheck.js"
import { setupDoxygen } from "./doxygen/doxygen.js"
Expand Down Expand Up @@ -42,30 +43,39 @@ export const appleClangSetups = {
"apple-llvm": setupAppleClang,
} as const

const cmakeLangSetups = {
cmakelang: setupCmakelang,
"cmake-lint": setupCmakelang,
"cmake-format": setupCmakelang,
cmakelint: setupCmakelang,
cmakeformat: setupCmakelang,
} as const

export const llvmTools = ["llvm", "clang", "clang++", "clang-tidy", "clang-format", "clangtidy", "clangformat"]

/** The setup functions */
export const setups = {
nala: setupNala,
brew: setupBrew,
choco: setupChocolatey,
python: setupPython,
powershell: setupPowershell,
pwsh: setupPowershell,
...llvmSetups,
...gccSetups,
...mingwSetups,
...msvcSetups,
...appleClangSetups,
nala: setupNala,
...cmakeLangSetups,
cmake: setupCmake,
ninja: setupNinja,
python: setupPython,
vcpkg: setupVcpkg,
bazel: setupBazel,
conan: setupConan,
meson: setupMeson,
gcovr: setupGcovr,
opencppcoverage: setupOpencppcoverage,
OpenCppCoverage: setupOpencppcoverage,
choco: setupChocolatey,
brew: setupBrew,
powershell: setupPowershell,
pwsh: setupPowershell,
ccache: setupCcache,
sccache: setupSccache,
doxygen: setupDoxygen,
Expand Down
91 changes: 91 additions & 0 deletions src/utils/compat/node.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// the installed @types/node package is version 12 so that backwards compatibility is maintained
// node: prefix is removed by Babel, so define the types of those packages here so that TypeScript can find them

declare module "node:fs" {
import fs from "fs"
export = fs
}

declare module "node:path" {
import path from "path"
export = path
}

declare module "node:child_process" {
import child_process from "child_process"
export = child_process
}

declare module "node:os" {
import os from "os"
export = os
}

declare module "node:util" {
import util from "util"
export = util
}

declare module "node:stream" {
import stream from "stream"
export = stream
}

declare module "node:zlib" {
import zlib from "zlib"
export = zlib
}

declare module "node:crypto" {
import crypto from "crypto"
export = crypto
}
declare module "node:http" {
import http from "http"
export = http
}

declare module "node:https" {
import https from "https"
export = https
}

declare module "node:events" {
import events from "events"
export = events
}

declare module "node:assert" {
import assert from "assert"
export = assert
}

declare module "node:constants" {
import constants from "constants"
export = constants
}

declare module "node:querystring" {
import querystring from "querystring"
export = querystring
}

declare module "node:url" {
import url from "url"
export = url
}

declare module "node:fs/promises" {
import fsPromises from "fs/promises"
export = fsPromises
}

declare module "node:path/posix" {
import pathPosix from "path/posix"
export = pathPosix
}

declare module "node:path/win32" {
import pathWin32 from "path/win32"
export = pathWin32
}
Loading

0 comments on commit fb2a9a2

Please sign in to comment.