Merge pull request #108 from aminya/nala [skip ci]

fix: support using nala instead of apt
This commit is contained in:
Amin Yahyaabadi 2022-07-27 17:39:12 -07:00 committed by GitHub
commit 79079b96ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 142 additions and 40 deletions

View File

@ -10,7 +10,7 @@ Setting up a **cross-platform** environment for building and testing C++/C proje
`setup-cpp` is supported on many platforms. It is continuously tested on several configurations including Windows (11, 10, 2022, 2019), Linux (Ubuntu 22.04, Ubuntu 20.04, Fedora, ArchLinux), and macOS (12, 11, 10.15). `setup-cpp` is backed by unit tests for each tool and integration tests for compiling cpp projects. `setup-cpp` is supported on many platforms. It is continuously tested on several configurations including Windows (11, 10, 2022, 2019), Linux (Ubuntu 22.04, Ubuntu 20.04, Fedora, ArchLinux), and macOS (12, 11, 10.15). `setup-cpp` is backed by unit tests for each tool and integration tests for compiling cpp projects.
# Features ## Features
`setup-cpp` is **modular** and you can choose to install any of these tools: `setup-cpp` is **modular** and you can choose to install any of these tools:
@ -18,7 +18,7 @@ Setting up a **cross-platform** environment for building and testing C++/C proje
| --------------------- | ------------------------------------------------------------ | | --------------------- | ------------------------------------------------------------ |
| compiler and analyzer | llvm, gcc, msvc, vcvarsall, cppcheck, clangtidy, clangformat | | compiler and analyzer | llvm, gcc, msvc, vcvarsall, cppcheck, clangtidy, clangformat |
| build system | cmake, ninja, meson, make, task | | build system | cmake, ninja, meson, make, task |
| package manager | vcpkg, conan, choco, brew | | package manager | vcpkg, conan, choco, brew, nala |
| cache | cppcache | | cache | cppcache |
| documentation | doxygen, graphviz | | documentation | doxygen, graphviz |
| coverage | gcovr, opencppcoverage, kcov | | coverage | gcovr, opencppcoverage, kcov |
@ -26,15 +26,15 @@ Setting up a **cross-platform** environment for building and testing C++/C proje
`setup-cpp` automatically installs the dependencies above tools if needed for the selected tool (e.g., `python` is required for `conan`). `setup-cpp` automatically installs the dependencies above tools if needed for the selected tool (e.g., `python` is required for `conan`).
# Usage ## Usage
## From Terminal ### From Terminal
You should download the executable file or the js file (if Nodejs installed), and run it with the available options. You should download the executable file or the js file (if Nodejs installed), and run it with the available options.
Tip: You can automate downloading using `wget`, `curl`, or other similar tools. Tip: You can automate downloading using `wget`, `curl`, or other similar tools.
### Executable #### Executable
Download the executable for your platform from [here](https://github.com/aminya/setup-cpp/releases/tag/v0.18.0), and run it with the available options. Download the executable for your platform from [here](https://github.com/aminya/setup-cpp/releases/tag/v0.18.0), and run it with the available options.
@ -72,7 +72,7 @@ NOTE: On Unix systems, when `setup-cpp` is used locally or in other CI services
NOTE: On Unix systems, you will not need `sudo` if you are already a root user (e.g., in a GitLab runner or Docker). NOTE: On Unix systems, you will not need `sudo` if you are already a root user (e.g., in a GitLab runner or Docker).
### With Nodejs #### With Nodejs
Download the `setup_cpp.js` file form [here](https://github.com/aminya/setup-cpp/releases/download/v0.18.0/setup_cpp.js), and run it with the available options. Download the `setup_cpp.js` file form [here](https://github.com/aminya/setup-cpp/releases/download/v0.18.0/setup_cpp.js), and run it with the available options.
@ -97,7 +97,7 @@ sudo node ./setup_cpp.js --compiler llvm --cmake true --ninja true --ccache true
source ~/.cpprc # activate cpp environment variables source ~/.cpprc # activate cpp environment variables
``` ```
## Inside GitHub Actions ### Inside GitHub Actions
Here is a complete cross-platform example that tests llvm, gcc, and msvc. It also uses cmake, ninja, vcpkg, and cppcheck. Here is a complete cross-platform example that tests llvm, gcc, and msvc. It also uses cmake, ninja, vcpkg, and cppcheck.
@ -158,7 +158,7 @@ jobs:
# ... # ...
``` ```
## Inside Docker ### Inside Docker
Here is an example for using setup_cpp to make a builder image that has the Cpp tools you need. Here is an example for using setup_cpp to make a builder image that has the Cpp tools you need.
@ -213,7 +213,7 @@ After build, run the following to start an interactive shell in your container
docker run -it setup_cpp docker run -it setup_cpp
``` ```
## Inside Docker inside GitHub Actions ### Inside Docker inside GitHub Actions
You can use the docker file discussed in the previous section inside GitHub Actions like the following: You can use the docker file discussed in the previous section inside GitHub Actions like the following:
@ -235,7 +235,7 @@ jobs:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true ACTIONS_ALLOW_UNSECURE_COMMANDS: true
``` ```
## Inside GitLab pipelines ### Inside GitLab pipelines
The following gives an example for setting up a C++ environment inside GitLab pipelines. The following gives an example for setting up a C++ environment inside GitLab pipelines.
@ -292,11 +292,11 @@ test_linux_gcc:
- *test - *test
``` ```
# Articles ## Articles
[Setup-Cpp on Dev.to](https://dev.to/aminya/setup-cpp-3ia4) [Setup-Cpp on Dev.to](https://dev.to/aminya/setup-cpp-3ia4)
# Usage Examples ## Usage Examples
- [cpp_vcpkg_project project](https://github.com/aminya/cpp_vcpkg_project) - [cpp_vcpkg_project project](https://github.com/aminya/cpp_vcpkg_project)
- [ftxui](https://github.com/ArthurSonzogni/FTXUI) - [ftxui](https://github.com/ArthurSonzogni/FTXUI)

View File

@ -75,6 +75,9 @@ inputs:
sevenzip: sevenzip:
description: "The 7z version to install." description: "The 7z version to install."
required: false required: false
nala:
description: 'The nala version to install ("" or "legacy").'
required: false
runs: runs:
using: "node12" using: "node12"

View File

@ -46,6 +46,7 @@ words:
- msys - msys
- multilib - multilib
- mxschmitt - mxschmitt
- nala
- noconfirm - noconfirm
- noprogressbar - noprogressbar
- nothrow - nothrow

2
dist/setup_cpp.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/setup_cpp.mjs vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -55,6 +55,14 @@ const DefaultUbuntuVersion: Record<string, Record<number, string>> = {
doxygen: { doxygen: {
20: "1.9.4", 20: "1.9.4",
}, },
nala: {
22: "",
21: "legacy",
20: "legacy",
18: "legacy",
16: "legacy",
14: "legacy",
},
} }
/** Get the default version if passed true or undefined, otherwise return the version itself */ /** Get the default version if passed true or undefined, otherwise return the version itself */

View File

@ -42,9 +42,11 @@ 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 { setupGraphviz } from "./graphviz/graphviz" import { setupGraphviz } from "./graphviz/graphviz"
import { setupNala } from "./nala/nala"
/** The setup functions */ /** The setup functions */
const setups = { const setups = {
nala: setupNala,
cmake: setupCmake, cmake: setupCmake,
ninja: setupNinja, ninja: setupNinja,
python: setupPython, python: setupPython,
@ -73,6 +75,7 @@ const setups = {
/** The tools that can be installed */ /** The tools that can be installed */
const tools: Array<keyof typeof setups> = [ const tools: Array<keyof typeof setups> = [
"nala",
"choco", "choco",
"brew", "brew",
"python", "python",
@ -372,6 +375,7 @@ All the available tools:
--python --python
--choco --choco
--brew --brew
--nala
--sevenzip --sevenzip
--graphviz --graphviz
`) `)

View File

@ -0,0 +1,14 @@
import { setupNala } from "../nala"
import { testBin } from "../../utils/tests/test-helpers"
import { isUbuntu } from "../../utils/env/isUbuntu"
jest.setTimeout(300000)
describe("setup-nala", () => {
it("should setup nala", async () => {
if (!isUbuntu()) {
return
}
const installInfo = setupNala("", "", process.arch)
await testBin("nala", ["--version"], installInfo?.binDir)
})
})

48
src/nala/nala.ts Normal file
View File

@ -0,0 +1,48 @@
import { dirname } from "path"
import which from "which"
import { isUbuntu } from "../utils/env/isUbuntu"
import { execSudo } from "../utils/exec/sudo"
import { setupAptPack } from "../utils/setup/setupAptPack"
let binDir: string | undefined
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function setupNala(version: string, _setupDir: string, _arch: string) {
if (!isUbuntu()) {
return undefined
}
if (typeof binDir === "string") {
return { binDir }
}
const maybeBinDir = which.sync("nala", { nothrow: true })
if (maybeBinDir !== null) {
binDir = dirname(maybeBinDir)
return { binDir }
}
// https://github.com/volitank/nala#-installation
setupAptPack("wget")
execSudo("/bin/bash", [
"-c",
`wget -qO - https://deb.volian.org/volian/scar.key | tee /etc/apt/trusted.gpg.d/volian-archive-scar-unstable.gpg > /dev/null`,
])
execSudo("/bin/bash", [
"-c",
`echo "deb http://deb.volian.org/volian/ scar main" | tee /etc/apt/sources.list.d/volian-archive-scar-unstable.list`,
])
try {
if (version !== "legacy") {
setupAptPack("nala", undefined, [], true)
} else {
setupAptPack("nala-legacy", undefined, [], true)
}
} catch (err) {
setupAptPack("nala-legacy", undefined, [], true)
}
binDir = "/usr/bin"
return { binDir }
}

View File

@ -4,8 +4,9 @@ import { execSudo } from "../exec/sudo"
import { info } from "@actions/core" import { info } from "@actions/core"
import { warning } from "../io/io" import { warning } from "../io/io"
import { isGitHubCI } from "../env/isCI" import { isGitHubCI } from "../env/isCI"
import { cpprc_path, setupCppInProfile } from "../env/addEnv" import { addEnv, cpprc_path, setupCppInProfile } from "../env/addEnv"
import { appendFileSync } from "fs" import { appendFileSync } from "fs"
import which from "which"
let didUpdate: boolean = false let didUpdate: boolean = false
let didInit: boolean = false let didInit: boolean = false
@ -14,21 +15,66 @@ let didInit: boolean = false
export function setupAptPack( export function setupAptPack(
name: string, name: string,
version?: string, version?: string,
repositories: boolean | string[] = true repositories: string[] = [],
update = false
): InstallationInfo { ): InstallationInfo {
info(`Installing ${name} ${version ?? ""} via apt`) info(`Installing ${name} ${version ?? ""} via apt`)
const apt = "apt-get" let apt: string = getApt()
process.env.DEBIAN_FRONTEND = "noninteractive" process.env.DEBIAN_FRONTEND = "noninteractive"
if (!didUpdate) { if (!didUpdate || update) {
execSudo(apt, ["update", "-y"]) updateRepos(apt)
didUpdate = true didUpdate = true
} }
if (!didInit) { if (!didInit) {
// install apt utils and certificates (usually missing from docker containers) initApt(apt)
didInit = true
}
if (Array.isArray(repositories) && repositories.length !== 0) {
for (const repo of repositories) {
// eslint-disable-next-line no-await-in-loop
execSudo("add-apt-repository", ["--update", "-y", repo])
}
updateRepos(apt)
}
if (version !== undefined && version !== "") {
try {
execSudo(apt, ["install", "--fix-broken", "-y", `${name}=${version}`])
} catch {
execSudo(apt, ["install", "--fix-broken", "-y", `${name}-${version}`])
}
} else {
execSudo(apt, ["install", "--fix-broken", "-y", name])
}
return { binDir: "/usr/bin/" }
}
function getApt() {
let apt: string
if (which.sync("nala", { nothrow: true }) !== null) {
apt = "nala"
// enable utf8 otherwise it fails because of the usage of ASCII encoding
addEnv("LANG", "C.UTF-8")
addEnv("LC_ALL", "C.UTF-8")
} else {
apt = "apt-get"
}
return apt
}
function updateRepos(apt: string) {
execSudo(apt, apt !== "nala" ? ["update", "-y"] : ["update"])
}
/** Install apt utils and certificates (usually missing from docker containers) */
function initApt(apt: string) {
execSudo(apt, [ execSudo(apt, [
"install", "install",
"--fix-broken", "--fix-broken",
@ -45,28 +91,6 @@ export function setupAptPack(
} catch (err) { } catch (err) {
warning(`Failed to add keys: ${err}`) warning(`Failed to add keys: ${err}`)
} }
didInit = true
}
if (Array.isArray(repositories)) {
for (const repo of repositories) {
// eslint-disable-next-line no-await-in-loop
execSudo("add-apt-repository", ["--update", "-y", repo])
}
execSudo(apt, ["update", "-y"])
}
if (version !== undefined && version !== "") {
try {
execSudo(apt, ["install", "--fix-broken", "-y", `${name}=${version}`])
} catch {
execSudo(apt, ["install", "--fix-broken", "-y", `${name}-${version}`])
}
} else {
execSudo(apt, ["install", "--fix-broken", "-y", name])
}
return { binDir: "/usr/bin/" }
} }
export function updateAptAlternatives(name: string, path: string) { export function updateAptAlternatives(name: string, path: string) {