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 Jun 16, 2016
1 parent 55978f1 commit 6099746
Show file tree
Hide file tree
Showing 16 changed files with 500 additions and 69 deletions.
8 changes: 7 additions & 1 deletion bin/tessel-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ if (!isRoot()) {
}
}

controller.t2Init = init;
controller.t2Init = init.initProject;

controller.crashReporter = function(options) {
var cr = Promise.resolve();
Expand Down Expand Up @@ -333,6 +333,12 @@ parser.command('init')
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
2 changes: 1 addition & 1 deletion lib/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ controller.renameTessel = function(opts) {
.then(function executeRename() {
return controller.standardTesselCommand(opts, function(tessel) {
log.info(`Renaming ${tessel.name} to ${opts.newName}`);
return tessel.rename(opts);
return tessel.rename(opts);
});
});
};
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) => {

This comment has been minimized.

Copy link
@rwaldron

rwaldron Jun 21, 2016

Contributor

Why is this detectLanguage when there is already precedent for resolveLanguage?


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

This comment has been minimized.

Copy link
@rwaldron

rwaldron Jun 21, 2016

Contributor

nit: why using ['js'] and not just 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;
133 changes: 66 additions & 67 deletions lib/init.js → lib/init/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ var PZ = require('promzard').PromZard;
var NPM = require('npm');

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

var log = require('../log');

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 @@ -24,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');

This comment has been minimized.

Copy link
@rwaldron

rwaldron Jun 21, 2016

Contributor

Why not just put the resources stuff at lib/init/resources/?

}

// Init promozard with appropriate config.
Expand All @@ -55,6 +63,7 @@ function buildJSON(npmConfig) {
pkg[k] = data[k];
}
});

log.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,79 +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() {
return new Promise(resolve => {
// // Generates blinky for JavaScript
exportables.generateJavaScriptSample = () => {

This comment has been minimized.

Copy link
@rwaldron

rwaldron Jun 21, 2016

Contributor

Since this is inside a file called javascript.js, I don't think it's necessary to call this generateJavaScriptSample. In fact, it's probably better for the entire feature if each init has a generateSample

return new Promise((resolve) => {
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';
return resolve();
}

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

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

function createTesselinclude() {
exportables.createTesselinclude = () => {
var tesselinclude = '.tesselinclude';
return new Promise((resolve) => {
fs.exists(tesselinclude, (exists) => {
if (exists) {
return resolve();
}

fs.copy(path.resolve(__dirname + './../resources/' + tesselinclude), tesselinclude, () => {
log.info('Created .tesselinclude.');
resolve();
});
fs.copySync(path.resolve(__dirname, './../../', 'resources/javascript', tesselinclude), tesselinclude);
log.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 @@ -157,9 +155,9 @@ function readPackageJson() {
resolve(data);
});
});
}
};

function writePackageJson(data) {
exportables.writePackageJson = (data) => {
return new Promise(function(resolve, reject) {
fs.writeFile(packageJson, data, function(err) {
if (err) {
Expand All @@ -168,19 +166,19 @@ function writePackageJson(data) {
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) => {

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

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

// Try to parse current package JSON
Expand All @@ -206,19 +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(() => {})
.catch((error) => {
.then(exportables.getDependencies)
.then(exportables.npmInstall)
.then(exportables.createTesselinclude)
.then(exportables.generateJavaScriptSample)
.catch(function(error) {
log.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 log = require('../log');

var exportables = {};

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

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

module.exports = exportables;

2 comments on commit 6099746

@rwaldron
Copy link
Contributor

@rwaldron rwaldron commented on 6099746 Jun 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should've been through some kind of review.

I see that it was reviewed, but I don't think that review was sufficient considering the broad issues that I'm finding throughout this patch.

@johnnyman727
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking this over again @rwaldron. Did #779 address all the issues you brought up here?

Please sign in to comment.