Skip to content

Commit

Permalink
Appium Doctor Start
Browse files Browse the repository at this point in the history
This is a basic vesion of Appium Doctor that checks for Xcode, Xcode
Command Line Tools, JAVA_HOME, and ANDROID_HOME
  • Loading branch information
penguinho committed Nov 26, 2013
1 parent 60ea4c3 commit 3bc4cd5
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
59 changes: 59 additions & 0 deletions bin/appium-doctor.js
Original file line number Diff line number Diff line change
@@ -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();
}
});
}
2 changes: 2 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
49 changes: 49 additions & 0 deletions lib/doctor/android.js
Original file line number Diff line number Diff line change
@@ -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 changes: 84 additions & 0 deletions lib/doctor/common.js
Original file line number Diff line number Diff line change
@@ -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 changes: 90 additions & 0 deletions lib/doctor/ios.js
Original file line number Diff line number Diff line change
@@ -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);
});
});
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down

0 comments on commit 3bc4cd5

Please sign in to comment.