nixpkgs/pkgs/development/tools/yarn2nix-moretea/yarn2nix/lib/generateNix.js
2019-07-25 17:15:00 +02:00

124 lines
3.2 KiB
JavaScript

const R = require('ramda')
const urlToName = require('./urlToName')
const { execFileSync } = require('child_process')
// fetchgit transforms
//
// "shell-quote@git+https://github.com/srghma/node-shell-quote.git#without_unlicenced_jsonify":
// version "1.6.0"
// resolved "git+https://github.com/srghma/node-shell-quote.git#1234commit"
//
// to
//
// builtins.fetchGit {
// url = "https://github.com/srghma/node-shell-quote.git";
// ref = "without_unlicenced_jsonify";
// rev = "1234commit";
// }
//
// and transforms
//
// "@graphile/plugin-supporter@git+https://1234user:1234pass@git.graphile.com/git/users/1234user/postgraphile-supporter.git":
// version "0.6.0"
// resolved "git+https://1234user:1234pass@git.graphile.com/git/users/1234user/postgraphile-supporter.git#1234commit"
//
// to
//
// builtins.fetchGit {
// url = "https://1234user:1234pass@git.graphile.com/git/users/1234user/postgraphile-supporter.git";
// ref = "master";
// rev = "1234commit";
// }
function prefetchgit(url, rev) {
return JSON.parse(
execFileSync("nix-prefetch-git", ["--rev", rev, url], {
stdio: [ "ignore", "pipe", "ignore" ],
timeout: 60000,
})
).sha256
}
function fetchgit(fileName, url, rev, branch, builtinFetchGit) {
return ` {
name = "${fileName}";
path =
let${builtinFetchGit ? `
repo = builtins.fetchGit {
url = "${url}";
ref = "${branch}";
rev = "${rev}";
};
` : `
repo = fetchgit {
url = "${url}";
rev = "${rev}";
sha256 = "${prefetchgit(url, rev)}";
};
`}in
runCommandNoCC "${fileName}" { buildInputs = [gnutar]; } ''
# Set u+w because tar-fs can't unpack archives with read-only dirs
# https://github.com/mafintosh/tar-fs/issues/79
tar cf $out --mode u+w -C \${repo} .
'';
}`
}
function fetchLockedDep(builtinFetchGit) {
return function (pkg) {
const { nameWithVersion, resolved } = pkg
if (!resolved) {
console.error(
`yarn2nix: can't find "resolved" field for package ${nameWithVersion}, you probably required it using "file:...", this feature is not supported, ignoring`,
)
return ''
}
const [url, sha1OrRev] = resolved.split('#')
const fileName = urlToName(url)
if (url.startsWith('git+')) {
const rev = sha1OrRev
const [_, branch] = nameWithVersion.split('#')
const urlForGit = url.replace(/^git\+/, '')
return fetchgit(fileName, urlForGit, rev, branch || 'master', builtinFetchGit)
}
const sha = sha1OrRev
return ` {
name = "${fileName}";
path = fetchurl {
name = "${fileName}";
url = "${url}";
sha1 = "${sha}";
};
}`
}
}
const HEAD = `
{ fetchurl, fetchgit, linkFarm, runCommandNoCC, gnutar }: rec {
offline_cache = linkFarm "offline" packages;
packages = [
`.trim()
// Object -> String
function generateNix(pkgs, builtinFetchGit) {
const nameWithVersionAndPackageNix = R.map(fetchLockedDep(builtinFetchGit), pkgs)
const packagesDefinition = R.join(
'\n',
R.values(nameWithVersionAndPackageNix),
)
return R.join('\n', [HEAD, packagesDefinition, ' ];', '}'])
}
module.exports = generateNix