Merge pull request #12 from balajikris/PackageBrowsing

Add first version of package browsing experience
This commit is contained in:
Balaji Krishnan 2017-03-15 16:37:54 -07:00 коммит произвёл GitHub
Родитель c0ccbaa7aa 045a3e0c9f
Коммит f66a9a0f3f
10 изменённых файлов: 193 добавлений и 21 удалений

Просмотреть файл

@ -28,6 +28,10 @@ This extension provides tools for NodeJs developers working with Azure SDKs.
![Snippets](resources/help/snippets.gif)
### Package browsing
![Package browsing](resources/help/package-browsing.gif)
### Code generation
#### 1. template deployment

Просмотреть файл

@ -1,5 +1,11 @@
# Change Log for Azure Node Essentials
## 0.2.5 [2017-03-10]
1. Package browsing for azure sdks.
1. auto install packages if any were added to package.json by running npm install in the background.
1. Some bug fixes.
## 0.2.4 [2017-02-11]
1. re-organized source code folder structure and refactored source code

Просмотреть файл

@ -45,12 +45,18 @@
"command": "Azure-Node.template-deploy",
"title": "Generate code for template deployment",
"category": "Azure-Node"
},
{
"command": "Azure-Node.browse-packages",
"title": "Browse Azure-SDK packages",
"category": "Azure-Node"
}
]
},
"scripts": {},
"dependencies": {
"npm": "*",
"npm-user-packages": "^2.0.0",
"escodegen": "^1.8.1",
"esprima": "^3.1.3"
},

Двоичные данные
resources/help/package-browsing.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 452 KiB

Просмотреть файл

@ -0,0 +1,5 @@
var codegenerator = require('./codegen');
exports.generateRequireStatements = function generateRequireStatements(document, modules) {
return codegenerator.generateRequireStatements(document, modules);
};

Просмотреть файл

@ -6,7 +6,6 @@ const deployTemplateFunctionName = 'deployTemplate';
exports.deployTemplate = function deployTemplate() {
var text = `function ${deployTemplateFunctionName}(credentials, callback){\
// TODO: initialize these variables
var subscriptionId;\
var resourceGroupName;\
var deploymentName;\
var templateFilePath;\
@ -23,7 +22,7 @@ exports.deployTemplate = function deployTemplate() {
template = JSON.parse(fs.readFileSync(templateFilePath));\
templateParameters = JSON.parse(fs.readFileSync(templateParametersFilePath));\
} catch (error) {\
console.error('Encountered error parsing template file:', error);\
callback(error);\
}\
\r\n
var resourceClient = new ResourceManagement.ResourceManagementClient(credentials, subscriptionId);\
@ -39,7 +38,10 @@ exports.generateRequireStatements = function generateRequireStatements(document)
};
exports.deployTemplateCallSite = function deployTemplateCallSite() {
var text = `${deployTemplateFunctionName}(credentials, function(err, result){ });`;
var text = `${deployTemplateFunctionName}(credentials, function(err, result){\
if(err) return console.log(err);\
console.log('template deployed to azure!');\
});`;
return codegenerator.generateCode(text);
};

Просмотреть файл

@ -0,0 +1,80 @@
var fs = require('fs');
var path = require('path');
var vscode = require('vscode');
var npmUserPackages = require('npm-user-packages');
var jsonEditor = require('../codegen/jsoneditor');
var utils = require('../utils');
var codegen = require('../codegen/codegen.browse-packages');
exports.createCommand = function createCommand() {
vscode.commands.registerCommand('Azure-Node.browse-packages', function () {
npmUserPackages('windowsazure').then(data => {
var pkgs = [];
data.forEach(function (item) {
pkgs.push({ "label": item.name, "description": item.version, "detail": item.description });
});
vscode.window.showQuickPick(pkgs).then((selectedItem) => {
if(!selectedItem){
return;
}
updatePackageJsonAndNpmInstall(selectedItem.label);
if (!vscode.window.activeTextEditor) {
return;
}
return generateCodeInEditor(selectedItem.label);
});
});
});
};
function updatePackageJsonAndNpmInstall(packageToAdd) {
var filePath = utils.getPackageJsonPath();
if (filePath && fs.existsSync(filePath)) {
var packages = [packageToAdd];
jsonEditor.addDependenciesIfRequired(filePath, packages);
// TODO: run npm-install only if package.json was touched
var npmOptions = {
prefix: filePath.slice(0, filePath.lastIndexOf(path.sep))
};
var installTask = utils.npmInstall(packages, npmOptions);
return installTask.then(
function onFulfilled() {
vscode.window.setStatusBarMessage(`npm install succeeded for ${packageToAdd}.`);
},
function onRejected() {
vscode.window.setStatusBarMessage(`npm install failed for ${packageToAdd}.`);
}
);
}
};
function generateCodeInEditor(moduleName) {
// generate code to be inserted.
const document = vscode.window.activeTextEditor.document;
var importsAndLineNumber = codegen.generateRequireStatements(document, [moduleName]);
vscode.window.activeTextEditor.edit((builder) => {
// insert import statements.
// Insertion point is the line where import group ends.
if (importsAndLineNumber) {
var importPos = new vscode.Position(importsAndLineNumber.line, 0);
var imports = importsAndLineNumber.code;
for (var importStatement of imports) {
builder.insert(importPos, importStatement);
}
}
});
// format the entire document.
// the code we inserted was generated as well-formatted but indenting is relative to the existing text
// in the document. Since we didn't examine existing text and are unaware of the indent depth where
// generated code will be inserted, we have to reformat the whole document. If this leads to performance issues, we'll revisit this logic.
return vscode.commands.executeCommand("editor.action.formatDocument");
};

Просмотреть файл

@ -3,6 +3,7 @@ var path = require('path');
var vscode = require('vscode');
var codegen = require('../codegen/codgen.template-deploy');
var jsonEditor = require('../codegen/jsoneditor');
var utils = require('../utils');
exports.createCommand = function createCommand() {
vscode.commands.registerCommand('Azure-Node.template-deploy', function () {
@ -13,20 +14,34 @@ exports.createCommand = function createCommand() {
}
// update package.json
updatePackageJson();
updatePackageJsonAndNpmInstall();
// generate code in current document
return generateCodeInEditor();
});
};
function updatePackageJson() {
// TODO: search rootDir\package.json
var filePath = path.join(vscode.workspace.rootPath, 'package.json');
function updatePackageJsonAndNpmInstall() {
var filePath = utils.getPackageJsonPath();
if (fs.existsSync(filePath)) {
if (filePath && fs.existsSync(filePath)) {
var packages = codegen.getPackageDependencies();
jsonEditor.addDependenciesIfRequired(filePath, packages);
// TODO: run npm-install only if package.json was touched
var npmOptions = {
prefix: filePath.slice(0, filePath.lastIndexOf(path.sep))
};
var installTask = utils.npmInstall(packages, npmOptions);
return installTask.then(
function onFulfilled() {
vscode.window.setStatusBarMessage(`npm install succeeded.`);
},
function onRejected() {
vscode.window.setStatusBarMessage(`npm install failed.`);
}
);
}
};

Просмотреть файл

@ -28,7 +28,7 @@ function ensureDependenciesAreInstalled() {
// Download and install template generator package.
var extensionName = 'Azure-Node-Essentials';
var generatorPackageName = 'generator-azure-node';
var generatorPackageVersion = '0.1.0';
var generatorPackageVersion = '0.1.1';
utils.isNodeInstalled().then(function (result) {
if (!result) {

Просмотреть файл

@ -1,19 +1,23 @@
var fs = require('fs');
var path = require('path');
var vscode = require('vscode');
let exec = require('child_process').exec;
var npm = require('npm');
// checks if there exists a valid installation of NodeJs on this machine
exports.isNodeInstalled = function isNodeInstalled() {
var cmdString = "node -v";
return new Promise(function (resolve, reject) {
exec(cmdString, (error, stdout) => {
if (error) {
return reject(error);
}
if (stdout.startsWith('v')) {
return resolve(true);
}
return resolve(false);
var cmdString = "node -v";
return new Promise(function (resolve, reject) {
exec(cmdString, (error, stdout) => {
if (error) {
return reject(error);
}
if (stdout.startsWith('v')) {
return resolve(true);
}
return resolve(false);
});
});
});
};
// lists all globally installed npm packages.
@ -70,7 +74,8 @@ exports.npmInstall = function npmInstall(packages, opts) {
var cmdString = "npm install " + packages.join(" ") + " "
+ (opts.global ? " -g" : "")
+ (opts.save ? " --save" : "")
+ (opts.saveDev ? " --saveDev" : "");
+ (opts.saveDev ? " --saveDev" : "")
+ (opts.prefix ? " --prefix " + opts.prefix : "");
return new Promise(function (resolve, reject) {
exec(cmdString, { cwd: opts.cwd ? opts.cwd : "/" }, (error) => {
@ -82,3 +87,52 @@ exports.npmInstall = function npmInstall(packages, opts) {
});
});
};
exports.getPackageJsonPath = function getPackageJsonPath() {
var dirAboveRoot = path.join(vscode.workspace.rootPath, '..');
var srcPath = getSourceLocation();
if (!srcPath) {
return;
}
var packageJsonPath;
while (srcPath !== dirAboveRoot) {
packageJsonPath = path.join(srcPath, 'package.json');
if (fs.existsSync(packageJsonPath)) {
return packageJsonPath;
}
else {
srcPath = path.join(srcPath, '..');
}
}
};
function getSourceLocation() {
var files = vscode.workspace.textDocuments.filter(item => item.isUntitled === false);
if (files) {
var sourceFile = files[0].fileName;
return sourceFile.slice(0, sourceFile.lastIndexOf('\\') + 1);
}
}
exports.install = function install(pkgName, options) {
var promise = new Promise(function (resolve, reject) {
if (!options) {
reject("options.prefix is required.");
}
npm.load(options, function (err) {
if (err) {
return reject(err);
}
npm.commands.install([pkgName + '@latest'], function (err, info) {
if (err) {
reject(err);
}
resolve(info);
});
});
});
return promise;
};