##// END OF EJS Templates
release: Merge default into stable for release preparation
marcink -
r802:f6088673 merge stable
parent child
Show More
Add another comment

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,15
1 {
2 "name": "rhodecode-elements",
3 "description": "User interface for elements for rhodecode",
4 "main": "index.html",
5 "dependencies": {
6 "webcomponentsjs": "^0.7.22",
7 "polymer": "Polymer/polymer#^1.6.1",
8 "paper-button": "PolymerElements/paper-button#^1.0.13",
9 "paper-spinner": "PolymerElements/paper-spinner#^1.2.0",
10 "paper-tooltip": "PolymerElements/paper-tooltip#^1.1.2",
11 "paper-toast": "PolymerElements/paper-toast#^1.3.0",
12 "paper-toggle-button": "PolymerElements/paper-toggle-button#^1.2.0",
13 "iron-ajax": "PolymerElements/iron-ajax#^1.4.3"
14 }
15 }
@@ -0,0 +1,60
1
2 =======================
3 Dependency management
4 =======================
5
6
7 Overview
8 ========
9
10 We use the Nix package manager to handle our dependencies. In general we use the
11 packages out of the package collection `nixpkgs`. For frequently changing
12 dependencies for Python and JavaScript we use the tools which are described in
13 this section to generate the needed Nix derivations.
14
15
16 Python dependencies
17 ===================
18
19 We use the tool `pip2nix` to generate the Nix derivations for our Python
20 dependencies.
21
22 Generating the dependencies should be done with the following command:
23
24 .. code:: shell
25
26 pip2nix generate --license
27
28
29 .. note::
30
31 License extraction support is still experimental, use the version from the
32 following pull request: https://github.com/ktosiek/pip2nix/pull/30
33
34
35
36 Node dependencies
37 =================
38
39 After adding new dependencies via ``npm install --save``, use `node2nix` to
40 update the corresponding Nix derivations:
41
42 .. code:: shell
43
44 cd pkgs
45 node2nix --input ../package.json \
46 -o node-packages.nix \
47 -e node-env.nix \
48 -c node-default.nix \
49 -d --flatten
50
51
52 Bower dependencies
53 ==================
54
55 Frontend dependencies are managed based on `bower`, with `bower2nix` a tool
56 exists which can generate the needed Nix derivations:
57
58 .. code:: shell
59
60 bower2nix bower.json pkgs/bower-packages.nix
@@ -0,0 +1,78
1 |RCE| 4.4.0 |RNS|
2 -----------------
3
4 Release Date
5 ^^^^^^^^^^^^
6
7 - 2016-09-16
8
9
10 General
11 ^^^^^^^
12
13 - UI: introduced Polymer webcomponents into core application. RhodeCode will
14 be now shipped together with Polymer framework webcomponents. Most of
15 dynamic UI components that require large amounts of interaction
16 will be done now with Polymer.
17 - live-notifications: use rhodecode-toast for live notifications instead of
18 toastr jquery plugin.
19 - Svn: moved svn http support out of labs settings. It's tested and stable now.
20
21
22 New Features
23 ^^^^^^^^^^^^
24
25 - Integrations: integrations can now be configure on whole repo group to apply
26 same integrations on multiple projects/groups at once.
27 - Integrations: added scopes on integrations, scopes are: Global,
28 Repository Group (with/without children), Repositories, Root Repositories Only.
29 It will allow to configure exactly which projects use which integrations.
30 - Integrations: show branches/commits separately when posting push events
31 to hipchat/slack, fixes #4192.
32 - Pull-requests: summary page now shows update dates for pull request to
33 easier see which one were receantly updated.
34 - UI: hidden inline comments will be shown in side view when browsing the diffs
35 - Diffs: added inline comments toggle into pull requests diff view. #2884
36 - Live-chat: added summon reviewers functionality. You can now request
37 presence from online users into a chat for collaborative code-review.
38 This requires channelstream to be enabled.
39 - UX: added a static 502 page for gateway error. Once configured via
40 Nginx or Apache it will present a custom RhodeCode page while
41 backend servers are offline. Fixes #4202.
42
43
44 Security
45 ^^^^^^^^
46
47 - Passwords: forced password change will not allow users to put in the
48 old password as new one.
49
50
51 Performance
52 ^^^^^^^^^^^
53
54 - Vcs: refactor vcs-middleware to handle order of .ini file backends in
55 detection of vcs protocol. Detection ends now on first match and speeds
56 overall transaction speed.
57 - Summary: Improve the algorithm and performance of detection README files
58 inside summary page. In some cases we reduced cold-cache time from 50s to 1s.
59 - Safari: improved speed of large diffs on Safari browser.
60 - UX: remove position relative on diff td as it causes very slow
61 rendering in browsers.
62
63 Fixes
64 ^^^^^
65
66 - UX: change confirm password widget to have spacing between the fields to
67 match rest of ui, fixes: #4200.
68 - UX: show multiple tags/branches in changelog/summary instead of
69 truncating them.
70 - My-account: fix test notifications for IE10+
71 - Vcs: change way refs are retrieved for git so same name branch/tags and
72 remotes can be supported, fixes #298.
73 - Lexers: added small extensions table to extend syntax highlighting for file
74 sources. Fixes #4227.
75 - Search: fix bug where file path link was wrong when the repository name was
76 in the file path, fixes #4228
77 - Fixed INT overflow bug
78 - Events: send pushed commits always in the correct in order.
@@ -0,0 +1,186
1 {
2 "dirs": {
3 "css": {
4 "src":"rhodecode/public/css",
5 "dest":"rhodecode/public/css"
6 },
7 "js": {
8 "src": "rhodecode/public/js/src",
9 "dest": "rhodecode/public/js"
10 }
11 },
12 "copy": {
13 "main": {
14 "expand": true,
15 "cwd": "bower_components",
16 "src": "webcomponentsjs/webcomponents-lite.js",
17 "dest": "<%= dirs.js.dest %>/vendors"
18 }
19 },
20 "concat": {
21 "polymercss": {
22 "src": [
23 "<%= dirs.js.src %>/components/root-styles-prefix.html",
24 "<%= dirs.css.src %>/style-polymer.css",
25 "<%= dirs.js.src %>/components/root-styles-suffix.html"
26 ],
27 "dest": "<%= dirs.js.dest %>/src/components/root-styles.gen.html",
28 "nonull": true
29 },
30 "dist": {
31 "src": [
32 "<%= dirs.js.src %>/jquery-1.11.1.min.js",
33 "<%= dirs.js.src %>/logging.js",
34 "<%= dirs.js.src %>/bootstrap.js",
35 "<%= dirs.js.src %>/mousetrap.js",
36 "<%= dirs.js.src %>/moment.js",
37 "<%= dirs.js.src %>/appenlight-client-0.4.1.min.js",
38 "<%= dirs.js.src %>/i18n_utils.js",
39 "<%= dirs.js.src %>/deform.js",
40 "<%= dirs.js.src %>/plugins/jquery.pjax.js",
41 "<%= dirs.js.src %>/plugins/jquery.dataTables.js",
42 "<%= dirs.js.src %>/plugins/flavoured_checkbox.js",
43 "<%= dirs.js.src %>/plugins/jquery.auto-grow-input.js",
44 "<%= dirs.js.src %>/plugins/jquery.autocomplete.js",
45 "<%= dirs.js.src %>/plugins/jquery.debounce.js",
46 "<%= dirs.js.src %>/plugins/jquery.mark.js",
47 "<%= dirs.js.src %>/plugins/jquery.timeago.js",
48 "<%= dirs.js.src %>/plugins/jquery.timeago-extension.js",
49 "<%= dirs.js.src %>/select2/select2.js",
50 "<%= dirs.js.src %>/codemirror/codemirror.js",
51 "<%= dirs.js.src %>/codemirror/codemirror_loadmode.js",
52 "<%= dirs.js.src %>/codemirror/codemirror_hint.js",
53 "<%= dirs.js.src %>/codemirror/codemirror_overlay.js",
54 "<%= dirs.js.src %>/codemirror/codemirror_placeholder.js",
55 "<%= dirs.js.dest %>/mode/meta.js",
56 "<%= dirs.js.dest %>/mode/meta_ext.js",
57 "<%= dirs.js.dest %>/rhodecode/i18n/select2/translations.js",
58 "<%= dirs.js.src %>/rhodecode/utils/array.js",
59 "<%= dirs.js.src %>/rhodecode/utils/string.js",
60 "<%= dirs.js.src %>/rhodecode/utils/pyroutes.js",
61 "<%= dirs.js.src %>/rhodecode/utils/ajax.js",
62 "<%= dirs.js.src %>/rhodecode/utils/autocomplete.js",
63 "<%= dirs.js.src %>/rhodecode/utils/colorgenerator.js",
64 "<%= dirs.js.src %>/rhodecode/utils/ie.js",
65 "<%= dirs.js.src %>/rhodecode/utils/os.js",
66 "<%= dirs.js.src %>/rhodecode/utils/topics.js",
67 "<%= dirs.js.src %>/rhodecode/widgets/multiselect.js",
68 "<%= dirs.js.src %>/rhodecode/init.js",
69 "<%= dirs.js.src %>/rhodecode/codemirror.js",
70 "<%= dirs.js.src %>/rhodecode/comments.js",
71 "<%= dirs.js.src %>/rhodecode/constants.js",
72 "<%= dirs.js.src %>/rhodecode/files.js",
73 "<%= dirs.js.src %>/rhodecode/followers.js",
74 "<%= dirs.js.src %>/rhodecode/menus.js",
75 "<%= dirs.js.src %>/rhodecode/notifications.js",
76 "<%= dirs.js.src %>/rhodecode/permissions.js",
77 "<%= dirs.js.src %>/rhodecode/pjax.js",
78 "<%= dirs.js.src %>/rhodecode/pullrequests.js",
79 "<%= dirs.js.src %>/rhodecode/settings.js",
80 "<%= dirs.js.src %>/rhodecode/select2_widgets.js",
81 "<%= dirs.js.src %>/rhodecode/tooltips.js",
82 "<%= dirs.js.src %>/rhodecode/users.js",
83 "<%= dirs.js.src %>/rhodecode/appenlight.js",
84 "<%= dirs.js.src %>/rhodecode.js"
85 ],
86 "dest": "<%= dirs.js.dest %>/scripts.js",
87 "nonull": true
88 }
89 },
90 "crisper": {
91 "dist": {
92 "options": {
93 "cleanup": false,
94 "onlySplit": true
95 },
96 "src": "<%= dirs.js.dest %>/rhodecode-components.html",
97 "dest": "<%= dirs.js.dest %>/rhodecode-components.js"
98 }
99 },
100 "less": {
101 "development": {
102 "options": {
103 "compress": false,
104 "yuicompress": false,
105 "optimization": 0
106 },
107 "files": {
108 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
109 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
110 }
111 },
112 "production": {
113 "options": {
114 "compress": true,
115 "yuicompress": true,
116 "optimization": 2
117 },
118 "files": {
119 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
120 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
121 }
122 },
123 "components": {
124 "files": [
125 {
126 "cwd": "<%= dirs.js.src %>/components/",
127 "dest": "<%= dirs.js.src %>/components/",
128 "src": [
129 "**/*.less"
130 ],
131 "expand": true,
132 "ext": ".css"
133 }
134 ]
135 }
136 },
137 "watch": {
138 "less": {
139 "files": [
140 "<%= dirs.css.src %>/**/*.less",
141 "<%= dirs.js.src %>/components/**/*.less"
142 ],
143 "tasks": [
144 "less:development",
145 "less:components",
146 "concat:polymercss",
147 "vulcanize"
148 ]
149 },
150 "js": {
151 "files": [
152 "!<%= dirs.js.src %>/components/root-styles.gen.html",
153 "<%= dirs.js.src %>/**/*.js",
154 "<%= dirs.js.src %>/components/**/*.html"
155 ],
156 "tasks": [
157 "less:components",
158 "concat:polymercss",
159 "vulcanize",
160 "crisper",
161 "concat:dist"
162 ]
163 }
164 },
165 "jshint": {
166 "rhodecode": {
167 "src": "<%= dirs.js.src %>/rhodecode/**/*.js",
168 "options": {
169 "jshintrc": ".jshintrc"
170 }
171 }
172 },
173 "vulcanize": {
174 "default": {
175 "options": {
176 "abspath": "",
177 "inlineScripts": true,
178 "inlineCss": true,
179 "stripComments": true
180 },
181 "files": {
182 "<%= dirs.js.dest %>/rhodecode-components.html": "<%= dirs.js.src %>/components/shared-components.html"
183 }
184 }
185 }
186 }
@@ -0,0 +1,67
1 # Backported buildBowerComponents so that we can also use it with the version
2 # 16.03 which is the current stable at the time of this writing.
3 #
4 # This file can be removed once building with 16.03 is not needed anymore.
5
6 { pkgs }:
7
8 { buildInputs ? [], generated, ... } @ attrs:
9
10 let
11 bower2nix-src = pkgs.fetchzip {
12 url = "https://github.com/rvl/bower2nix/archive/v3.0.1.tar.gz";
13 sha256 = "1zbvz96k2j6g0r4lvm5cgh41a73k9dgayk7x63cmg538dzznxvyb";
14 };
15
16 bower2nix = import "${bower2nix-src}/default.nix" { inherit pkgs; };
17
18 fetchbower = import ./backport-16.03-fetchbower.nix {
19 inherit (pkgs) stdenv lib;
20 inherit bower2nix;
21 };
22
23 # Fetches the bower packages. `generated` should be the result of a
24 # `bower2nix` command.
25 bowerPackages = import generated {
26 inherit (pkgs) buildEnv;
27 inherit fetchbower;
28 };
29
30 in pkgs.stdenv.mkDerivation (
31 attrs
32 //
33 {
34 name = "bower_components-" + attrs.name;
35
36 inherit bowerPackages;
37
38 builder = builtins.toFile "builder.sh" ''
39 source $stdenv/setup
40
41 # The project's bower.json is required
42 cp $src/bower.json .
43
44 # Dereference symlinks -- bower doesn't like them
45 cp --recursive --reflink=auto \
46 --dereference --no-preserve=mode \
47 $bowerPackages bc
48
49 # Bower install in offline mode -- links together the fetched
50 # bower packages.
51 HOME=$PWD bower \
52 --config.storage.packages=bc/packages \
53 --config.storage.registry=bc/registry \
54 --offline install
55
56 # Sets up a single bower_components directory within
57 # the output derivation.
58 mkdir -p $out
59 mv bower_components $out
60 '';
61
62 buildInputs = buildInputs ++ [
63 pkgs.git
64 pkgs.nodePackages.bower
65 ];
66 }
67 )
@@ -0,0 +1,26
1 { stdenv, lib, bower2nix }:
2 let
3 bowerVersion = version:
4 let
5 components = lib.splitString "#" version;
6 hash = lib.last components;
7 ver = if builtins.length components == 1 then version else hash;
8 in ver;
9
10 fetchbower = name: version: target: outputHash: stdenv.mkDerivation {
11 name = "${name}-${bowerVersion version}";
12 buildCommand = ''
13 fetch-bower --quiet --out=$PWD/out "${name}" "${target}" "${version}"
14 # In some cases, the result of fetchBower is different depending
15 # on the output directory (e.g. if the bower package contains
16 # symlinks). So use a local output directory before copying to
17 # $out.
18 cp -R out $out
19 '';
20 outputHashMode = "recursive";
21 outputHashAlgo = "sha256";
22 inherit outputHash;
23 buildInputs = [ bower2nix ];
24 };
25
26 in fetchbower
@@ -0,0 +1,31
1 { fetchbower, buildEnv }:
2 buildEnv { name = "bower-env"; ignoreCollisions = true; paths = [
3 (fetchbower "webcomponentsjs" "0.7.22" "^0.7.22" "0ggh3k8ssafd056ib1m5bvzi7cpz3ry7gr5176d79na1w0c3i7dz")
4 (fetchbower "polymer" "Polymer/polymer#1.6.1" "Polymer/polymer#^1.6.1" "09mm0jgk457gvwqlc155swch7gjr6fs3g7spnvhi6vh5b6518540")
5 (fetchbower "paper-button" "PolymerElements/paper-button#1.0.13" "PolymerElements/paper-button#^1.0.13" "0i3y153nqk06pn0gk282vyybnl3g1w3w41d5i9z659cgn27g3fvm")
6 (fetchbower "paper-spinner" "PolymerElements/paper-spinner#1.2.0" "PolymerElements/paper-spinner#^1.2.0" "1av1m6y81jw3hjhz1yqy3rwcgxarjzl58ldfn4q6sn51pgzngfqb")
7 (fetchbower "paper-tooltip" "PolymerElements/paper-tooltip#1.1.2" "PolymerElements/paper-tooltip#^1.1.2" "1j64nprcyk2d2bbl3qwjyr0lbjngm4wclpyfwgai1c4y6g6bigd2")
8 (fetchbower "paper-toast" "PolymerElements/paper-toast#1.3.0" "PolymerElements/paper-toast#^1.3.0" "0x9rqxsks5455s8pk4aikpp99ijdn6kxr9gvhwh99nbcqdzcxq1m")
9 (fetchbower "paper-toggle-button" "PolymerElements/paper-toggle-button#1.2.0" "PolymerElements/paper-toggle-button#^1.2.0" "0mphcng3ngspbpg4jjn0mb91nvr4xc1phq3qswib15h6sfww1b2w")
10 (fetchbower "iron-ajax" "PolymerElements/iron-ajax#1.4.3" "PolymerElements/iron-ajax#^1.4.3" "0m3dx27arwmlcp00b7n516sc5a51f40p9vapr1nvd57l3i3z0pzm")
11 (fetchbower "iron-flex-layout" "PolymerElements/iron-flex-layout#1.3.1" "PolymerElements/iron-flex-layout#^1.0.0" "0nswv3ih3bhflgcd2wjfmddqswzgqxb2xbq65jk9w3rkj26hplbl")
12 (fetchbower "paper-behaviors" "PolymerElements/paper-behaviors#1.0.12" "PolymerElements/paper-behaviors#^1.0.0" "012bqk97awgz55cn7rm9g7cckrdhkqhls3zvp8l6nd4rdwcrdzq8")
13 (fetchbower "paper-material" "PolymerElements/paper-material#1.0.6" "PolymerElements/paper-material#^1.0.0" "0rljmknfdbm5aabvx9pk77754zckj3l127c3mvnmwkpkkr353xnh")
14 (fetchbower "paper-styles" "PolymerElements/paper-styles#1.1.4" "PolymerElements/paper-styles#^1.0.0" "0j8vg74xrcxlni8i93dsab3y80f34kk30lv4yblqpkp9c3nrilf7")
15 (fetchbower "neon-animation" "PolymerElements/neon-animation#1.2.4" "PolymerElements/neon-animation#^1.0.0" "16mz9i2n5w0k5j8d6gha23cnbdgm5syz3fawyh89gdbq97bi2q5j")
16 (fetchbower "iron-a11y-announcer" "PolymerElements/iron-a11y-announcer#1.0.5" "PolymerElements/iron-a11y-announcer#^1.0.0" "0n7c7j1pwk3835s7s2jd9125wdcsqf216yi5gj07wn5s8h8p7m9d")
17 (fetchbower "iron-overlay-behavior" "PolymerElements/iron-overlay-behavior#1.8.6" "PolymerElements/iron-overlay-behavior#^1.0.9" "14brn9gz6qqskarg3fxk91xs7vg02vgcsz9a9743kidxr0l0413m")
18 (fetchbower "iron-fit-behavior" "PolymerElements/iron-fit-behavior#1.2.5" "PolymerElements/iron-fit-behavior#^1.1.0" "1msnlh8lp1xg6v4h6dkjwj9kzac5q5q208ayla3x9hi483ki6rlf")
19 (fetchbower "iron-checked-element-behavior" "PolymerElements/iron-checked-element-behavior#1.0.5" "PolymerElements/iron-checked-element-behavior#^1.0.0" "0l0yy4ah454s8bzfv076s8by7h67zy9ni6xb932qwyhx8br6c1m7")
20 (fetchbower "promise-polyfill" "polymerlabs/promise-polyfill#1.0.1" "polymerlabs/promise-polyfill#^1.0.0" "045bj2caav3famr5hhxgs1dx7n08r4s46mlzwb313vdy17is38xb")
21 (fetchbower "iron-behaviors" "PolymerElements/iron-behaviors#1.0.17" "PolymerElements/iron-behaviors#^1.0.0" "021qvkmbk32jrrmmphpmwgby4bzi5jyf47rh1bxmq2ip07ly4bpr")
22 (fetchbower "paper-ripple" "PolymerElements/paper-ripple#1.0.8" "PolymerElements/paper-ripple#^1.0.0" "0r9sq8ik7wwrw0qb82c3rw0c030ljwd3s466c9y4qbcrsbvfjnns")
23 (fetchbower "font-roboto" "PolymerElements/font-roboto#1.0.1" "PolymerElements/font-roboto#^1.0.1" "02jz43r0wkyr3yp7rq2rc08l5cwnsgca9fr54sr4rhsnl7cjpxrj")
24 (fetchbower "iron-meta" "PolymerElements/iron-meta#1.1.2" "PolymerElements/iron-meta#^1.0.0" "1wl4dx8fnsknw9z9xi8bpc4cy9x70c11x4zxwxnj73hf3smifppl")
25 (fetchbower "iron-resizable-behavior" "PolymerElements/iron-resizable-behavior#1.0.5" "PolymerElements/iron-resizable-behavior#^1.0.0" "1fd5zmbr2hax42vmcasncvk7lzi38fmb1kyii26nn8pnnjak7zkn")
26 (fetchbower "iron-selector" "PolymerElements/iron-selector#1.5.2" "PolymerElements/iron-selector#^1.0.0" "1ajv46llqzvahm5g6g75w7nfyjcslp53ji0wm96l2k94j87spv3r")
27 (fetchbower "web-animations-js" "web-animations/web-animations-js#2.2.2" "web-animations/web-animations-js#^2.2.0" "1izfvm3l67vwys0bqbhidi9rqziw2f8wv289386sc6jsxzgkzhga")
28 (fetchbower "iron-a11y-keys-behavior" "PolymerElements/iron-a11y-keys-behavior#1.1.7" "PolymerElements/iron-a11y-keys-behavior#^1.0.0" "070z46dbbz242002gmqrgy28x0y1fcqp9hnvbi05r3zphiqfx3l7")
29 (fetchbower "iron-validatable-behavior" "PolymerElements/iron-validatable-behavior#1.1.1" "PolymerElements/iron-validatable-behavior#^1.0.0" "1yhxlvywhw2klbbgm3f3cmanxfxggagph4ii635zv0c13707wslv")
30 (fetchbower "iron-form-element-behavior" "PolymerElements/iron-form-element-behavior#1.0.6" "PolymerElements/iron-form-element-behavior#^1.0.0" "0rdhxivgkdhhz2yadgdbjfc70l555p3y83vjh8rfj5hr0asyn6q1")
31 ]; }
@@ -0,0 +1,15
1 # This file has been generated by node2nix 1.0.0. Do not edit!
2
3 {pkgs ? import <nixpkgs> {
4 inherit system;
5 }, system ? builtins.currentSystem}:
6
7 let
8 nodeEnv = import ./node-env.nix {
9 inherit (pkgs) stdenv python utillinux runCommand writeTextFile nodejs;
10 };
11 in
12 import ./node-packages.nix {
13 inherit (pkgs) fetchurl fetchgit;
14 inherit nodeEnv;
15 } No newline at end of file
@@ -0,0 +1,292
1 # This file originates from node2nix
2
3 {stdenv, python, nodejs, utillinux, runCommand, writeTextFile}:
4
5 let
6 # Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise
7 tarWrapper = runCommand "tarWrapper" {} ''
8 mkdir -p $out/bin
9
10 cat > $out/bin/tar <<EOF
11 #! ${stdenv.shell} -e
12 $(type -p tar) "\$@" --warning=no-unknown-keyword
13 EOF
14
15 chmod +x $out/bin/tar
16 '';
17
18 # Function that generates a TGZ file from a NPM project
19 buildNodeSourceDist =
20 { name, version, src, ... }:
21
22 stdenv.mkDerivation {
23 name = "node-tarball-${name}-${version}";
24 inherit src;
25 buildInputs = [ nodejs ];
26 buildPhase = ''
27 export HOME=$TMPDIR
28 tgzFile=$(npm pack)
29 '';
30 installPhase = ''
31 mkdir -p $out/tarballs
32 mv $tgzFile $out/tarballs
33 mkdir -p $out/nix-support
34 echo "file source-dist $out/tarballs/$tgzFile" >> $out/nix-support/hydra-build-products
35 '';
36 };
37
38 includeDependencies = {dependencies}:
39 stdenv.lib.optionalString (dependencies != [])
40 (stdenv.lib.concatMapStrings (dependency:
41 ''
42 # Bundle the dependencies of the package
43 mkdir -p node_modules
44 cd node_modules
45
46 # Only include dependencies if they don't exist. They may also be bundled in the package.
47 if [ ! -e "${dependency.name}" ]
48 then
49 ${composePackage dependency}
50 fi
51
52 cd ..
53 ''
54 ) dependencies);
55
56 # Recursively composes the dependencies of a package
57 composePackage = { name, packageName, src, dependencies ? [], ... }@args:
58 let
59 fixImpureDependencies = writeTextFile {
60 name = "fixDependencies.js";
61 text = ''
62 var fs = require('fs');
63 var url = require('url');
64
65 /*
66 * Replaces an impure version specification by *
67 */
68 function replaceImpureVersionSpec(versionSpec) {
69 var parsedUrl = url.parse(versionSpec);
70
71 if(versionSpec == "latest" || versionSpec == "unstable" ||
72 versionSpec.substr(0, 2) == ".." || dependency.substr(0, 2) == "./" || dependency.substr(0, 2) == "~/" || dependency.substr(0, 1) == '/')
73 return '*';
74 else if(parsedUrl.protocol == "git:" || parsedUrl.protocol == "git+ssh:" || parsedUrl.protocol == "git+http:" || parsedUrl.protocol == "git+https:" ||
75 parsedUrl.protocol == "http:" || parsedUrl.protocol == "https:")
76 return '*';
77 else
78 return versionSpec;
79 }
80
81 var packageObj = JSON.parse(fs.readFileSync('./package.json'));
82
83 /* Replace dependencies */
84 if(packageObj.dependencies !== undefined) {
85 for(var dependency in packageObj.dependencies) {
86 var versionSpec = packageObj.dependencies[dependency];
87 packageObj.dependencies[dependency] = replaceImpureVersionSpec(versionSpec);
88 }
89 }
90
91 /* Replace development dependencies */
92 if(packageObj.devDependencies !== undefined) {
93 for(var dependency in packageObj.devDependencies) {
94 var versionSpec = packageObj.devDependencies[dependency];
95 packageObj.devDependencies[dependency] = replaceImpureVersionSpec(versionSpec);
96 }
97 }
98
99 /* Replace optional dependencies */
100 if(packageObj.optionalDependencies !== undefined) {
101 for(var dependency in packageObj.optionalDependencies) {
102 var versionSpec = packageObj.optionalDependencies[dependency];
103 packageObj.optionalDependencies[dependency] = replaceImpureVersionSpec(versionSpec);
104 }
105 }
106
107 /* Write the fixed JSON file */
108 fs.writeFileSync("package.json", JSON.stringify(packageObj));
109 '';
110 };
111 in
112 ''
113 DIR=$(pwd)
114 cd $TMPDIR
115
116 unpackFile ${src}
117
118 # Make the base dir in which the target dependency resides first
119 mkdir -p "$(dirname "$DIR/${packageName}")"
120
121 if [ -f "${src}" ]
122 then
123 # Figure out what directory has been unpacked
124 packageDir=$(find . -type d -maxdepth 1 | tail -1)
125
126 # Restore write permissions to make building work
127 chmod -R u+w "$packageDir"
128
129 # Move the extracted tarball into the output folder
130 mv "$packageDir" "$DIR/${packageName}"
131 elif [ -d "${src}" ]
132 then
133 # Restore write permissions to make building work
134 chmod -R u+w $strippedName
135
136 # Move the extracted directory into the output folder
137 mv $strippedName "$DIR/${packageName}"
138 fi
139
140 # Unset the stripped name to not confuse the next unpack step
141 unset strippedName
142
143 # Some version specifiers (latest, unstable, URLs, file paths) force NPM to make remote connections or consult paths outside the Nix store.
144 # The following JavaScript replaces these by * to prevent that
145 cd "$DIR/${packageName}"
146 node ${fixImpureDependencies}
147
148 # Include the dependencies of the package
149 ${includeDependencies { inherit dependencies; }}
150 cd ..
151 ${stdenv.lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
152 '';
153
154 # Extract the Node.js source code which is used to compile packages with
155 # native bindings
156 nodeSources = runCommand "node-sources" {} ''
157 tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
158 mv node-* $out
159 '';
160
161 # Builds and composes an NPM package including all its dependencies
162 buildNodePackage = { name, packageName, version, dependencies ? [], production ? true, npmFlags ? "", dontNpmInstall ? false, preRebuild ? "", ... }@args:
163
164 stdenv.lib.makeOverridable stdenv.mkDerivation (builtins.removeAttrs args [ "dependencies" ] // {
165 name = "node-${name}-${version}";
166 buildInputs = [ tarWrapper python nodejs ] ++ stdenv.lib.optional (stdenv.isLinux) utillinux ++ args.buildInputs or [];
167 dontStrip = args.dontStrip or true; # Striping may fail a build for some package deployments
168
169 inherit dontNpmInstall preRebuild;
170
171 unpackPhase = args.unpackPhase or "true";
172
173 buildPhase = args.buildPhase or "true";
174
175 compositionScript = composePackage args;
176 passAsFile = [ "compositionScript" ];
177
178 installPhase = args.installPhase or ''
179 # Create and enter a root node_modules/ folder
180 mkdir -p $out/lib/node_modules
181 cd $out/lib/node_modules
182
183 # Compose the package and all its dependencies
184 source $compositionScriptPath
185
186 # Patch the shebangs of the bundled modules to prevent them from
187 # calling executables outside the Nix store as much as possible
188 patchShebangs .
189
190 # Deploy the Node.js package by running npm install. Since the
191 # dependencies have been provided already by ourselves, it should not
192 # attempt to install them again, which is good, because we want to make
193 # it Nix's responsibility. If it needs to install any dependencies
194 # anyway (e.g. because the dependency parameters are
195 # incomplete/incorrect), it fails.
196 #
197 # The other responsibilities of NPM are kept -- version checks, build
198 # steps, postprocessing etc.