Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add an option for install directory of mini{forge,conda} #342

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ inputs:
installers"
required: false
default: ""
install-dir:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm inclined to using installation-directory here instead. The rest of the options in this project seem to be using no abbreviations (e.g. we fully spell environment instead of env).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @isuruf, indeed I agree with @jaimergp comment, we should try to use full names :)

description:
"If provided, the installer will be installed in the given directory."
required: false
default: ""
miniconda-version:
description:
"If provided, this version of Miniconda3 will be downloaded and installed.
Expand Down
56 changes: 30 additions & 26 deletions dist/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47592,7 +47592,7 @@ function installBaseTools(inputs, options) {
}
}
if (tools.length) {
yield conda.condaCommand(["install", "--name", "base", ...tools], options);
yield conda.condaCommand(["install", "--name", "base", ...tools], inputs, options);
// *Now* use the new options, as we may have a new conda/mamba with more supported
// options that previously failed
yield conda.applyCondaConfiguration(inputs, postInstallOptions);
Expand Down Expand Up @@ -47797,7 +47797,7 @@ exports.updateMamba = {
}
core.info("Creating bash wrapper for `mamba`...");
// Add bat-less forwarder for bash users on Windows
const mambaBat = conda.condaExecutable(options).replace(/\\/g, "/");
const mambaBat = conda.condaExecutable(inputs, options).replace(/\\/g, "/");
const contents = `bash.exe -c "exec '${mambaBat}' $*" || exit 1`;
fs.writeFileSync(mambaBat.slice(0, -4), contents);
core.info(`... wrote ${mambaBat}:\n${contents}`);
Expand Down Expand Up @@ -47919,11 +47919,14 @@ const utils = __importStar(__nccwpck_require__(1314));
/**
* Provide current location of miniconda or location where it will be installed
*/
function condaBasePath(options) {
function condaBasePath(inputs, options) {
let condaPath;
if (options.useBundled) {
condaPath = constants.MINICONDA_DIR_PATH;
}
else if (inputs.installDir) {
condaPath = inputs.installDir;
}
else {
condaPath = path.join(os.homedir(), "miniconda3");
}
Expand All @@ -47946,8 +47949,8 @@ exports.envCommandFlag = envCommandFlag;
/**
* Provide cross platform location of conda/mamba executable
*/
function condaExecutable(options, subcommand) {
const dir = condaBasePath(options);
function condaExecutable(inputs, options, subcommand) {
const dir = condaBasePath(inputs, options);
let condaExe;
let commandName = "conda";
if (options.useMamba &&
Expand All @@ -47960,17 +47963,17 @@ function condaExecutable(options, subcommand) {
}
exports.condaExecutable = condaExecutable;
/** Detect the presence of mamba */
function isMambaInstalled(options) {
const mamba = condaExecutable(Object.assign(Object.assign({}, options), { useMamba: true }));
function isMambaInstalled(inputs, options) {
const mamba = condaExecutable(inputs, Object.assign(Object.assign({}, options), { useMamba: true }));
return fs.existsSync(mamba);
}
exports.isMambaInstalled = isMambaInstalled;
/**
* Run Conda command
*/
function condaCommand(cmd, options) {
function condaCommand(cmd, inputs, options) {
return __awaiter(this, void 0, void 0, function* () {
const command = [condaExecutable(options, cmd[0]), ...cmd];
const command = [condaExecutable(inputs, options, cmd[0]), ...cmd];
return yield utils.execute(command);
});
}
Expand Down Expand Up @@ -48016,7 +48019,7 @@ function applyCondaConfiguration(inputs, options) {
// .slice ensures working against a copy
for (const channel of channels.slice().reverse()) {
core.info(`Adding channel '${channel}'`);
yield condaCommand(["config", "--add", "channels", channel], options);
yield condaCommand(["config", "--add", "channels", channel], inputs, options);
}
// All other options are just passed as their string representations
for (const [key, value] of configEntries) {
Expand All @@ -48025,15 +48028,15 @@ function applyCondaConfiguration(inputs, options) {
}
core.info(`${key}: ${value}`);
try {
yield condaCommand(["config", "--set", key, value], options);
yield condaCommand(["config", "--set", key, value], inputs, options);
}
catch (err) {
core.warning(err);
}
}
// Log all configuration information
yield condaCommand(["config", "--show-sources"], options);
yield condaCommand(["config", "--show"], options);
yield condaCommand(["config", "--show-sources"], inputs, options);
yield condaCommand(["config", "--show"], inputs, options);
});
}
exports.applyCondaConfiguration = applyCondaConfiguration;
Expand All @@ -48055,12 +48058,12 @@ function condaInit(inputs, options) {
"chown",
"-R",
`${userName}:staff`,
condaBasePath(options),
condaBasePath(inputs, options),
]);
}
else if (constants.IS_WINDOWS) {
for (let folder of constants.WIN_PERMS_FOLDERS) {
ownPath = path.join(condaBasePath(options), folder);
ownPath = path.join(condaBasePath(inputs, options), folder);
if (fs.existsSync(ownPath)) {
core.info(`Fixing ${folder} ownership`);
yield utils.execute(["takeown", "/f", ownPath, "/r", "/d", "y"]);
Expand All @@ -48085,7 +48088,7 @@ function condaInit(inputs, options) {
}
// Run conda init
for (let cmd of ["--all"]) {
yield condaCommand(["init", cmd], options);
yield condaCommand(["init", cmd], inputs, options);
}
if (inputs.removeProfiles == "true") {
// Rename files
Expand Down Expand Up @@ -48504,7 +48507,7 @@ function ensureEnvironment(inputs, options) {
if (yield provider.provides(inputs, options)) {
core.info(`... will ${provider.label}.`);
const args = yield provider.condaArgs(inputs, options);
return yield core.group(`Updating '${inputs.activateEnvironment}' env from ${provider.label}...`, () => conda.condaCommand(args, options));
return yield core.group(`Updating '${inputs.activateEnvironment}' env from ${provider.label}...`, () => conda.condaCommand(args, inputs, options));
}
}
throw Error(`'activate-environment: ${inputs.activateEnvironment}' could not be created`);
Expand Down Expand Up @@ -48839,6 +48842,7 @@ function parseInputs() {
condaVersion: core.getInput("conda-version"),
environmentFile: core.getInput("environment-file"),
installerUrl: core.getInput("installer-url"),
installDir: core.getInput("install-dir"),
mambaVersion: core.getInput("mamba-version"),
useMamba: core.getInput("use-mamba"),
minicondaVersion: core.getInput("miniconda-version"),
Expand Down Expand Up @@ -49445,7 +49449,7 @@ function runInstaller(installerPath, outputPath, inputs, options) {
}
yield utils.execute(command);
// The installer may have provisioned `mamba` in `base`: use now if requested
const mambaInInstaller = conda.isMambaInstalled(options);
const mambaInInstaller = conda.isMambaInstalled(inputs, options);
if (mambaInInstaller) {
core.info("Mamba was found in the `base` env");
options = Object.assign(Object.assign({}, options), { mambaInInstaller, useMamba: mambaInInstaller && inputs.useMamba === "true" });
Expand Down Expand Up @@ -49508,10 +49512,10 @@ const utils = __importStar(__nccwpck_require__(1314));
/**
* Add Conda executable to PATH environment variable
*/
function setPathVariables(options) {
function setPathVariables(inputs, options) {
return __awaiter(this, void 0, void 0, function* () {
const condaBin = path.join(conda.condaBasePath(options), "condabin");
const condaPath = conda.condaBasePath(options);
const condaBin = path.join(conda.condaBasePath(inputs, options), "condabin");
const condaPath = conda.condaBasePath(inputs, options);
core.info(`Add "${condaBin}" to PATH`);
core.addPath(condaBin);
if (!options.useBundled) {
Expand All @@ -49524,10 +49528,10 @@ exports.setPathVariables = setPathVariables;
/**
* Ensure the conda cache path is available as an environment variable
*/
function setCacheVariable(options) {
function setCacheVariable(inputs, options) {
return __awaiter(this, void 0, void 0, function* () {
const folder = utils.cacheFolder();
yield conda.condaCommand(["config", "--add", "pkgs_dirs", folder], options);
yield conda.condaCommand(["config", "--add", "pkgs_dirs", folder], inputs, options);
core.exportVariable(constants.ENV_VAR_CONDA_PKGS, folder);
});
}
Expand Down Expand Up @@ -49608,7 +49612,7 @@ function setupMiniconda(inputs) {
const installerInfo = yield core.group("Ensuring installer...", () => installer.getLocalInstallerPath(inputs, options));
// The desired installer may change the options
options = Object.assign(Object.assign({}, options), installerInfo.options);
const basePath = conda.condaBasePath(options);
const basePath = conda.condaBasePath(inputs, options);
if (installerInfo.localInstallerPath && !options.useBundled) {
options = yield core.group("Running installer...", () => installer.runInstaller(installerInfo.localInstallerPath, basePath, inputs, options));
}
Expand All @@ -49620,13 +49624,13 @@ function setupMiniconda(inputs) {
'Miniforge for you, add `miniconda-version: "latest"` or `miniforge-version: "latest"`, ' +
"respectively, to the parameters for this action.");
}
yield core.group("Setup environment variables...", () => outputs.setPathVariables(options));
yield core.group("Setup environment variables...", () => outputs.setPathVariables(inputs, options));
if (inputs.condaConfigFile) {
yield core.group("Copying condarc file...", () => conda.copyConfig(inputs));
}
// For potential 'channels' that may alter configuration
options.envSpec = yield core.group("Parsing environment...", () => env.getEnvSpec(inputs));
yield core.group("Configuring conda package cache...", () => outputs.setCacheVariable(options));
yield core.group("Configuring conda package cache...", () => outputs.setCacheVariable(inputs, options));
yield core.group("Applying initial configuration...", () => conda.applyCondaConfiguration(inputs, options));
yield core.group("Initializing conda shell integration...", () => conda.condaInit(inputs, options));
// New base tools may change options
Expand Down
6 changes: 5 additions & 1 deletion src/base-tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ export async function installBaseTools(
}

if (tools.length) {
await conda.condaCommand(["install", "--name", "base", ...tools], options);
await conda.condaCommand(
["install", "--name", "base", ...tools],
inputs,
options,
);

// *Now* use the new options, as we may have a new conda/mamba with more supported
// options that previously failed
Expand Down
2 changes: 1 addition & 1 deletion src/base-tools/update-mamba.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const updateMamba: types.IToolProvider = {
}
core.info("Creating bash wrapper for `mamba`...");
// Add bat-less forwarder for bash users on Windows
const mambaBat = conda.condaExecutable(options).replace(/\\/g, "/");
const mambaBat = conda.condaExecutable(inputs, options).replace(/\\/g, "/");

const contents = `bash.exe -c "exec '${mambaBat}' $*" || exit 1`;
fs.writeFileSync(mambaBat.slice(0, -4), contents);
Expand Down
38 changes: 26 additions & 12 deletions src/conda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ import * as utils from "./utils";
/**
* Provide current location of miniconda or location where it will be installed
*/
export function condaBasePath(options: types.IDynamicOptions): string {
export function condaBasePath(
inputs: types.IActionInputs,
options: types.IDynamicOptions,
): string {
let condaPath: string;
if (options.useBundled) {
condaPath = constants.MINICONDA_DIR_PATH;
} else if (inputs.installDir) {
condaPath = inputs.installDir;
} else {
condaPath = path.join(os.homedir(), "miniconda3");
}
Expand All @@ -43,10 +48,11 @@ export function envCommandFlag(inputs: types.IActionInputs): string[] {
* Provide cross platform location of conda/mamba executable
*/
export function condaExecutable(
inputs: types.IActionInputs,
options: types.IDynamicOptions,
subcommand?: string,
): string {
const dir: string = condaBasePath(options);
const dir: string = condaBasePath(inputs, options);
let condaExe: string;
let commandName = "conda";
if (
Expand All @@ -61,8 +67,11 @@ export function condaExecutable(
}

/** Detect the presence of mamba */
export function isMambaInstalled(options: types.IDynamicOptions) {
const mamba = condaExecutable({ ...options, useMamba: true });
export function isMambaInstalled(
inputs: types.IActionInputs,
options: types.IDynamicOptions,
) {
const mamba = condaExecutable(inputs, { ...options, useMamba: true });
return fs.existsSync(mamba);
}

Expand All @@ -71,9 +80,10 @@ export function isMambaInstalled(options: types.IDynamicOptions) {
*/
export async function condaCommand(
cmd: string[],
inputs: types.IActionInputs,
options: types.IDynamicOptions,
): Promise<void> {
const command = [condaExecutable(options, cmd[0]), ...cmd];
const command = [condaExecutable(inputs, options, cmd[0]), ...cmd];
return await utils.execute(command);
}

Expand Down Expand Up @@ -127,7 +137,11 @@ export async function applyCondaConfiguration(
// .slice ensures working against a copy
for (const channel of channels.slice().reverse()) {
core.info(`Adding channel '${channel}'`);
await condaCommand(["config", "--add", "channels", channel], options);
await condaCommand(
["config", "--add", "channels", channel],
inputs,
options,
);
}

// All other options are just passed as their string representations
Expand All @@ -137,15 +151,15 @@ export async function applyCondaConfiguration(
}
core.info(`${key}: ${value}`);
try {
await condaCommand(["config", "--set", key, value], options);
await condaCommand(["config", "--set", key, value], inputs, options);
} catch (err) {
core.warning(err as Error);
}
}

// Log all configuration information
await condaCommand(["config", "--show-sources"], options);
await condaCommand(["config", "--show"], options);
await condaCommand(["config", "--show-sources"], inputs, options);
await condaCommand(["config", "--show"], inputs, options);
}

/**
Expand All @@ -170,11 +184,11 @@ export async function condaInit(
"chown",
"-R",
`${userName}:staff`,
condaBasePath(options),
condaBasePath(inputs, options),
]);
} else if (constants.IS_WINDOWS) {
for (let folder of constants.WIN_PERMS_FOLDERS) {
ownPath = path.join(condaBasePath(options), folder);
ownPath = path.join(condaBasePath(inputs, options), folder);
if (fs.existsSync(ownPath)) {
core.info(`Fixing ${folder} ownership`);
await utils.execute(["takeown", "/f", ownPath, "/r", "/d", "y"]);
Expand All @@ -200,7 +214,7 @@ export async function condaInit(

// Run conda init
for (let cmd of ["--all"]) {
await condaCommand(["init", cmd], options);
await condaCommand(["init", cmd], inputs, options);
}

if (inputs.removeProfiles == "true") {
Expand Down
2 changes: 1 addition & 1 deletion src/env/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export async function ensureEnvironment(
const args = await provider.condaArgs(inputs, options);
return await core.group(
`Updating '${inputs.activateEnvironment}' env from ${provider.label}...`,
() => conda.condaCommand(args, options),
() => conda.condaCommand(args, inputs, options),
);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export async function parseInputs(): Promise<types.IActionInputs> {
condaVersion: core.getInput("conda-version"),
environmentFile: core.getInput("environment-file"),
installerUrl: core.getInput("installer-url"),
installDir: core.getInput("install-dir"),
mambaVersion: core.getInput("mamba-version"),
useMamba: core.getInput("use-mamba"),
minicondaVersion: core.getInput("miniconda-version"),
Expand Down
2 changes: 1 addition & 1 deletion src/installer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export async function runInstaller(
await utils.execute(command);

// The installer may have provisioned `mamba` in `base`: use now if requested
const mambaInInstaller = conda.isMambaInstalled(options);
const mambaInInstaller = conda.isMambaInstalled(inputs, options);
if (mambaInInstaller) {
core.info("Mamba was found in the `base` env");
options = {
Expand Down
Loading
Loading