summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-01-09 16:45:32 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2015-01-09 16:45:32 +0000
commitb092a66c21cb977a872d2b45d8edec31d96eeb28 (patch)
tree3402b26fa0939782153090ad1d169b0073bf3122
parent45c31c5d34d5c98627af3953027a2a8a35adfce4 (diff)
parente0cf555d06901e8c83f5166b2731dab3a5f46072 (diff)
downloadimport-b092a66c21cb977a872d2b45d8edec31d96eeb28.tar.gz
Merge remote-tracking branch 'zara-github/trynew'
Reviewed-By: Jim MacArthur <jim.macarthur@codethink.co.uk> Reviewed-By: Sam Thursfield <sam.thursfield@codethink.co.uk>
-rw-r--r--README.npm21
-rw-r--r--baserockimport/app.py18
-rw-r--r--baserockimport/exts/importer_base.js24
-rwxr-xr-xbaserockimport/exts/npm.find_deps91
-rwxr-xr-xbaserockimport/exts/npm.to_chunk72
-rwxr-xr-xbaserockimport/exts/npm.to_lorry51
6 files changed, 277 insertions, 0 deletions
diff --git a/README.npm b/README.npm
new file mode 100644
index 0000000..04a0ff6
--- /dev/null
+++ b/README.npm
@@ -0,0 +1,21 @@
+You need to set NODE_PATH=/usr/lib/node_modules/ to use this importer!!!!!
+eg: your command could look like:
+
+NODE_PATH=/usr/lib/node_modules/ baserock-import npm PACKAGENAME [version]
+
+The default (and strongly encouraged) behavour of npm is to install the
+modules that a program depends on inside the source tree of the project,
+in a subdirectory called 'node_modules'. The authors of npm are pretty
+against globally installing packages that other packages depend on. There
+is a 'install --global' option which seems to be only for programs that
+you want available in /usr/bin.
+
+npm's FAQ responds to the question of how to have globally installed
+packages, with "Write your own package manager, then. It´s not that hard.".
+OK! And we could have done that, but we found that by (ab)using the `npm build`
+command it's possible to get npm to install a package into
+/usr/lib/node_modules without installing its dependencies. This is consistent
+with how Baserock (and pretty much every other Linux distribution) tries
+to do things. Node.js doesn't seem to have a built-in 'look for modules here'
+path, so you'll need to set NODE_PATH=/usr/lib/node_modules when running
+programs that use the packages installed in the Baserock system.
diff --git a/baserockimport/app.py b/baserockimport/app.py
index 2ab2c87..cd3203e 100644
--- a/baserockimport/app.py
+++ b/baserockimport/app.py
@@ -78,6 +78,8 @@ class BaserockImportApplication(cliapp.Application):
return False
def setup(self):
+ self.add_subcommand('npm', self.import_npm,
+ arg_synopsis='PACKAGE [VERSION]')
self.add_subcommand('omnibus', self.import_omnibus,
arg_synopsis='REPO PROJECT_NAME SOFTWARE_NAME')
self.add_subcommand('rubygems', self.import_rubygems,
@@ -170,6 +172,22 @@ class BaserockImportApplication(cliapp.Application):
loop.enable_importer('rubygems')
loop.run()
+ def import_npm(self, args):
+ '''Import one or more Node.js npm packages.'''
+ if len(args) not in [1, 2]:
+ raise cliapp.AppException(
+ 'Please pass the name and version of an npm package on the '
+ 'commandline.')
+
+ goal_name = args[0]
+ goal_version = args[1] if len(args) == 2 else 'master'
+
+ loop = baserockimport.mainloop.ImportLoop(
+ app=self,
+ goal_kind='npm', goal_name=goal_name, goal_version=goal_version)
+ loop.enable_importer('npm', strata=['strata/nodejs.morph'])
+ loop.run()
+
def import_rubygems(self, args):
'''Import one or more RubyGems.'''
if len(args) not in [1, 2]:
diff --git a/baserockimport/exts/importer_base.js b/baserockimport/exts/importer_base.js
new file mode 100644
index 0000000..d7c84a3
--- /dev/null
+++ b/baserockimport/exts/importer_base.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2014 Codethink Limited
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+// Helper functions for Node.js / npm importer.
+
+exports.getFirstItem = function(info) {
+ if (Object.keys(info).length != 1)
+ throw(
+ util.format("Expected info object containing one item, got %j", info))
+ return info[Object.keys(info)[0]];
+}
+
diff --git a/baserockimport/exts/npm.find_deps b/baserockimport/exts/npm.find_deps
new file mode 100755
index 0000000..da2fc2c
--- /dev/null
+++ b/baserockimport/exts/npm.find_deps
@@ -0,0 +1,91 @@
+#!/usr/bin/env node
+//
+// Copyright (C) 2014 Codethink Limited
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+async = require("async");
+npm = require("npm");
+semver = require("semver");
+util = require("util");
+
+base = require("./importer_base");
+
+function parseArgs(argv) {
+ if (argv.length === 4)
+ return argv[3];
+
+ if (argv.length === 5)
+ return argv[3] + '@' + argv[4];
+
+ throw("Error! Wrong number of command line arguments! Usage: " +
+ "./npm.find_deps SOURCE_DIR NAME VERSION");
+}
+
+function getDeps(er, packageInfo) {
+ var names = [];
+ var ranges = {};
+ var resolved = {};
+
+ package = base.getFirstItem(packageInfo);
+
+ if (package.dependencies === undefined) {
+ showDeps({});
+ return;
+ }
+
+ names = Object.keys(package.dependencies);
+
+ for (name in package.dependencies)
+ ranges[name] = package.dependencies[name];
+
+ var resolveDepVersion = function(depName, cb) {
+ npm.commands.view([depName], "silent", function (er, packageInfoSet) {
+ if (er) throw er;
+
+ for (i in packageInfoSet) {
+ package = packageInfoSet[i];
+
+ resolved[package.name] = semver.maxSatisfying(package.versions, ranges[package.name]);
+ };
+
+ cb();
+ })
+ };
+
+ async.each(names, resolveDepVersion, function(er){
+ if (er) throw er;
+
+ showDeps(resolved);
+ })
+};
+
+function showDeps(runtimeDeps) {
+ var output = {
+ "npm": {
+ "build-dependencies": {},
+ "runtime-dependencies": runtimeDeps
+ }
+ };
+
+ outputText = JSON.stringify(output, null, 4);
+ console.log(outputText);
+}
+
+npm.load(function(er, npm) {
+ var package = parseArgs(process.argv);
+ if (er) throw er;
+ npm.commands.view([package], "silent", getDeps);
+});
+
diff --git a/baserockimport/exts/npm.to_chunk b/baserockimport/exts/npm.to_chunk
new file mode 100755
index 0000000..02a6ae5
--- /dev/null
+++ b/baserockimport/exts/npm.to_chunk
@@ -0,0 +1,72 @@
+#!/usr/bin/env node
+//
+// Copyright (C) 2014 Codethink Limited
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+YAML = require('yamljs');
+npm = require("npm");
+
+base = require("./importer_base");
+
+npm.load(function(er, npm) {
+ var packageName;
+ var packageVersion;
+ var packageFullName;
+
+ if (process.argv.length === 4) {
+ packageName = process.argv[3];
+ packageFullName = packageName;
+ } else if (process.argv.length === 5) {
+ packageName = process.argv[3];
+ packageVersion = process.argv[4];
+ packageFullName = packageName + '@' + packageVersion;
+ } else
+ throw("Error! Wrong number of command line arguments! Usage: " +
+ "./npm.to_chunk SOURCE_DIR NAME VERSION");
+
+ if (er) throw er;
+
+ npm.commands.view([packageFullName], "silent", getDescription);
+
+ function getDescription(er, packageInfo) {
+
+ if (er) throw er;
+
+ package = base.getFirstItem(packageInfo);
+ description = package.description;
+
+ description = description + " (morphology generated by baserock import tool)";
+ products = [];
+ configureCommands = [];
+ buildCommands = [];
+ installCommands = ['mkdir -p "$DESTDIR"/"$PREFIX"/lib/node_modules/' + packageName,
+ 'cp -a * "$DESTDIR"/"$PREFIX"/lib/node_modules/'+ packageName,
+ 'npm config set prefix "$DESTDIR"/"$PREFIX"',
+ 'npm config set unsafe-perm true',
+ 'cd "$DESTDIR"/"$PREFIX" && npm build --global --verbose "$DESTDIR"/"$PREFIX"/lib/node_modules/'+ packageName];
+
+ morphology = {
+ 'name' : packageFullName,
+ 'kind' : 'chunk',
+ 'description' : description,
+ 'build-system' : 'manual',
+ 'install-commands' : installCommands,
+ };
+
+ yamlString = YAML.stringify(morphology, 4);
+ console.log(yamlString);
+ };
+});
+
diff --git a/baserockimport/exts/npm.to_lorry b/baserockimport/exts/npm.to_lorry
new file mode 100755
index 0000000..ba0f442
--- /dev/null
+++ b/baserockimport/exts/npm.to_lorry
@@ -0,0 +1,51 @@
+#!/usr/bin/env node
+//
+// Copyright (C) 2014 Codethink Limited
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+npm = require("npm");
+
+base = require("./importer_base");
+
+npm.load(function(er, npm) {
+ if (process.argv.length === 3)
+ packageName = process.argv[2];
+ else
+ throw ("Error! Too many command line arguments! Usage: " +
+ "./npm.to_lorry PACKAGENAME");
+ if (er) throw er;
+
+ npm.commands.view([packageName], "silent", getRepo);
+
+ function getRepo(er, packageInfo){
+ if (er) throw er;
+
+ package = base.getFirstItem(packageInfo);
+
+ repoInfo = package.repository;
+ pathWithPkgName = "npm/" + packageName;
+
+ lorry = {};
+ lorry[pathWithPkgName] = {
+ "url": repoInfo["url"],
+ "type": repoInfo["type"],
+ "x-products-npm": [packageName]
+ };
+
+ outputText=JSON.stringify(lorry, null, 4);
+ console.log(outputText);
+ }
+});
+