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.
# Features
## Features
`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 |
| build system | cmake, ninja, meson, make, task |
| package manager | vcpkg, conan, choco, brew |
| package manager | vcpkg, conan, choco, brew, nala |
| cache | cppcache |
| documentation | doxygen, graphviz |
| 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`).
# 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.
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.
@ -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).
### 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.
@ -97,7 +97,7 @@ sudo node ./setup_cpp.js --compiler llvm --cmake true --ninja true --ccache true
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.
@ -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.
@ -213,7 +213,7 @@ After build, run the following to start an interactive shell in your container
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:
@ -235,7 +235,7 @@ jobs:
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.
@ -292,11 +292,11 @@ test_linux_gcc:
- *test
```
# Articles
## Articles
[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)
- [ftxui](https://github.com/ArthurSonzogni/FTXUI)

View File

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

View File

@ -46,6 +46,7 @@ words:
- msys
- multilib
- mxschmitt
- nala
- noconfirm
- noprogressbar
- 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: {
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 */

View File

@ -42,9 +42,11 @@ import { setupKcov } from "./kcov/kcov"
import { addEnv } from "./utils/env/addEnv"
import { setupSevenZip } from "./sevenzip/sevenzip"
import { setupGraphviz } from "./graphviz/graphviz"
import { setupNala } from "./nala/nala"
/** The setup functions */
const setups = {
nala: setupNala,
cmake: setupCmake,
ninja: setupNinja,
python: setupPython,
@ -73,6 +75,7 @@ const setups = {
/** The tools that can be installed */
const tools: Array<keyof typeof setups> = [
"nala",
"choco",
"brew",
"python",
@ -372,6 +375,7 @@ All the available tools:
--python
--choco
--brew
--nala
--sevenzip
--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 { warning } from "../io/io"
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 which from "which"
let didUpdate: boolean = false
let didInit: boolean = false
@ -14,21 +15,66 @@ let didInit: boolean = false
export function setupAptPack(
name: string,
version?: string,
repositories: boolean | string[] = true
repositories: string[] = [],
update = false
): InstallationInfo {
info(`Installing ${name} ${version ?? ""} via apt`)
const apt = "apt-get"
let apt: string = getApt()
process.env.DEBIAN_FRONTEND = "noninteractive"
if (!didUpdate) {
execSudo(apt, ["update", "-y"])
if (!didUpdate || update) {
updateRepos(apt)
didUpdate = true
}
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, [
"install",
"--fix-broken",
@ -45,28 +91,6 @@ export function setupAptPack(
} catch (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) {