mirror of
https://github.com/appium/appium.git
synced 2026-01-25 11:48:49 -06:00
Bumps [argparse](https://github.com/nodeca/argparse) from 1.0.10 to 2.0.1. - [Release notes](https://github.com/nodeca/argparse/releases) - [Changelog](https://github.com/nodeca/argparse/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/argparse/compare/1.0.10...2.0.1) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Mykola Mokhnach <mokhnach@gmail.com>
236 lines
6.6 KiB
JavaScript
236 lines
6.6 KiB
JavaScript
import _ from 'lodash';
|
|
import path from 'path';
|
|
import { mkdirp, fs, system } from 'appium-support';
|
|
import axios from 'axios';
|
|
import { exec } from 'teen_process';
|
|
import { rootDir } from './utils';
|
|
import logger from './logger';
|
|
import semver from 'semver';
|
|
import {
|
|
StoreDeprecatedDefaultCapabilityAction, DEFAULT_CAPS_ARG,
|
|
} from './argsparse-actions';
|
|
|
|
|
|
const npmPackage = require(path.resolve(rootDir, 'package.json'));
|
|
const APPIUM_VER = npmPackage.version;
|
|
const MIN_NODE_VERSION = npmPackage.engines.node;
|
|
|
|
const GIT_META_ROOT = '.git';
|
|
const GIT_BINARY = `git${system.isWindows() ? '.exe' : ''}`;
|
|
const GITHUB_API = 'https://api.github.com/repos/appium/appium';
|
|
|
|
const BUILD_INFO = {
|
|
version: APPIUM_VER,
|
|
};
|
|
|
|
function getNodeVersion () {
|
|
return semver.coerce(process.version);
|
|
}
|
|
|
|
function isSubClass (candidateClass, superClass) {
|
|
return _.isFunction(superClass) && _.isFunction(candidateClass)
|
|
&& (candidateClass.prototype instanceof superClass || candidateClass === superClass);
|
|
}
|
|
|
|
async function updateBuildInfo (useGithubApiFallback = false) {
|
|
const sha = await getGitRev(useGithubApiFallback);
|
|
if (!sha) {
|
|
return;
|
|
}
|
|
BUILD_INFO['git-sha'] = sha;
|
|
const built = await getGitTimestamp(sha, useGithubApiFallback);
|
|
if (!_.isEmpty(built)) {
|
|
BUILD_INFO.built = built;
|
|
}
|
|
}
|
|
|
|
async function getGitRev (useGithubApiFallback = false) {
|
|
if (await fs.exists(path.resolve(rootDir, GIT_META_ROOT))) {
|
|
try {
|
|
const {stdout} = await exec(GIT_BINARY, ['rev-parse', 'HEAD'], {
|
|
cwd: rootDir
|
|
});
|
|
return stdout.trim();
|
|
} catch (ign) {}
|
|
}
|
|
|
|
if (!useGithubApiFallback) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const resBodyObj = (await axios.get(`${GITHUB_API}/tags`, {
|
|
headers: {
|
|
'User-Agent': `Appium ${APPIUM_VER}`
|
|
}
|
|
})).data;
|
|
if (_.isArray(resBodyObj)) {
|
|
for (const {name, commit} of resBodyObj) {
|
|
if (name === `v${APPIUM_VER}` && commit && commit.sha) {
|
|
return commit.sha;
|
|
}
|
|
}
|
|
}
|
|
} catch (ign) {}
|
|
return null;
|
|
}
|
|
|
|
async function getGitTimestamp (commitSha, useGithubApiFallback = false) {
|
|
if (await fs.exists(path.resolve(rootDir, GIT_META_ROOT))) {
|
|
try {
|
|
const {stdout} = await exec(GIT_BINARY, ['show', '-s', '--format=%ci', commitSha], {
|
|
cwd: rootDir
|
|
});
|
|
return stdout.trim();
|
|
} catch (ign) {}
|
|
}
|
|
|
|
if (!useGithubApiFallback) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const resBodyObj = (await axios.get(`${GITHUB_API}/commits/${commitSha}`, {
|
|
headers: {
|
|
'User-Agent': `Appium ${APPIUM_VER}`
|
|
}
|
|
})).data;
|
|
if (resBodyObj && resBodyObj.commit) {
|
|
if (resBodyObj.commit.committer && resBodyObj.commit.committer.date) {
|
|
return resBodyObj.commit.committer.date;
|
|
}
|
|
if (resBodyObj.commit.author && resBodyObj.commit.author.date) {
|
|
return resBodyObj.commit.author.date;
|
|
}
|
|
}
|
|
} catch (ign) {}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @returns Mutable object containing Appium build information. By default it
|
|
* only contains the Appium version, but is updated with the build timestamp
|
|
* and git commit hash asynchronously as soon as `updateBuildInfo` is called
|
|
* and succeeds.
|
|
*/
|
|
function getBuildInfo () {
|
|
return BUILD_INFO;
|
|
}
|
|
|
|
function checkNodeOk () {
|
|
const version = getNodeVersion();
|
|
if (!semver.satisfies(version, MIN_NODE_VERSION)) {
|
|
logger.errorAndThrow(`Node version must be ${MIN_NODE_VERSION}. Currently ${version.version}`);
|
|
}
|
|
}
|
|
|
|
function warnNodeDeprecations () {
|
|
/**
|
|
* Uncomment this section to get node version deprecation warnings
|
|
* Also add test cases to config-specs.js to cover the cases added
|
|
**/
|
|
|
|
// const version = getNodeVersion();
|
|
// if (version.major < 8) {
|
|
// logger.warn(`Appium support for versions of node < ${version.major} has been ` +
|
|
// 'deprecated and will be removed in a future version. Please ' +
|
|
// 'upgrade!');
|
|
// }
|
|
}
|
|
|
|
async function showConfig () {
|
|
await updateBuildInfo(true);
|
|
console.log(JSON.stringify(getBuildInfo())); // eslint-disable-line no-console
|
|
}
|
|
|
|
function getNonDefaultArgs (parser, args) {
|
|
return parser.rawArgs.reduce((acc, [, {dest, default: defaultValue}]) => {
|
|
if (args[dest] && args[dest] !== defaultValue) {
|
|
acc[dest] = args[dest];
|
|
}
|
|
return acc;
|
|
}, {});
|
|
}
|
|
|
|
function getDeprecatedArgs (parser, args) {
|
|
// go through the server command line arguments and figure
|
|
// out which of the ones used are deprecated
|
|
return parser.rawArgs.reduce((acc, [[name], {dest, default: defaultValue, action}]) => {
|
|
if (!args[dest] || args[dest] === defaultValue) {
|
|
return acc;
|
|
}
|
|
|
|
if (action?.deprecated_for) {
|
|
acc[name] = action.deprecated_for;
|
|
} else if (isSubClass(action, StoreDeprecatedDefaultCapabilityAction)) {
|
|
acc[name] = DEFAULT_CAPS_ARG;
|
|
}
|
|
return acc;
|
|
}, {});
|
|
}
|
|
|
|
function checkValidPort (port, portName) {
|
|
if (port > 0 && port < 65536) return true; // eslint-disable-line curly
|
|
logger.error(`Port '${portName}' must be greater than 0 and less than 65536. Currently ${port}`);
|
|
return false;
|
|
}
|
|
|
|
function validateServerArgs (parser, args) {
|
|
// arguments that cannot both be set
|
|
let exclusives = [
|
|
['noReset', 'fullReset'],
|
|
['ipa', 'safari'],
|
|
['app', 'safari'],
|
|
['forceIphone', 'forceIpad'],
|
|
['deviceName', 'defaultDevice']
|
|
];
|
|
|
|
for (let exSet of exclusives) {
|
|
let numFoundInArgs = 0;
|
|
for (let opt of exSet) {
|
|
if (_.has(args, opt) && args[opt]) {
|
|
numFoundInArgs++;
|
|
}
|
|
}
|
|
if (numFoundInArgs > 1) {
|
|
throw new Error(`You can't pass in more than one argument from the ` +
|
|
`set ${JSON.stringify(exSet)}, since they are ` +
|
|
`mutually exclusive`);
|
|
}
|
|
}
|
|
|
|
const validations = {
|
|
port: checkValidPort,
|
|
callbackPort: checkValidPort,
|
|
bootstrapPort: checkValidPort,
|
|
chromedriverPort: checkValidPort,
|
|
robotPort: checkValidPort,
|
|
backendRetries: (r) => r >= 0,
|
|
};
|
|
|
|
const nonDefaultArgs = getNonDefaultArgs(parser, args);
|
|
|
|
for (let [arg, validator] of _.toPairs(validations)) {
|
|
if (_.has(nonDefaultArgs, arg)) {
|
|
if (!validator(args[arg], arg)) {
|
|
throw new Error(`Invalid argument for param ${arg}: ${args[arg]}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function validateTmpDir (tmpDir) {
|
|
try {
|
|
await mkdirp(tmpDir);
|
|
} catch (e) {
|
|
throw new Error(`We could not ensure that the temp dir you specified ` +
|
|
`(${tmpDir}) exists. Please make sure it's writeable.`);
|
|
}
|
|
}
|
|
|
|
export {
|
|
getBuildInfo, validateServerArgs, checkNodeOk, showConfig,
|
|
warnNodeDeprecations, validateTmpDir, getNonDefaultArgs, getDeprecatedArgs,
|
|
getGitRev, checkValidPort, APPIUM_VER, updateBuildInfo,
|
|
};
|