Merge pull request #1530 from penguinho/doctor

Appium Doctor Start
This commit is contained in:
Jonathan Lipps
2013-11-26 17:51:28 -08:00
7 changed files with 290 additions and 0 deletions

View File

@@ -38,6 +38,11 @@ want to run tests on. See below for particular platform requirements.
If you want to run Appium via an `npm install`, hack with or contribute to Appium, you will need
[node.js and npm](http://nodejs.org) 0.8 or greater (`brew install node`).
To verify that all of Appium's dependencies are met you can use `appium-doctor`.
Run `appium-doctor` and supply the `--ios` or `--android` flags to verify that all
of the dependencies are set up correctly. If running from source, you mayve have to use
`bin/appium-doctor.js` or `node bin/appium-doctor.js`.
### iOS Requirements
* Mac OS X 10.7 or higher, 10.8.4 recommended

59
bin/appium-doctor.js Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env node
"use strict";
var ios = require('../lib/doctor/ios.js')
, android = require('../lib/doctor/android.js')
, common = require("../lib/doctor/common.js")
, log = require('../lib/doctor/common.js').log
, eol = require('os').EOL
, async = require('async');
var argv = process.argv
, doAndroid = argv.indexOf('--android') > -1
, doIOS = argv.indexOf('--ios') > -1
, verbose = argv.indexOf('--verbose') > -1;
if (!doIOS && !doAndroid) {
doIOS = true;
doAndroid = true;
}
var runiOSChecks = function(cb) {
if (doIOS) {
log.comment("Running iOS Checks");
ios.runAllChecks(function(err) {
if (!err) {
log.pass("iOS Checks were successful." + eol);
cb();
} else {
common.exitDoctor();
}
});
}
};
var runAndroidChecks = function(cb) {
if (doAndroid) {
log.comment("Running Android Checks");
android.runAllChecks(function(err) {
if (!err) {
log.pass("Android Checks were successful." + eol);
cb();
} else {
common.exitDoctor();
}
});
}
};
if (require.main === module) {
async.series([
runiOSChecks,
runAndroidChecks
], function(err) {
if (!err) {
log.pass("All Checks were successful");
} else {
common.exitDoctor();
}
});
}

View File

@@ -24,6 +24,8 @@ to github or write to the appium-discuss mailing list.
./reset.sh --android # android-only
./reset.sh --selendroid # selendroid-only
* You might also want to run `reset.sh` with the `--dev` flag if you want the test apps downloaded and built as well.
* You can also use `appium-doctor` to automatically verify that all dependencies are met. If running from source, you
may have to use `bin/appium-doctor.js` or `node bin/appium-doctor.js`.
* If you get this error after upgrading to Android SDK 22:
`{ANDROID_HOME}/tools/ant/uibuild.xml:155: SDK does not have any Build Tools installed.`
In the Android SDK 22, the platform and build tools are split up into their own items in the SDK manager. Make sure you install the build-tools and platform-tools.

49
lib/doctor/android.js Normal file
View File

@@ -0,0 +1,49 @@
"use strict";
var path = require('path')
, fs = require('fs')
, env = process.env
, exec = require('child_process').exec
, common = require("./common.js")
, log = require('./common.js').log
, async = require('async');
exports.runAllChecks = function(cb) {
async.series([
exports.IsAndroidHomeExported,
exports.IsJavaHomeExported
], cb);
};
exports.IsAndroidHomeExported = function(cb) {
var msg;
if (env.ANDROID_HOME === null) {
msg = 'ANDROID_HOME is not set';
log.fail(msg);
cb(msg, msg);
} else if (fs.existsSync(env.ANDROID_HOME)) {
msg = 'ANDROID_HOME is set to "' + env.ANDROID_HOME + '."';
log.pass(msg);
cb(null, msg);
} else {
msg = 'ANDROID_HOME is set but does not exist on the file system at "' + env.ANDROID_HOME + '"';
log.fail(msg);
cb(msg, msg);
}
};
exports.IsJavaHomeExported = function(cb) {
var msg;
if (env.JAVA_HOME === null) {
log.fail(msg);
msg = 'JAVA_HOME is not set';
cb(msg, msg);
} else if (fs.existsSync(env.JAVA_HOME)) {
msg = 'JAVA_HOME is set to "' + env.JAVA_HOME + '."';
log.pass(msg);
cb(null, msg);
} else {
msg = 'JAVA_HOME is set but does not exist on the file system at "' + env.JAVA_HOME + '"';
log.fail(msg);
cb(msg, msg);
}
};

84
lib/doctor/common.js Normal file
View File

@@ -0,0 +1,84 @@
"use strict";
var prompt = require("prompt")
, colors = require("colors");
prompt.message = '';
prompt.delimiter = '';
var log = {
pass : function(msg) {
console.log('\u2714 '.green + msg.white);
},
fail : function(msg) {
console.log('\u2716 '.red + msg.white);
},
warning : function(msg) {
console.log(msg.yellow);
},
error : function(msg) {
console.log(msg.red);
},
comment : function(msg) {
console.log(msg.cyan);
},
info : function(msg) {
console.log(msg.white);
},
verbose : function(msg) {
console.log(msg.grey);
},
debug : function(msg) {
console.log(msg.darkgrey);
}
};
exports.log = Object.create(log);
exports.exitDoctor = function() {
log.error("Appium-Doctor detected problems. Please fix and rerun Appium-Doctor.");
process.exit(-1);
};
exports.promptYesOrNo = function(message, yesCb, noCb) {
prompt.start();
var promptSchema = {
properties: {
continue: {
description: (message + ' (y/n) ').white,
delimiter: '',
type: 'string',
pattern: /^(y|n)/,
message: 'Please enter y or n!',
required: true
}
}
};
prompt.get(promptSchema, function(err, result) {
if (result.continue == 'y') {
yesCb();
} else {
noCb();
}
});
};
exports.promptForAnyKey = function(cb) {
prompt.start();
var promptSchema = {
properties: {
continue: {
description: 'Press any key to continue:'.white,
type: 'string'
}
}
};
prompt.get(promptSchema, function() {
cb();
});
};

90
lib/doctor/ios.js Normal file
View File

@@ -0,0 +1,90 @@
"use strict";
var path = require('path')
, fs = require('fs')
, env = process.env
, exec = require('child_process').exec
, common = require("./common.js")
, log = require('./common.js').log
, async = require('async');
exports.runAllChecks = function(cb) {
async.series([
exports.checkForXcode,
exports.checkForXcodeCommandLineTools
], cb);
};
exports.checkForXcode = function(cb) {
var msg;
exec("xcode-select -p", { maxBuffer: 524288}, function(err, stdout) {
if (err === null) {
var xcodePath = stdout.replace("\n","");
if(fs.existsSync(xcodePath)) {
msg = "Xcode is installed at " + xcodePath;
log.pass(msg);
cb(null, msg);
} else {
msg = "Xcode is not installed.";
log.fail(msg);
common.promptYesOrNo("Fix it?", function() {
exports.installXcode(cb);
}, function() {
cb(msg, msg);
});
}
} else {
msg = "Xcode is not installed: " + err;
log.fail(msg);
common.promptYesOrNo("Fix it?", function() {
exports.installXcode(cb);
}, function() {
cb(msg, msg);
});
}
});
};
exports.checkForXcodeCommandLineTools = function(cb) {
var msg;
exec("pkgutil --pkg-info=com.apple.pkg.CLTools_Executables", { maxBuffer: 524288}, function(err, stdout) {
if (err === null) {
var match = stdout.match(/install-time/);
if (match !== null) {
msg = "Xcode Command Line Tools are installed.";
cb(null, msg);
} else {
msg = "Xcode Command Line Tools are NOT installed.";
log.fail(msg);
common.promptYesOrNo("Fix it?", function() {
exports.installXcodeCommandLineTools(cb);
}, function() {
cb(msg, msg);
});
}
} else {
msg = "Xcode Command Line Tools are NOT installed: " + err;
log.fail(msg);
common.promptYesOrNo("Fix it?", function() {
exports.installXcodeCommandLineTools(cb);
}, function() {
cb(msg, msg);
});
}
});
};
exports.installXcode = function(cb) {
exec("xcode-select --install", { maxBuffer: 524288}, function() {
common.promptForAnyKey(function() {
exports.checkForXcode(cb);
});
});
};
exports.installXcodeCommandLineTools = function(cb) {
exec("xcode-select --install", { maxBuffer: 524288}, function() {
common.promptForAnyKey(function() {
exports.checkForXcodeCommandLineTools(cb);
});
});
};

View File

@@ -26,6 +26,7 @@
"main": "./lib/server/main.js",
"bin": {
"appium": "./bin/appium.js",
"appium-doctor": "./bin/appium-doctor.js",
"instruments_client": "./bin/instruments-client.js",
"authorize_ios": "./bin/authorize-ios.js"
},