Skip to content

Commit

Permalink
Initial support for private git dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
svanderburg committed Jan 5, 2018
1 parent caf5d68 commit 0ca808c
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 7 deletions.
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Table of Contents
- [Adding unspecified dependencies](#adding-unspecified-dependencies)
- [Adding additional/global NPM packages to a packaging process](#adding-additionalglobal-npm-packages-to-a-packaging-process)
- [Disabling running NPM install](#disabling-running-npm-install)
- [Using private Git repositories](#using-private-git-repositories)
- [API documentation](#api-documentation)
- [License](#license)
- [Acknowledgements](#acknowledgements)
Expand Down Expand Up @@ -482,6 +483,51 @@ By overriding a package and setting the `dontNpmInstall` parameter to `true`, we
skip the install step (which merely serves as a check). The generated expression
is actually responsible for obtaining and extracting the dependencies.

Using private Git repositories
------------------------------
In some development projects, it may be desired to deploy private Git
repositories as dependencies. The `fetchgit {}` function in Nixpkgs, however,
only supports public repositories.

It is also possible to instruct the generator to use the `fetchgitPrivate {}`
function, that adds support for private repositories that can be reached with
SSH:

```bash
node2nix --use-fetchgit-private
```

Before running the `node2nix` command shown above, you probably want to set
up `ssh-agent` first and use `ssh-add` to add a private key to the keychain to
prevent the generator from asking for passphrases.

When deploying a project or package, you need to pass an additional parameter
that provides an SSH configuration file with a reference to an identify file.
The following SSH config file (e.g. `~/ssh_config`) suffices for me:

```
StrictHostKeyChecking=no
UserKnownHostsFile /dev/null
IdentityFile ~/id_rsa
```

When deploying a package with Nix, you must propagate the location of the SSH
config file as a parameter:

```bash
$ nix-build -A package -I ssh-config-file=~/ssh_config
```

It is also possible to provide the location of the config file by adapting the
`NIX_PATH` environment variable, as opposed to using the `-I` parameter:

```bash
$ export NIX_PATH=ssh-config-file=~/ssh_config:$NIX_PATH
```

The above approach also makes it possible to deploy a NPM package with private
dependencies as part of a NixOS, NixOps or Disnix configuration.

API documentation
=================
This package includes API documentation, which can be generated with
Expand Down
10 changes: 8 additions & 2 deletions bin/node2nix.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ var switches = [
['--pkg-name NAME', 'Specifies the name of the Node.js package to use from Nixpkgs (defaults to: nodejs)'],
['--registry NAME', 'URL referring to the NPM packages registry. It defaults to the official NPM one, but can be overridden to support private registries'],
['--bypass-cache', 'Specifies that package builds need to bypass the content addressable cache (required for NPM 5.x)'],
['--no-copy-node-env', 'Do not create a copy of the Nix expression that builds NPM packages']
['--no-copy-node-env', 'Do not create a copy of the Nix expression that builds NPM packages'],
['--use-fetchgit-private', 'Use fetchGitPrivate instead of fetchgit in the generated Nix expressions']
];

var parser = new optparse.OptionParser(switches);
Expand All @@ -48,6 +49,7 @@ var registryURL = "http://registry.npmjs.org";
var nodePackage = "nodejs-4_x";
var noCopyNodeEnv = false;
var bypassCache = false;
var useFetchGitPrivate = false;
var executable;

/* Define process rules for option parameters */
Expand Down Expand Up @@ -131,6 +133,10 @@ parser.on('no-copy-node-env', function(arg, value) {
noCopyNodeEnv = true;
});

parser.on('use-fetchgit-private', function(arg, value) {
useFetchGitPrivate = true;
});

/* Define process rules for non-option parameters */

parser.on(1, function(opt) {
Expand Down Expand Up @@ -193,7 +199,7 @@ if(version) {
}

/* Perform the NPM to Nix conversion */
node2nix.npmToNix(inputJSON, outputNix, compositionNix, nodeEnvNix, lockJSON, supplementJSON, supplementNix, production, includePeerDependencies, flatten, nodePackage, registryURL, noCopyNodeEnv, bypassCache, function(err) {
node2nix.npmToNix(inputJSON, outputNix, compositionNix, nodeEnvNix, lockJSON, supplementJSON, supplementNix, production, includePeerDependencies, flatten, nodePackage, registryURL, noCopyNodeEnv, bypassCache, useFetchGitPrivate, function(err) {
if(err) {
process.stderr.write(err + "\n");
process.exit(1);
Expand Down
34 changes: 31 additions & 3 deletions lib/expressions/CompositionExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,29 @@ function composePathRelativeToCompositionExpression(compositionNix, exprNix) {
return prefixRelativePath(path.relative(path.dirname(compositionNix), exprNix));
}

function CompositionExpression(compositionNix, nodePackage, nodeEnvNix, packagesNix, supplementNix, generateSupplement) {
/**
* Creates a new composition expression instance.
*
* @class CompositionExpression
* @extends NixASTNode
* @classdesc Represents an expression that composes NPM packages
*
* @constructor
* @param {String} compositionNix Path to which the generated composition expression is written
* @param {String} nodePackage Name of the Node.js package to use from Nixpkgs
* @param {String} nodeEnvNix Path to which the NPM package build expression is written
* @param {String} packagesNix Path to a Nix expression containing packages and sources
* @param {String} supplementNix Path to which the generated supplement expression is written
* @param {Boolean} generateSupplement Indicates whether we need a reference to a supplement Nix expression
* @param {Boolean} useFetchGitPrivate Indicates that the fetchgitPrivate function should be used instead of fetchgit
*/
function CompositionExpression(compositionNix, nodePackage, nodeEnvNix, packagesNix, supplementNix, generateSupplement, useFetchGitPrivate) {
this.nodePackage = nodePackage;
this.nodeEnvNixPath = composePathRelativeToCompositionExpression(compositionNix, nodeEnvNix);
this.packagesNixPath = composePathRelativeToCompositionExpression(compositionNix, packagesNix);
this.supplementNix = supplementNix;
this.generateSupplement = generateSupplement;
this.useFetchGitPrivate = useFetchGitPrivate;
}

/* CompositionExpression inherits from NixASTNode */
Expand All @@ -34,6 +51,17 @@ inherit(nijs.NixASTNode, CompositionExpression);
*/
CompositionExpression.prototype.toNixAST = function() {
var globalBuildInputs;
var fetchgitAttr;

// Determine which fetchgit function to use
if(this.useFetchGitPrivate) {
fetchgitAttr = new nijs.NixAttrReference({
attrSetExpr: new nijs.NixExpression("pkgs"),
refExpr: new nijs.NixExpression("fetchgitPrivate")
});
} else {
fetchgitAttr = new nijs.NixInherit("pkgs");
}

if(this.generateSupplement) {
var supplementNixPath = prefixRelativePath(this.supplementNix);
Expand All @@ -45,7 +73,7 @@ CompositionExpression.prototype.toNixAST = function() {
paramExpr: {
nodeEnv: new nijs.NixInherit(),
fetchurl: new nijs.NixInherit("pkgs"),
fetchgit: new nijs.NixInherit("pkgs")
fetchgit: fetchgitAttr
}
})
});
Expand Down Expand Up @@ -88,7 +116,7 @@ CompositionExpression.prototype.toNixAST = function() {
funExpr: new nijs.NixImport(new nijs.NixFile({ value: this.packagesNixPath })),
paramExpr: {
fetchurl: new nijs.NixInherit("pkgs"),
fetchgit: new nijs.NixInherit("pkgs"),
fetchgit: fetchgitAttr,
nodeEnv: new nijs.NixInherit(),
globalBuildInputs: globalBuildInputs ? new nijs.NixInherit() : undefined
}
Expand Down
5 changes: 3 additions & 2 deletions lib/node2nix.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function copyNodeEnvExpr(nodeEnvNix, callback) {
*/
exports.copyNodeEnvExpr = copyNodeEnvExpr;

function npmToNix(inputJSON, outputNix, compositionNix, nodeEnvNix, lockJSON, supplementJSON, supplementNix, production, includePeerDependencies, flatten, nodePackage, registryURL, noCopyNodeEnv, bypassCache, callback) {
function npmToNix(inputJSON, outputNix, compositionNix, nodeEnvNix, lockJSON, supplementJSON, supplementNix, production, includePeerDependencies, flatten, nodePackage, registryURL, noCopyNodeEnv, bypassCache, useFetchGitPrivate, callback) {
var obj = JSON.parse(fs.readFileSync(inputJSON));
var version = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"))).version;
var disclaimer = "# This file has been generated by node2nix " + version + ". Do not edit!\n\n";
Expand Down Expand Up @@ -121,7 +121,7 @@ function npmToNix(inputJSON, outputNix, compositionNix, nodeEnvNix, lockJSON, su

/* Generate and write a Nix composition expression to the specified output file */
function(callback) {
expr = new CompositionExpression(compositionNix, nodePackage, nodeEnvNix, outputNix, supplementNix, (supplementJSON !== undefined));
expr = new CompositionExpression(compositionNix, nodePackage, nodeEnvNix, outputNix, supplementNix, (supplementJSON !== undefined), useFetchGitPrivate);
fs.writeFile(compositionNix, disclaimer + nijs.jsToNix(expr, true), callback);
},

Expand Down Expand Up @@ -154,6 +154,7 @@ function npmToNix(inputJSON, outputNix, compositionNix, nodeEnvNix, lockJSON, su
* @param {String} registryURL URL of the NPM registry
* @param {Boolean} noCopyNodeEnv Indicates that no copy of the NPM package build expression should be made
* @param {Boolean} bypassCache Indicates that the content addressable cache should be bypassed
* @param {Boolean} useFetchGitPrivate Indicates that the fetchgitPrivate function should be used instead of fetchgit
* @param {function(String, String)} callback Callback function that gets invoked when the work is done.
* If an error occurs, the error parameter is set to contain the error
* If the operation succeeds, it returns a string containing the registry expression containing the packages and all its dependencies
Expand Down

0 comments on commit 0ca808c

Please sign in to comment.