Skip to content

Commit

Permalink
Adding @nplus11's work on Rust init
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyman727 committed May 11, 2016
1 parent 24fdd7d commit ce6c70e
Show file tree
Hide file tree
Showing 15 changed files with 514 additions and 77 deletions.
14 changes: 13 additions & 1 deletion bin/tessel-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,24 @@ makeCommand('list')
.help('Lists all connected Tessels and their authorization status.');

parser.command('init')
.callback(init)
// .callback(init)
.callback((opts) => {
// We have to wrap the function in an anonymous callback
// or nomnom shields it from being stubbed for unit tests
return init.initProject(opts)
.then(module.exports.closeSuccessfulCommand, module.exports.closeFailedCommand);
})
.option('interactive', {
flag: true,
abbr: 'i',
help: 'Run in interactive mode'
})
.option('lang', {
metavar: 'LANG',
abbr: 'l',
default: 'js',
help: 'The language to use <javascript|rust|js|rs>. Javascript by default'
})
.help('Initialize repository for your Tessel project');

makeCommand('wifi')
Expand Down
59 changes: 59 additions & 0 deletions lib/init/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// System Objects
var path = require('path');
// Third Party Dependencies

// Internal
var languages = {
js: require('./javascript'),
rs: require('./rust'),
py: require('./python'),
};

var exportables = {};

// Initialize the directory given the various options
exportables.initProject = (opts) => {

// Set a default directory if one was not provided
opts.directory = opts.directory || path.resolve('.');

// Detect the requested language
var lang = exportables.detectLanguage(opts);

// If a language could not be detected
if (lang === null) {
// Return an error
return Promise.reject(new Error('Unrecognized language selection.'));
} else {
// Otherwise generate a project in that language
return lang.generateProject(opts);
}
};

// Determine the langauge to initialize the project with
exportables.detectLanguage = (opts) => {

// If somehow a language option wasn't provided
if (!opts.lang) {
// Return JS as default
return languages['js'];
}

// Iterate through each of the langauges
for (var key in languages) {
// Pull out the language info
var lang = languages[key];

// Check if the language option is within the available language keywords
if (lang.meta.keywords &&
lang.meta.keywords.indexOf(opts.lang.toLowerCase()) > -1) {
// If it is, return that language
return lang;
}
}

// If not, someone has requested a language that is not supported
return null;
};

module.exports = exportables;
148 changes: 75 additions & 73 deletions lib/init.js → lib/init/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ var PZ = require('promzard').PromZard;
var NPM = require('npm');

// Internal
// ...
var logs = require('../logs');

var packageJson = path.resolve('./package.json');

var pkg, ctx, options;

function loadNpm() {
var exportables = {};

exportables.meta = {
keywords: ['javascript', 'js']
};

exportables.loadNpm = () => {
// You have to load npm in order to use it programatically
return new Promise(function(resolve, reject) {
NPM.load(function(error, npm) {
Expand All @@ -23,22 +30,24 @@ function loadNpm() {
resolve(npm);
});
});
}
};

function getNpmConfig(npm) {
// Resolve an npm cofig list, or nothing (existance is not needed)
exportables.getNpmConfig = (npm) => {
// Always resolve, we don't care if there isn't an npm config.
return Promise.resolve(npm.config.list || {});
}
};

function buildJSON(npmConfig) {
// Builds the package.json file and writes it to the directory
exportables.buildJSON = (npmConfig) => {
return new Promise(function(resolve, reject) {
// Path to promzard config file
var promzardConfig;
ctx.config = npmConfig;
// Default to auto config
promzardConfig = path.resolve(__dirname + '/../', 'resources/init-default.js');
promzardConfig = path.resolve(__dirname, './../../', 'resources/javascript/init-default.js');
if (options.interactive) {
promzardConfig = path.resolve(__dirname + '/../', 'resources/init-config.js');
promzardConfig = path.resolve(__dirname, '/../../', 'resources/javascript/init-config.js');
}

// Init promozard with appropriate config.
Expand All @@ -55,7 +64,7 @@ function buildJSON(npmConfig) {
}
});

console.log('Created package.json.');
logs.info('Created package.json.');
resolve(data);
});

Expand All @@ -64,9 +73,10 @@ function buildJSON(npmConfig) {
reject(error);
});
});
}
};

function getDependencies(pkg) {
// Returns the dependencies of the package.json file
exportables.getDependencies = (pkg) => {
if (!pkg.dependencies) {
return [];
}
Expand All @@ -75,76 +85,67 @@ function getDependencies(pkg) {
dependencies.push(mod + '@' + pkg.dependencies[mod]);
}
return dependencies;
}
};

// Installs npm and dependencies
exportables.npmInstall = (dependencies) => {
return new Promise((resolve, reject) => {

function npmInstall(dependencies) {
return new Promise(function(resolve, reject) {
// Install the dependencies
// If there are no depencencies resolve
if (!dependencies.length) {
return resolve();
}

// Load npm to get the npm object
loadNpm()
.then(function(npm) {
// load npm to get the npm object
exportables.loadNpm()
.then((npm) => {
npm.commands.install(dependencies, function(error) {
if (error) {
reject(error);
}
resolve();
});

});
});
}

function generateSample() {
var filename = 'index.js';

// If an index.js already exists
fs.exists(filename, function(exists) {
// just return
if (exists) {
return;
}
};

// If not and rust was requested
if (options.rust) {
// Place the rust example
filename = 'index.rs';
}
// If python was requested
if (options.python) {
// Place the python example
filename = 'index.py';
}
// // Generates blinky for JavaScript
exportables.generateJavaScriptSample = () => {
return new Promise((resolve) => {
var filename = 'index.js';
// If an index.js already exists
fs.exists(filename, function(exists) {
// just return
if (exists) {
return resolve();
}

// Pipe the contents of the default file into a new file
fs.createReadStream(path.resolve(__dirname + './../resources/' + filename))
.pipe(fs.createWriteStream(filename));
// Pipe the contents of the default file into a new file
fs.createReadStream(path.resolve(__dirname, './../../', 'resources/javascript', filename))
.pipe(fs.createWriteStream(filename));

console.log('Wrote "Hello World" to index.js');
logs.info('Wrote "Hello World" to index.js');
return resolve();
});
});
}
};

function createTesselinclude() {
exportables.createTesselinclude = () => {
var tesselinclude = '.tesselinclude';

return new Promise((resolve) => {
fs.exists(tesselinclude, (exists) => {
if (exists) {
return resolve();
}

fs.copySync(path.resolve(__dirname + './../resources/' + tesselinclude), tesselinclude);
console.log('Created .tesselinclude.');
fs.copySync(path.resolve(__dirname, './../../', 'resources/javascript', tesselinclude), tesselinclude);
logs.info('Created .tesselinclude.');
resolve();
});
});
}
};

function readPackageJson() {
exportables.readPackageJson = () => {
return new Promise(function(resolve, reject) {
fs.readFile(packageJson, 'utf8', function(err, data) {
if (err) {
Expand All @@ -154,31 +155,30 @@ function readPackageJson() {
resolve(data);
});
});
}
};

function writePackageJson(data) {
exportables.writePackageJson = (data) => {
return new Promise(function(resolve, reject) {
fs.writeFile(packageJson, data, function(err) {
if (err) {
return reject(err);
}

resolve();
});
});
}
};

function prettyPrintJson(data) {
exportables.prettyPrintJson = (data) => {
return JSON.stringify(data, null, 2);
}
};

module.exports = function(opts) {
// Set interactive boolean off of CLI flags
options = opts;
exportables.generateProject = (opts) => {

console.log('Initializing Tessel 2 Project...');
// Make the options global
options = opts;

readPackageJson()
logs.info('Initializing new Tessel project for JavaScript...');
return exportables.readPackageJson()
.then(function(data) {

// Try to parse current package JSON
Expand All @@ -204,18 +204,20 @@ module.exports = function(opts) {
ctx.version = undefined;
return ctx;
})
.then(loadNpm)
.then(getNpmConfig)
.then(buildJSON)
.then(prettyPrintJson)
.then(writePackageJson)
.then(readPackageJson)
.then(exportables.loadNpm)
.then(exportables.getNpmConfig)
.then(exportables.buildJSON)
.then(exportables.prettyPrintJson)
.then(exportables.writePackageJson)
.then(exportables.readPackageJson)
.then(JSON.parse)
.then(getDependencies)
.then(npmInstall)
.then(createTesselinclude)
.then(generateSample)
.then(exportables.getDependencies)
.then(exportables.npmInstall)
.then(exportables.createTesselinclude)
.then(exportables.generateJavaScriptSample)
.catch(function(error) {
console.error(error);
logs.error(error);
});
};

module.exports = exportables;
18 changes: 18 additions & 0 deletions lib/init/python.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// System Objects

// Third Party Dependencies

// Internal
var logs = require('../logs');

var exportables = {};

exportables.meta = {
keywords: ['py', 'python']
};

exportables.generateProject = () => {
logs.info(`Sorry, Python project generation isn't implemented yet. Contributions welcome!`);
};

module.exports = exportables;
Loading

0 comments on commit ce6c70e

Please sign in to comment.