auto-pod
Version:
Automatically choose tunneling or direct connection for cocoapods. As easy as `pod` itself. Help you get rid of GFW of China.
215 lines • 7.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const cli = require("commander");
const child_process_1 = require("child_process");
const fs_1 = require("fs");
const yaml = require("js-yaml");
const path_1 = require("path");
const shell = require("shelljs");
const url = require("url");
const Logger_1 = require("./Logger");
const ProxyServer_1 = require("./ProxyServer");
let displayError = true;
const optionNames = [
'logLevel',
'config',
'debug',
'tunneling',
];
function getFileConfig(filePath) {
const absFile = path_1.resolve(process.cwd(), filePath);
if (!fs_1.existsSync(absFile)) {
Logger_1.getLogger()
.error('Cannot find auto-pod.yaml. You may also use another config file by "-c" param.');
throw new Error(`Cannot find ${absFile}`);
}
const content = fs_1.readFileSync(absFile).toString('utf8');
let config = null;
try {
config = yaml.safeLoad(content);
}
catch (err) {
Logger_1.getLogger().error(`invalid yaml content: ${err.message}`);
const error = new Error(`invalid yaml content: ${err.message}`);
// error.code = err.code;
throw error;
}
const fileConfig = {
excludes: config.excludes || [],
forceTunneling: false,
includes: config.includes || [],
proxies: [],
};
// Parse each proxies as providers.
if (!config.proxies || !(config.proxies instanceof Array)) {
Logger_1.getLogger()
.error('No proxies is set. Please provide us at least one element in `proxies` field.');
throw new Error("No proxies is set.");
}
if (config.proxies.length === 0) {
throw new Error("No proxies is provided.");
}
for (const proxy of config.proxies) {
let opts = {};
if ('string' === typeof proxy)
opts = url.parse(proxy);
// prefer `hostname` over `host`, because of `url.parse()`
opts.host = opts.hostname || opts.host;
// SOCKS doesn't *technically* have a default port, but this is
// the same default that `curl(1)` uses
opts.nport = +opts.port || 1080;
if (opts.host && opts.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete opts.path;
delete opts.pathname;
}
const originalLookup = opts.lookup;
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
opts.lookup = false;
switch (opts.protocol) {
case 'socks4:':
opts.lookup = true;
// pass through
case 'socks4a:':
opts.version = 4;
break;
case 'socks5:':
opts.lookup = true;
// pass through
case 'socks:': // no version specified, default to 5h
case 'socks5h:':
opts.version = 5;
break;
default:
throw new TypeError(`A "socks" protocol must be specified! Got: ${proxy.protocol}`);
}
if (opts.auth) {
const auth = opts.auth.split(':');
opts.authentication = { username: auth[0], password: auth[1] };
// opts.userid = auth[0];
}
// Set to manually set lookup value.
if (typeof originalLookup !== 'undefined') {
opts.lookup = !!originalLookup;
}
fileConfig.proxies.push(opts);
}
if ('force-tunneling' in config) {
fileConfig.forceTunneling = !!config['force-tunneling'];
}
return fileConfig;
}
exports.getFileConfig = getFileConfig;
function getOptionsArgs(args) {
const options = {};
optionNames.forEach((name) => {
if (Object.hasOwnProperty.apply(args, [name])) {
if (typeof args[name] !== 'string') {
throw new Error(`string "${name}" expected`);
}
options[name] = args[name];
}
});
return options;
}
exports.getOptionsArgs = getOptionsArgs;
function setUpGitProxy(port) {
shell.exec(`git config --global http.proxy http://127.0.0.1:${port}/`);
shell.exec(`git config --global https.proxy http://127.0.0.1:${port}/`);
}
exports.setUpGitProxy = setUpGitProxy;
function unsetGitProxy() {
shell.exec(`git config --unset --global http.proxy`);
shell.exec(`git config --unset --global https.proxy`);
}
exports.unsetGitProxy = unsetGitProxy;
function unsafeMain() {
const pkgJson = fs_1.readFileSync(`${__dirname}/../package.json`, 'utf-8');
const version = JSON.parse(pkgJson).version;
cli.version(version)
// .option('-s, --socks [socks]', 'specify your socks proxy host, default: 127.0.0.1:1080')
// .option('-p, --port [port]',
// 'specify the listening port of http proxy server, default: 8080')
// .option('-l, --host [host]',
// 'specify the listening host of http proxy server, default: 127.0.0.1')
.option('-c, --config [config]', 'read configs from file in json format')
.option('-t, --tunneling', 'Force tunneling all traffic through proxies.')
.option('--debug ', 'Enable debug mode')
.option('--level [level]', 'log level, vals: info, error')
.parse(process.argv);
const options = getOptionsArgs(cli);
if (!options.debug) {
displayError = false;
}
if (options.logLevel && typeof options.logLevel === 'string') {
Logger_1.init(options.logLevel);
}
// Find auto-pod.yaml.
const configFile = options.config || 'auto-pod.yaml';
const fileConfig = getFileConfig(configFile);
if (options.tunneling) {
// Overwrites force tunneling
fileConfig.forceTunneling = true;
}
// Startup the server.
const server = new ProxyServer_1.ProxyServer(fileConfig);
server.on('listening', () => {
// Get running port
const address = server.address();
Logger_1.getLogger().info(`Server listening on: ${address.address}:${address.port}`);
//
// Shell run the pod.
setUpGitProxy(address.port);
Logger_1.getLogger().info("Setup git proxy.");
// Run shelljs.
// shell.exec("pod")
// Copy the process env.
const env = JSON.parse(JSON.stringify(process.env));
env.http_proxy = `http://127.0.0.1:${address.port}`;
env.https_proxy = `http://127.0.0.1:${address.port}`;
Logger_1.getLogger().info("Starting pod...");
const pod = child_process_1.spawn('pod', cli.args, {
env,
shell: true,
stdio: 'pipe',
});
pod.stdout.on('data', (data) => {
process.stdout.write(data);
});
pod.stderr.on('data', (data) => {
process.stdout.write(data);
});
pod.on('close', (code) => {
if (code !== 0) {
Logger_1.getLogger().error('Failed to execute the pod.');
}
else {
Logger_1.getLogger().info("Pod finished.");
}
unsetGitProxy();
Logger_1.getLogger().info("Git proxy removed.");
// Stop the server
server.unref();
// Shutdown the http proxy server.
server.close();
});
});
// Listening at any random port.
server.listen({ host: '127.0.0.1', port: 0 });
}
function main() {
try {
unsafeMain();
}
catch (e) {
if (displayError) {
Logger_1.getLogger().error(e);
process.exit(1);
}
}
}
exports.main = main;
//# sourceMappingURL=cli.js.map