Skip to content

Commit

Permalink
split up existing functions
Browse files Browse the repository at this point in the history
  • Loading branch information
bollwyvl committed Nov 22, 2020
1 parent 4c99d39 commit 6ca11f6
Show file tree
Hide file tree
Showing 15 changed files with 3,814 additions and 2,582 deletions.
816 changes: 810 additions & 6 deletions dist/delete/index.js

Large diffs are not rendered by default.

4,082 changes: 2,206 additions & 1,876 deletions dist/setup/index.js

Large diffs are not rendered by default.

283 changes: 283 additions & 0 deletions src/conda.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
//-----------------------------------------------------------------------
// Conda helpers
//-----------------------------------------------------------------------

import * as fs from "fs";
import * as path from "path";
import * as os from "os";

import * as core from "@actions/core";
import * as io from "@actions/io";

import { IS_LINUX, IS_MAC, IS_WINDOWS, MINICONDA_DIR_PATH } from "./constants";
import { IShells, Result, TCondaConfig } from "./types";
import { execute } from "./utils";

/**
* Provide current location of miniconda or location where it will be installed
*/
export function minicondaPath(useBundled: boolean = true): string {
let condaPath: string = MINICONDA_DIR_PATH;
if (!useBundled) {
if (IS_MAC) {
condaPath = "/Users/runner/miniconda3";
} else {
condaPath += "3";
}
}
return condaPath;
}

/**
* Provide cross platform location of conda/mamba executable
*/
export function condaExecutable(
useBundled: boolean,
useMamba: boolean = false
): string {
const dir: string = minicondaPath(useBundled);
let condaExe: string;
let commandName: string;
commandName = useMamba ? "mamba" : "conda";
commandName = IS_WINDOWS ? commandName + ".bat" : commandName;
condaExe = path.join(dir, "condabin", commandName);
return condaExe;
}

/**
* Run Conda command
*/
export async function condaCommand(
cmd: string[],
useBundled: boolean,
useMamba: boolean = false
): Promise<Result> {
const command = [condaExecutable(useBundled, useMamba), ...cmd];
return await execute(command);
}

/**
* Setup Conda configuration
*/
export async function applyCondaConfiguration(
condaConfig: TCondaConfig,
useBundled: boolean
): Promise<Result> {
let result: Result;
try {
for (const key of Object.keys(condaConfig)) {
core.info(`"${key}": "${condaConfig[key]}"`);
if (condaConfig[key].length !== 0) {
if (key === "channels") {
// Split by comma and reverse order to preserve higher priority
// as listed in the option
let channels: Array<string> = condaConfig[key].split(",").reverse();
let channel: string;
for (channel of channels) {
result = await condaCommand(
["config", "--add", key, channel],
useBundled,
false
);
if (!result.ok) return result;
}
} else {
result = await condaCommand(
["config", "--set", key, condaConfig[key]],
useBundled,
false
);
if (!result.ok) return result;
}
}
}

result = await condaCommand(
["config", "--show-sources"],
useBundled,
false
);
if (!result.ok) return result;

result = await condaCommand(["config", "--show"], useBundled, false);
if (!result.ok) return result;
} catch (err) {
return { ok: false, error: err };
}
return { ok: true, data: "ok" };
}

/**
* Initialize Conda
*/
export async function condaInit(
activateEnvironment: string,
useBundled: boolean,
condaConfig: TCondaConfig,
removeProfiles: string
): Promise<Result> {
let result: Result;
let ownPath: string;
const isValidActivate: boolean =
activateEnvironment !== "base" &&
activateEnvironment !== "root" &&
activateEnvironment !== "";
const autoActivateBase: boolean =
condaConfig["auto_activate_base"] === "true";

// Fix ownership of folders
if (useBundled) {
if (IS_MAC) {
core.startGroup("Fixing conda folders ownership");
const userName: string = process.env.USER as string;
result = await execute([
"sudo",
"chown",
"-R",
`${userName}:staff`,
minicondaPath(useBundled),
]);
core.endGroup();
if (!result.ok) return result;
} else if (IS_WINDOWS) {
for (let folder of [
"condabin/",
"Scripts/",
"shell/",
"etc/profile.d/",
"/Lib/site-packages/xonsh/",
]) {
ownPath = path.join(minicondaPath(useBundled), folder);
if (fs.existsSync(ownPath)) {
core.startGroup(`Fixing ${folder} ownership`);
result = await execute(["takeown", "/f", ownPath, "/r", "/d", "y"]);
core.endGroup();
if (!result.ok) return result;
}
}
}
}

// Remove profile files
if (removeProfiles == "true") {
for (let rc of [
".bashrc",
".bash_profile",
".config/fish/config.fish",
".profile",
".tcshrc",
".xonshrc",
".zshrc",
".config/powershell/profile.ps1",
"Documents/PowerShell/profile.ps1",
"Documents/WindowsPowerShell/profile.ps1",
]) {
try {
let file: string = path.join(os.homedir(), rc);
if (fs.existsSync(file)) {
core.info(`Removing "${file}"`);
await io.rmRF(file);
}
} catch (err) {
core.warning(err);
}
}
}

// Run conda init
for (let cmd of ["--all"]) {
await execute([condaExecutable(useBundled, false), "init", cmd]);
}

// Rename files
if (IS_LINUX) {
let source: string = "~/.bashrc".replace("~", os.homedir());
let dest: string = "~/.profile".replace("~", os.homedir());
core.info(`Renaming "${source}" to "${dest}"\n`);
await io.mv(source, dest);
} else if (IS_MAC) {
let source: string = "~/.bash_profile".replace("~", os.homedir());
let dest: string = "~/.profile".replace("~", os.homedir());
core.info(`Renaming "${source}" to "${dest}"\n`);
await io.mv(source, dest);
}

// PowerShell profiles
let powerExtraText = `
# ----------------------------------------------------------------------------`;
if (isValidActivate) {
powerExtraText += `
# Conda Setup Action: Custom activation
conda activate ${activateEnvironment}`;
}
powerExtraText += `
# ----------------------------------------------------------------------------`;

// Bash profiles
let bashExtraText: string = `
# ----------------------------------------------------------------------------
# Conda Setup Action: Basic configuration
set -eo pipefail`;
if (isValidActivate) {
bashExtraText += `
# Conda Setup Action: Custom activation
conda activate ${activateEnvironment}`;
bashExtraText += `
# ----------------------------------------------------------------------------`;
}

// Batch profiles
let batchExtraText = `
:: ---------------------------------------------------------------------------`;
if (autoActivateBase) {
batchExtraText += `
:: Conda Setup Action: Activate base
@CALL "%CONDA_BAT%" activate base`;
}
if (isValidActivate) {
batchExtraText += `
:: Conda Setup Action: Custom activation
@CALL "%CONDA_BAT%" activate ${activateEnvironment}`;
}
batchExtraText += `
:: Conda Setup Action: Basic configuration
@SETLOCAL EnableExtensions
@SETLOCAL DisableDelayedExpansion
:: ---------------------------------------------------------------------------`;

let extraShells: IShells;
const shells: IShells = {
"~/.bash_profile": bashExtraText,
"~/.profile": bashExtraText,
"~/.zshrc": bashExtraText,
"~/.config/fish/config.fish": bashExtraText,
"~/.tcshrc": bashExtraText,
"~/.xonshrc": bashExtraText,
"~/.config/powershell/profile.ps1": powerExtraText,
"~/Documents/PowerShell/profile.ps1": powerExtraText,
"~/Documents/WindowsPowerShell/profile.ps1": powerExtraText,
};
if (useBundled) {
extraShells = {
"C:/Miniconda/etc/profile.d/conda.sh": bashExtraText,
"C:/Miniconda/etc/fish/conf.d/conda.fish": bashExtraText,
"C:/Miniconda/condabin/conda_hook.bat": batchExtraText,
};
} else {
extraShells = {
"C:/Miniconda3/etc/profile.d/conda.sh": bashExtraText,
"C:/Miniconda3/etc/fish/conf.d/conda.fish": bashExtraText,
"C:/Miniconda3/condabin/conda_hook.bat": batchExtraText,
};
}
const allShells: IShells = { ...shells, ...extraShells };
Object.keys(allShells).forEach((key) => {
let filePath: string = key.replace("~", os.homedir());
const text = allShells[key];
if (fs.existsSync(filePath)) {
core.info(`Append to "${filePath}":\n ${text} \n`);
fs.appendFileSync(filePath, text);
}
});
return { ok: true, data: "ok" };
}
68 changes: 68 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as os from "os";
import * as path from "path";

import { IArchitectures, IOperatingSystems } from "./types";

//-----------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------
export const MINICONDA_DIR_PATH: string = process.env["CONDA"] || "";
export const IS_WINDOWS: boolean = process.platform === "win32";
export const IS_MAC: boolean = process.platform === "darwin";
export const IS_LINUX: boolean = process.platform === "linux";
export const IS_UNIX: boolean = IS_MAC || IS_LINUX;
export const MINICONDA_BASE_URL: string =
"https://repo.anaconda.com/miniconda/";

export const ARCHITECTURES: IArchitectures = {
x64: "x86_64",
x86: "x86",
ARM64: "aarch64", // To be supported by github runners
ARM32: "armv7l", // To be supported by github runners
};

export const OS_NAMES: IOperatingSystems = {
win32: "Windows",
darwin: "MacOSX",
linux: "Linux",
};

export const KNOWN_EXTENSIONS = [".exe", ".sh"];

/**
* errors that are always probably spurious
*/
export const IGNORED_WARNINGS = [
// appear on win install, we can swallow them
`menuinst_win32`,
`Unable to register environment`,
`0%|`,
// appear on certain Linux/OSX installers
`Please run using "bash"`,
// old condas don't know what to do with these
`Key 'use_only_tar_bz2' is not a known primitive parameter.`,
];

/**
* warnings that should be errors
*/
export const FORCED_ERRORS = [
// conda env create will ignore invalid sections and move on
`EnvironmentSectionNotValid`,
];

/**
* avoid spurious conda warnings before we have a chance to update them
*/
export const BOOTSTRAP_CONDARC = "notify_outdated_conda: false";

/**
* the conda config file
*/
export const CONDARC_PATH = path.join(os.homedir(), ".condarc");

/** Where to put files. Should eventually be configurable */
export const CONDA_CACHE_FOLDER = "conda_pkgs_dir";

/** the environment variable exported */
export const ENV_VAR_CONDA_PKGS = "CONDA_PKGS_DIR";
Loading

0 comments on commit 6ca11f6

Please sign in to comment.