Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'upstream/master'

  • Loading branch information...
commit f3470e014981589eba6808d0350e935d7ffdd2b5 2 parents 05dfac3 + 630728d
@vvision authored
Showing with 12,388 additions and 1,874 deletions.
  1. +1 −0  .gitignore
  2. +12 −0 AUTHORS
  3. +1 −1  Makefile
  4. +2 −2 README.md
  5. +2 −0  doc/api/deprecate.md
  6. +8 −7 doc/api/npm.md
  7. +23 −7 doc/cli/config.md
  8. +2 −0  doc/cli/deprecate.md
  9. +10 −3 doc/cli/disputes.md
  10. +46 −0 doc/cli/faq.md
  11. +209 −0 doc/cli/global.md
  12. +3 −0  doc/cli/install.md
  13. +26 −5 doc/cli/json.md
  14. +1 −3 doc/cli/registry.md
  15. +19 −0 doc/cli/rm.md
  16. +49 −4 doc/cli/scripts.md
  17. +3 −3 doc/cli/semver.md
  18. +22 −0 doc/cli/stars.md
  19. +4 −1 doc/cli/update.md
  20. +10 −1 doc/cli/version.md
  21. +3 −1 doc/cli/view.md
  22. +4 −1 lib/build.js
  23. +302 −85 lib/cache.js
  24. +14 −2 lib/dedupe.js
  25. +1 −1  lib/deprecate.js
  26. +178 −51 lib/install.js
  27. +1 −1  lib/link.js
  28. +21 −9 lib/ls.js
  29. +5 −0 lib/npm.js
  30. +5 −0 lib/outdated.js
  31. +18 −5 lib/publish.js
  32. +4 −0 lib/run-script.js
  33. +8 −5 lib/search.js
  34. +27 −0 lib/stars.js
  35. +1 −0  lib/uninstall.js
  36. +1 −0  lib/unpublish.js
  37. +15 −3 lib/utils/error-handler.js
  38. +1 −1  lib/utils/exec.js
  39. +11 −4 lib/utils/lifecycle.js
  40. +6 −9 lib/utils/sha.js
  41. +69 −21 lib/utils/tar.js
  42. +15 −10 node_modules/abbrev/lib/abbrev.js
  43. +24 −10 node_modules/abbrev/package.json
  44. +27 −0 node_modules/chmodr/LICENSE
  45. +3 −0  node_modules/chmodr/README.md
  46. +54 −0 node_modules/chmodr/chmodr.js
  47. +28 −0 node_modules/chmodr/package.json
  48. +63 −0 node_modules/chmodr/test/basic.js
  49. +58 −0 node_modules/chmodr/test/sync.js
  50. +2 −3 node_modules/fstream-npm/fstream-npm.js
  51. +27 −0 node_modules/fstream-npm/node_modules/fstream-ignore/LICENSE
  52. +3 −2 node_modules/fstream-npm/node_modules/fstream-ignore/package.json
  53. +2 −2 node_modules/fstream-npm/package.json
  54. +27 −0 node_modules/fstream/LICENSE
  55. +5 −0 node_modules/fstream/lib/file-writer.js
  56. +2 −2 node_modules/fstream/lib/proxy-writer.js
  57. +2 −3 node_modules/fstream/lib/writer.js
  58. +5 −7 node_modules/fstream/package.json
  59. +57 −18 node_modules/glob/glob.js
  60. +6 −9 node_modules/glob/package.json
  61. +122 −7 node_modules/glob/test/00-setup.js
  62. +30 −85 node_modules/glob/test/bash-comparison.js
  63. +348 −0 node_modules/glob/test/bash-results.json
  64. +39 −28 node_modules/glob/test/mark.js
  65. +113 −0 node_modules/glob/test/nocase-nomagic.js
  66. +8 −41 node_modules/glob/test/pause-resume.js
  67. +32 −29 node_modules/glob/test/root.js
  68. +7 −3 node_modules/graceful-fs/graceful-fs.js
  69. +4 −3 node_modules/graceful-fs/package.json
  70. +5 −0 node_modules/graceful-fs/test/open.js
  71. +9 −1 node_modules/ini/README.md
  72. +27 −3 node_modules/ini/ini.js
  73. +4 −3 node_modules/ini/package.json
  74. +15 −0 node_modules/ini/test/fixtures/foo.ini
  75. +13 −3 node_modules/ini/test/foo.js
  76. +1 −0  node_modules/init-package-json/node_modules/promzard/package.json
  77. +5 −1 node_modules/init-package-json/package.json
  78. +12 −10 node_modules/lockfile/LICENSE
  79. +30 −48 node_modules/lockfile/lockfile.js
  80. +4 −3 node_modules/lockfile/package.json
  81. +43 −0 node_modules/lockfile/test/basic.js
  82. +41 −0 node_modules/lru-cache/README.md
  83. +50 −2 node_modules/lru-cache/lib/lru-cache.js
  84. +6 −5 node_modules/lru-cache/package.json
  85. +34 −0 node_modules/lru-cache/test/basic.js
  86. +52 −0 node_modules/lru-cache/test/foreach.js
  87. +50 −0 node_modules/lru-cache/test/memory-leak.js
  88. +6 −4 node_modules/minimatch/minimatch.js
  89. +27 −0 node_modules/minimatch/node_modules/sigmund/LICENSE
  90. +53 −0 node_modules/minimatch/node_modules/sigmund/README.md
  91. +283 −0 node_modules/minimatch/node_modules/sigmund/bench.js
  92. +38 −0 node_modules/minimatch/node_modules/sigmund/package.json
  93. +39 −0 node_modules/minimatch/node_modules/sigmund/sigmund.js
  94. +24 −0 node_modules/minimatch/node_modules/sigmund/test/basic.js
  95. +5 −4 node_modules/minimatch/package.json
  96. +2 −1  node_modules/mkdirp/.travis.yml
  97. +26 −24 node_modules/mkdirp/README.markdown
  98. +10 −8 node_modules/mkdirp/package.json
  99. +6 −0 node_modules/node-gyp/.jshintrc
  100. +16 −5 node_modules/node-gyp/README.md
  101. +6 −1 node_modules/node-gyp/addon.gypi
  102. 0  node_modules/node-gyp/{legacy/tools → }/gyp/.npmignore
  103. 0  node_modules/node-gyp/{legacy/tools → }/gyp/AUTHORS
  104. +4 −0 node_modules/node-gyp/{legacy/tools → }/gyp/DEPS
  105. 0  node_modules/node-gyp/{legacy/tools → }/gyp/LICENSE
  106. 0  node_modules/node-gyp/{legacy/tools → }/gyp/MANIFEST
  107. 0  node_modules/node-gyp/{legacy/tools → }/gyp/OWNERS
  108. +109 −0 node_modules/node-gyp/gyp/PRESUBMIT.py
  109. +1 −0  node_modules/node-gyp/{legacy/tools → }/gyp/buildbot/buildbot_run.py
  110. 0  node_modules/node-gyp/{legacy/tools → }/gyp/codereview.settings
  111. 0  node_modules/node-gyp/{legacy/tools → }/gyp/gyp
  112. 0  node_modules/node-gyp/{legacy/tools → }/gyp/gyp.bat
  113. 0  node_modules/node-gyp/{legacy/tools → }/gyp/gyp_dummy.c
  114. +12 −2 node_modules/node-gyp/{legacy/tools → }/gyp/gyptest.py
  115. +17 −16 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/MSVSNew.py
  116. +2 −2 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/MSVSProject.py
  117. +22 −8 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/MSVSSettings.py
  118. +9 −8 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/MSVSSettings_test.py
  119. +2 −2 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/MSVSToolFile.py
  120. +3 −2 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/MSVSUserFile.py
  121. +145 −43 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/MSVSVersion.py
  122. +2 −2 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/SCons.py
  123. +57 −15 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/__init__.py
  124. +79 −8 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/common.py
  125. +71 −0 node_modules/node-gyp/gyp/pylib/gyp/common_test.py
  126. +13 −4 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/easy_xml.py
  127. +5 −4 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/easy_xml_test.py
  128. 0  node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/__init__.py
  129. +1,092 −0 node_modules/node-gyp/gyp/pylib/gyp/generator/android.py
  130. +31 −2 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/dump_dependency_json.py
  131. +273 −0 node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py
  132. 0  node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/gypd.py
  133. 0  node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/gypsh.py
  134. +183 −177 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/make.py
  135. +345 −105 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/msvs.py
  136. +4 −2 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/msvs_test.py
  137. +732 −199 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/ninja.py
  138. +44 −0 node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py
  139. +31 −3 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/scons.py
  140. +46 −21 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/generator/xcode.py
  141. +682 −401 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/input.py
  142. +22 −16 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/mac_tool.py
  143. +722 −0 node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py
  144. +18 −11 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/ninja_syntax.py
  145. 0  node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/sun_tool.py
  146. +193 −0 node_modules/node-gyp/gyp/pylib/gyp/win_tool.py
  147. +223 −130 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/xcode_emulation.py
  148. +98 −67 node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/xcodeproj_file.py
  149. 0  node_modules/node-gyp/{legacy/tools → }/gyp/pylib/gyp/xml_fix.py
  150. 0  node_modules/node-gyp/{legacy/tools → }/gyp/pylintrc
  151. 0  node_modules/node-gyp/{legacy/tools → }/gyp/samples/samples
  152. 0  node_modules/node-gyp/{legacy/tools → }/gyp/samples/samples.bat
  153. 0  node_modules/node-gyp/{legacy/tools → }/gyp/setup.py
  154. +23 −0 node_modules/node-gyp/gyp/test/actions-bare/gyptest-bare.py
  155. +25 −0 node_modules/node-gyp/gyp/test/actions-bare/src/bare.gyp
  156. +11 −0 node_modules/node-gyp/gyp/test/actions-bare/src/bare.py
  157. +72 −0 node_modules/node-gyp/gyp/test/actions-multiple/gyptest-all.py
  158. +226 −0 node_modules/node-gyp/gyp/test/actions-multiple/src/actions.gyp
  159. +9 −0 node_modules/node-gyp/gyp/test/actions-multiple/src/copy.py
  160. +12 −0 node_modules/node-gyp/gyp/test/actions-multiple/src/filter.py
  161. +11 −0 node_modules/node-gyp/gyp/test/actions-multiple/src/foo.c
  162. +1 −0  node_modules/node-gyp/gyp/test/actions-multiple/src/input.txt
  163. +22 −0 node_modules/node-gyp/gyp/test/actions-multiple/src/main.c
  164. +26 −0 node_modules/node-gyp/gyp/test/actions-none/gyptest-none.py
  165. +12 −0 node_modules/node-gyp/gyp/test/actions-none/src/fake_cross.py
  166. +1 −0  node_modules/node-gyp/gyp/test/actions-none/src/foo.cc
  167. +35 −0 node_modules/node-gyp/gyp/test/actions-none/src/none_with_source_files.gyp
  168. +26 −0 node_modules/node-gyp/gyp/test/actions-subdir/gyptest-action.py
  169. +11 −0 node_modules/node-gyp/gyp/test/actions-subdir/src/make-file.py
  170. +31 −0 node_modules/node-gyp/gyp/test/actions-subdir/src/none.gyp
  171. +11 −0 node_modules/node-gyp/gyp/test/actions-subdir/src/subdir/make-subdir-file.py
  172. +28 −0 node_modules/node-gyp/gyp/test/actions-subdir/src/subdir/subdir.gyp
  173. +102 −0 node_modules/node-gyp/gyp/test/actions/gyptest-all.py
  174. +69 −0 node_modules/node-gyp/gyp/test/actions/gyptest-default.py
  175. +24 −0 node_modules/node-gyp/gyp/test/actions/gyptest-errors.py
  176. +24 −0 node_modules/node-gyp/gyp/test/actions/src/action_missing_name.gyp
  177. +114 −0 node_modules/node-gyp/gyp/test/actions/src/actions.gyp
  178. +21 −0 node_modules/node-gyp/gyp/test/actions/src/confirm-dep-files.py
  179. +46 −0 node_modules/node-gyp/gyp/test/actions/src/subdir1/counter.py
  180. +74 −0 node_modules/node-gyp/gyp/test/actions/src/subdir1/executable.gyp
  181. +20 −0 node_modules/node-gyp/gyp/test/actions/src/subdir1/make-prog1.py
  182. +20 −0 node_modules/node-gyp/gyp/test/actions/src/subdir1/make-prog2.py
  183. +12 −0 node_modules/node-gyp/gyp/test/actions/src/subdir1/program.c
  184. +11 −0 node_modules/node-gyp/gyp/test/actions/src/subdir2/make-file.py
  185. +33 −0 node_modules/node-gyp/gyp/test/actions/src/subdir2/none.gyp
  186. +21 −0 node_modules/node-gyp/gyp/test/actions/src/subdir3/generate_main.py
  187. +29 −0 node_modules/node-gyp/gyp/test/actions/src/subdir3/null_input.gyp
  188. +56 −0 node_modules/node-gyp/gyp/test/additional-targets/gyptest-additional.py
  189. +13 −0 node_modules/node-gyp/gyp/test/additional-targets/src/all.gyp
  190. +56 −0 node_modules/node-gyp/gyp/test/additional-targets/src/dir1/actions.gyp
  191. +11 −0 node_modules/node-gyp/gyp/test/additional-targets/src/dir1/emit.py
  192. +6 −0 node_modules/node-gyp/gyp/test/additional-targets/src/dir1/lib1.c
  193. +31 −0 node_modules/node-gyp/gyp/test/assembly/gyptest-assembly.py
  194. +4 −0 node_modules/node-gyp/gyp/test/assembly/src/as.bat
  195. +62 −0 node_modules/node-gyp/gyp/test/assembly/src/assembly.gyp
  196. +15 −0 node_modules/node-gyp/gyp/test/assembly/src/lib1.S
  197. +3 −0  node_modules/node-gyp/gyp/test/assembly/src/lib1.c
  198. +12 −0 node_modules/node-gyp/gyp/test/assembly/src/program.c
  199. +22 −0 node_modules/node-gyp/gyp/test/build-option/gyptest-build.py
  200. +13 −0 node_modules/node-gyp/gyp/test/build-option/hello.c
  201. +15 −0 node_modules/node-gyp/gyp/test/build-option/hello.gyp
  202. +85 −0 node_modules/node-gyp/gyp/test/builddir/gyptest-all.py
  203. +85 −0 node_modules/node-gyp/gyp/test/builddir/gyptest-default.py
  204. +21 −0 node_modules/node-gyp/gyp/test/builddir/src/builddir.gypi
  205. +6 −0 node_modules/node-gyp/gyp/test/builddir/src/func1.c
  206. +6 −0 node_modules/node-gyp/gyp/test/builddir/src/func2.c
  207. +6 −0 node_modules/node-gyp/gyp/test/builddir/src/func3.c
  208. +6 −0 node_modules/node-gyp/gyp/test/builddir/src/func4.c
  209. +6 −0 node_modules/node-gyp/gyp/test/builddir/src/func5.c
  210. +10 −0 node_modules/node-gyp/gyp/test/builddir/src/prog1.c
  211. +30 −0 node_modules/node-gyp/gyp/test/builddir/src/prog1.gyp
  212. +10 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/prog2.c
  213. +19 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/prog2.gyp
  214. +10 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/subdir3/prog3.c
  215. +19 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/subdir3/prog3.gyp
  216. +10 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/subdir3/subdir4/prog4.c
  217. +19 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/subdir3/subdir4/prog4.gyp
  218. +10 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/subdir3/subdir4/subdir5/prog5.c
  219. +19 −0 node_modules/node-gyp/gyp/test/builddir/src/subdir2/subdir3/subdir4/subdir5/prog5.gyp
  220. +15 −0 node_modules/node-gyp/gyp/test/cflags/cflags.c
  221. +16 −0 node_modules/node-gyp/gyp/test/cflags/cflags.gyp
  222. +65 −0 node_modules/node-gyp/gyp/test/cflags/gyptest-cflags.py
  223. +29 −0 node_modules/node-gyp/gyp/test/compilable/gyptest-headers.py
  224. +26 −0 node_modules/node-gyp/gyp/test/compilable/src/headers.gyp
  225. +7 −0 node_modules/node-gyp/gyp/test/compilable/src/lib1.cpp
  226. +6 −0 node_modules/node-gyp/gyp/test/compilable/src/lib1.hpp
  227. +9 −0 node_modules/node-gyp/gyp/test/compilable/src/program.cpp
  228. +34 −0 node_modules/node-gyp/gyp/test/compiler-override/compiler-global-settings.gyp.in
  229. +17 −0 node_modules/node-gyp/gyp/test/compiler-override/compiler-host.gyp
  230. +16 −0 node_modules/node-gyp/gyp/test/compiler-override/compiler.gyp
  231. +7 −0 node_modules/node-gyp/gyp/test/compiler-override/cxxtest.cc
  232. +55 −0 node_modules/node-gyp/gyp/test/compiler-override/gyptest-compiler-env.py
  233. +52 −0 node_modules/node-gyp/gyp/test/compiler-override/gyptest-compiler-global-settings.py
  234. +6 −0 node_modules/node-gyp/gyp/test/compiler-override/my_cc.py
  235. +6 −0 node_modules/node-gyp/gyp/test/compiler-override/my_cxx.py
  236. +6 −0 node_modules/node-gyp/gyp/test/compiler-override/my_ld.py
  237. +7 −0 node_modules/node-gyp/gyp/test/compiler-override/test.c
  238. +15 −0 node_modules/node-gyp/gyp/test/configurations/basics/configurations.c
  239. +32 −0 node_modules/node-gyp/gyp/test/configurations/basics/configurations.gyp
  240. +29 −0 node_modules/node-gyp/gyp/test/configurations/basics/gyptest-configurations.py
  241. +21 −0 node_modules/node-gyp/gyp/test/configurations/inheritance/configurations.c
  242. +40 −0 node_modules/node-gyp/gyp/test/configurations/inheritance/configurations.gyp
  243. +33 −0 node_modules/node-gyp/gyp/test/configurations/inheritance/gyptest-inheritance.py
  244. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/actions.gyp
  245. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/all_dependent_settings.gyp
  246. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/configurations.gyp
  247. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/dependencies.gyp
  248. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/direct_dependent_settings.gyp
  249. +39 −0 node_modules/node-gyp/gyp/test/configurations/invalid/gyptest-configurations.py
  250. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/libraries.gyp
  251. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/link_settings.gyp
  252. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/sources.gyp
  253. +17 −0 node_modules/node-gyp/gyp/test/configurations/invalid/standalone_static_library.gyp
  254. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/target_name.gyp
  255. +18 −0 node_modules/node-gyp/gyp/test/configurations/invalid/type.gyp
  256. +58 −0 node_modules/node-gyp/gyp/test/configurations/target_platform/configurations.gyp
  257. +8 −0 node_modules/node-gyp/gyp/test/configurations/target_platform/front.c
  258. +40 −0 node_modules/node-gyp/gyp/test/configurations/target_platform/gyptest-target_platform.py
  259. +3 −0  node_modules/node-gyp/gyp/test/configurations/target_platform/left.c
  260. +3 −0  node_modules/node-gyp/gyp/test/configurations/target_platform/right.c
  261. +12 −0 node_modules/node-gyp/gyp/test/configurations/x64/configurations.c
  262. +38 −0 node_modules/node-gyp/gyp/test/configurations/x64/configurations.gyp
  263. +31 −0 node_modules/node-gyp/gyp/test/configurations/x64/gyptest-x86.py
  264. +40 −0 node_modules/node-gyp/gyp/test/copies/gyptest-all.py
  265. +40 −0 node_modules/node-gyp/gyp/test/copies/gyptest-default.py
  266. +38 −0 node_modules/node-gyp/gyp/test/copies/gyptest-slash.py
  267. +23 −0 node_modules/node-gyp/gyp/test/copies/gyptest-updir.py
  268. +36 −0 node_modules/node-gyp/gyp/test/copies/src/copies-slash.gyp
  269. +21 −0 node_modules/node-gyp/gyp/test/copies/src/copies-updir.gyp
  270. +70 −0 node_modules/node-gyp/gyp/test/copies/src/copies.gyp
  271. +1 −0  node_modules/node-gyp/gyp/test/copies/src/directory/file3
  272. +1 −0  node_modules/node-gyp/gyp/test/copies/src/directory/file4
  273. +1 −0  node_modules/node-gyp/gyp/test/copies/src/directory/subdir/file5
  274. +1 −0  node_modules/node-gyp/gyp/test/copies/src/file1
  275. +1 −0  node_modules/node-gyp/gyp/test/copies/src/file2
  276. +1 −0  node_modules/node-gyp/gyp/test/copies/src/parentdir/subdir/file6
  277. +18 −0 node_modules/node-gyp/gyp/test/custom-generator/gyptest-custom-generator.py
  278. +14 −0 node_modules/node-gyp/gyp/test/custom-generator/mygenerator.py
  279. +15 −0 node_modules/node-gyp/gyp/test/custom-generator/test.gyp
  280. +15 −0 node_modules/node-gyp/gyp/test/cxxflags/cxxflags.cc
  281. +16 −0 node_modules/node-gyp/gyp/test/cxxflags/cxxflags.gyp
  282. +65 −0 node_modules/node-gyp/gyp/test/cxxflags/gyptest-cxxflags.py
  283. +11 −0 node_modules/node-gyp/gyp/test/defines-escaping/defines-escaping.c
  284. +19 −0 node_modules/node-gyp/gyp/test/defines-escaping/defines-escaping.gyp
  285. +184 −0 node_modules/node-gyp/gyp/test/defines-escaping/gyptest-defines-escaping.py
  286. +22 −0 node_modules/node-gyp/gyp/test/defines/defines-env.gyp
  287. +23 −0 node_modules/node-gyp/gyp/test/defines/defines.c
  288. +38 −0 node_modules/node-gyp/gyp/test/defines/defines.gyp
  289. +34 −0 node_modules/node-gyp/gyp/test/defines/gyptest-define-override.py
  290. +51 −0 node_modules/node-gyp/gyp/test/defines/gyptest-defines-env-regyp.py
  291. +85 −0 node_modules/node-gyp/gyp/test/defines/gyptest-defines-env.py
  292. +27 −0 node_modules/node-gyp/gyp/test/defines/gyptest-defines.py
  293. +9 −0 node_modules/node-gyp/gyp/test/dependencies/a.c
  294. +3 −0  node_modules/node-gyp/gyp/test/dependencies/b/b.c
  295. +22 −0 node_modules/node-gyp/gyp/test/dependencies/b/b.gyp
  296. +9 −0 node_modules/node-gyp/gyp/test/dependencies/b/b3.c
  297. +4 −0 node_modules/node-gyp/gyp/test/dependencies/c/c.c
  298. +22 −0 node_modules/node-gyp/gyp/test/dependencies/c/c.gyp
  299. +3 −0  node_modules/node-gyp/gyp/test/dependencies/c/d.c
  300. +23 −0 node_modules/node-gyp/gyp/test/dependencies/double_dependency.gyp
Sorry, we could not display the entire diff because too many files (1,217) changed.
View
1  .gitignore
@@ -16,3 +16,4 @@ npm-debug.log
/npmrc
/release/
/npm-*.tgz
+/node_modules/npm-registry-client/test/fixtures
View
12 AUTHORS
@@ -71,10 +71,22 @@ Domenic Denicola <domenic@domenicdenicola.com>
James Halliday <mail@substack.net>
Jeremy Cantrell <jmcantrell@gmail.com>
Ribettes <patlogan29@gmail.com>
+Einar Otto Stangvik <einaros@gmail.com>
Don Park <donpark@docuverse.com>
Kei Son <heyacct@gmail.com>
Nicolas Morel <marsup@gmail.com>
Mark Dube <markisdee@gmail.com>
+Nathan Rajlich <nathan@tootallnate.net>
Maxim Bogushevich <boga1@mail.ru>
Justin Beckwith <justbe@microsoft.com>
Meaglin <Meaglin.wasabi@gmail.com>
+Ben Evans <ben@bensbit.co.uk>
+Nathan Zadoks <nathan@nathan7.eu>
+Brian White <mscdex@gmail.com>
+Jed Schmidt <tr@nslator.jp>
+Ian Livingstone <ianl@cs.dal.ca>
+Patrick Pfeiffer <patrick@buzzle.at>
+Paul Miller <paul@paulmillr.com>
+seebees <seebees@gmail.com>
+Carl Lange <carl@flax.ie>
+Jan Lehnardt <jan@apache.org>
View
2  Makefile
@@ -92,7 +92,7 @@ doc/cli/index.md: $(markdowns) scripts/index-build.js scripts/doc-build.sh packa
node scripts/index-build.js > $@
node_modules/.bin/ronn:
- node cli.js install
+ node cli.js install ronn
doc: man
View
4 README.md
@@ -42,11 +42,11 @@ There's a pretty robust install script at
You can set any npm configuration params with that script:
-npm_config_prefix=/some/path sh install.sh
+ npm_config_prefix=/some/path sh install.sh
Or, you can run it in uber-debuggery mode:
-npm_debug=1 sh install.sh
+ npm_debug=1 sh install.sh
### Even Fancier
View
2  doc/api/deprecate.md
@@ -25,6 +25,8 @@ The 'args' parameter must have exactly two elements:
Note that you must be the package owner to deprecate something. See the
`owner` and `adduser` help topics.
+To un-deprecate a package, specify an empty string (`""`) for the `message` argument.
+
## SEE ALSO
* npm-publish(3)
View
15 doc/api/npm.md
@@ -4,7 +4,7 @@ npm(3) -- node package manager
## SYNOPSIS
var npm = require("npm")
- npm.load(configObject, function (er, npm) {
+ npm.load([configObject,] function (er, npm) {
// use the npm object, now that it's loaded.
npm.config.set(key, val)
@@ -25,12 +25,13 @@ This is the API documentation for npm.
To find documentation of the command line
client, see `npm(1)`.
-Prior to using npm's commands,
-`npm.load()` must be called with an object hash of
-top-level configs. In the npm command line client,
-this set of configs is parsed from the command line options. Additional
-configuration params are loaded from two configuration files. See
-`npm-config(1)` for more information.
+Prior to using npm's commands, `npm.load()` must be called.
+If you provide `configObject` as an object hash of top-level
+configs, they override the values stored in the various config
+locations. In the npm command line client, this set of configs
+is parsed from the command line options. Additional configuration
+params are loaded from two configuration files. See `npm-config(1)`
+for more information.
After that, each of the functions are accessible in the
commands object: `npm.commands.<cmd>`. See `npm-index(1)` for a list of
View
30 doc/cli/config.md
@@ -36,11 +36,15 @@ work the same.
`$HOME/.npmrc` (or the `userconfig` param, if set above)
This file is an ini-file formatted list of `key = value` parameters.
+Environment variables can be replaced using `${VARIABLE_NAME}`. For example:
+
+ prefix = ${HOME}/.npm-packages
### Global config file
`$PREFIX/etc/npmrc` (or the `globalconfig` param, if set above):
-This file is an ini-file formatted list of `key = value` parameters
+This file is an ini-file formatted list of `key = value` parameters.
+Environment variables can be replaced as above.
### Built-in config file
@@ -167,6 +171,18 @@ then the user could change the behavior by doing:
Force npm to always require authentication when accessing the registry,
even for `GET` requests.
+### bin-links
+
+* Default: `true`
+* Type: Boolean
+
+Tells npm to create symlinks (or `.cmd` shims on Windows) for package
+executables.
+
+Set to false to have it not do this. This can be used to work around
+the fact that some file systems don't support symlinks, even on
+ostensibly Unix systems.
+
### browser
* Default: OS X: `"open"`, others: `"google-chrome"`
@@ -228,7 +244,7 @@ explicitly used, and that only GET requests use the cache.
### cache-min
-* Default: 0
+* Default: 10
* Type: Number
The minimum time (in seconds) to keep items in the registry cache before
@@ -357,10 +373,10 @@ Operates in "global" mode, so that packages are installed into the
`prefix` folder instead of the current working directory. See
`npm-folders(1)` for more on the differences in behavior.
-* packages are installed into the `prefix/node_modules` folder, instead of the
+* packages are installed into the `{prefix}/lib/node_modules` folder, instead of the
current working directory.
-* bin files are linked to `prefix/bin`
-* man pages are linked to `prefix/share/man`
+* bin files are linked to `{prefix}/bin`
+* man pages are linked to `{prefix}/share/man`
### globalconfig
@@ -398,7 +414,7 @@ A proxy to use for outgoing https requests.
### user-agent
-* Default: npm/{npm.version} node/{process.version}
+* Default: node/{process.version} {process.platform} {process.arch}
* Type: String
Sets a User-Agent to the request header
@@ -575,7 +591,7 @@ standard output.
### prefix
-* Default: node's process.installPrefix
+* Default: see npm-folders(1)
* Type: path
The location to install global items. If set on the command line, then
View
2  doc/cli/deprecate.md
@@ -18,6 +18,8 @@ something like this:
Note that you must be the package owner to deprecate something. See the
`owner` and `adduser` help topics.
+To un-deprecate a package, specify an empty string (`""`) for the `message` argument.
+
## SEE ALSO
* npm-publish(1)
View
13 doc/cli/disputes.md
@@ -4,8 +4,10 @@ npm-disputes(1) -- Handling Module Name Disputes
## SYNOPSIS
1. Get the author email with `npm owner ls <pkgname>`
-1. Email the author, CC <i@izs.me>.
-2. After a few weeks, if there's no resolution, we'll sort it out.
+2. Email the author, CC <i@izs.me>.
+3. After a few weeks, if there's no resolution, we'll sort it out.
+
+Don't squat on package names. Publish code or move out of the way.
## DESCRIPTION
@@ -40,7 +42,7 @@ Joe's appropriate course of action in each case is the same.
1. `npm owner ls foo`. This will tell Joe the email address of the
owner (Bob).
-2. Joe emails Bob, explaining the situation **as respecfully as possible**,
+2. Joe emails Bob, explaining the situation **as respectfully as possible**,
and what he would like to do with the module name. He adds
isaacs <i@izs.me> to the CC list of the email. Mention in the email
that Bob can run `npm owner add joe foo` to add Joe as an owner of
@@ -75,6 +77,11 @@ but not limited to:
MIT-licensed program, and then removing or changing the copyright and
license statement)
3. Illegal content.
+4. "Squatting" on a package name that you *plan* to use, but aren't
+ actually using. Sorry, I don't care how great the name is, or how
+ perfect a fit it is for the thing that someday might happen. If
+ someone wants to use it today, and you're just taking up space with
+ an empty tarball, you're going to be evicted.
If you see bad behavior like this, please report it right away.
View
46 doc/cli/faq.md
@@ -72,6 +72,52 @@ Write your own package manager, then. It's not that hard.
npm will not help you do something that is known to be a bad idea.
+## `"node_modules"` is the name of my deity's arch-rival, and a Forbidden Word in my religion. Can I configure npm to use a different folder?
+
+No. This will never happen. This question comes up sometimes,
+because it seems silly from the outside that npm couldn't just be
+configured to put stuff somewhere else, and then npm could load them
+from there. It's an arbitrary spelling choice, right? What's the big
+deal?
+
+At the time of this writing, the string `'node_modules'` appears 151
+times in 53 separate files in npm and node core (excluding tests and
+documentation).
+
+Some of these references are in node's built-in module loader. Since
+npm is not involved **at all** at run-time, node itself would have to
+be configured to know where you've decided to stick stuff. Complexity
+hurdle #1. Since the Node module system is locked, this cannot be
+changed, and is enough to kill this request. But I'll continue, in
+deference to your deity's delicate feelings regarding spelling.
+
+Many of the others are in dependencies that npm uses, which are not
+necessarily tightly coupled to npm (in the sense that they do not read
+npm's configuration files, etc.) Each of these would have to be
+configured to take the name of the `node_modules` folder as a
+parameter. Complexity hurdle #2.
+
+Furthermore, npm has the ability to "bundle" dependencies by adding
+the dep names to the `"bundledDependencies"` list in package.json,
+which causes the folder to be included in the package tarball. What
+if the author of a module bundles its dependencies, and they use a
+different spelling for `node_modules`? npm would have to rename the
+folder at publish time, and then be smart enough to unpack it using
+your locally configured name. Complexity hurdle #3.
+
+Furthermore, what happens when you *change* this name? Fine, it's
+easy enough the first time, just rename the `node_modules` folders to
+`./blergyblerp/` or whatever name you choose. But what about when you
+change it again? npm doesn't currently track any state about past
+configuration settings, so this would be rather difficult to do
+properly. It would have to track every previous value for this
+config, and always accept any of them, or else yesterday's install may
+be broken tomorrow. Complexity hurdle #5.
+
+Never going to happen. The folder is named `node_modules`. It is
+written indelibly in the Node Way, handed down from the ancient times
+of Node 0.3.
+
## Should I check my `node_modules` folder into git?
Mikeal Rogers answered this question very well:
View
209 doc/cli/global.md
@@ -0,0 +1,209 @@
+npm-folders(1) -- Folder Structures Used by npm
+===============================================
+
+## DESCRIPTION
+
+npm puts various things on your computer. That's its job.
+
+This document will tell you what it puts where.
+
+### tl;dr
+
+* Local install (default): puts stuff in `./node_modules` of the current
+ package root.
+* Global install (with `-g`): puts stuff in /usr/local or wherever node
+ is installed.
+* Install it **locally** if you're going to `require()` it.
+* Install it **globally** if you're going to run it on the command line.
+* If you need both, then install it in both places, or use `npm link`.
+
+### prefix Configuration
+
+The `prefix` config defaults to the location where node is installed.
+On most systems, this is `/usr/local`, and most of the time is the same
+as node's `process.installPrefix`.
+
+On windows, this is the exact location of the node.exe binary. On Unix
+systems, it's one level up, since node is typically installed at
+`{prefix}/bin/node` rather than `{prefix}/node.exe`.
+
+When the `global` flag is set, npm installs things into this prefix.
+When it is not set, it uses the root of the current package, or the
+current working directory if not in a package already.
+
+### Node Modules
+
+Packages are dropped into the `node_modules` folder under the `prefix`.
+When installing locally, this means that you can
+`require("packagename")` to load its main module, or
+`require("packagename/lib/path/to/sub/module")` to load other modules.
+
+Global installs on Unix systems go to `{prefix}/lib/node_modules`.
+Global installs on Windows go to `{prefix}/node_modules` (that is, no
+`lib` folder.)
+
+If you wish to `require()` a package, then install it locally.
+
+### Executables
+
+When in global mode, executables are linked into `{prefix}/bin` on Unix,
+or directly into `{prefix}` on Windows.
+
+When in local mode, executables are linked into
+`./node_modules/.bin` so that they can be made available to scripts run
+through npm. (For example, so that a test runner will be in the path
+when you run `npm test`.)
+
+### Man Pages
+
+When in global mode, man pages are linked into `{prefix}/share/man`.
+
+When in local mode, man pages are not installed.
+
+Man pages are not installed on Windows systems.
+
+### Cache
+
+See `npm-cache(1)`. Cache files are stored in `~/.npm` on Posix, or
+`~/npm-cache` on Windows.
+
+This is controlled by the `cache` configuration param.
+
+### Temp Files
+
+Temporary files are stored by default in the folder specified by the
+`tmp` config, which defaults to the TMPDIR, TMP, or TEMP environment
+variables, or `/tmp` on Unix and `c:\windows\temp` on Windows.
+
+Temp files are given a unique folder under this root for each run of the
+program, and are deleted upon successful exit.
+
+## More Information
+
+When installing locally, npm first tries to find an appropriate
+`prefix` folder. This is so that `npm install foo@1.2.3` will install
+to the sensible root of your package, even if you happen to have `cd`ed
+into some other folder.
+
+Starting at the $PWD, npm will walk up the folder tree checking for a
+folder that contains either a `package.json` file, or a `node_modules`
+folder. If such a thing is found, then that is treated as the effective
+"current directory" for the purpose of running npm commands. (This
+behavior is inspired by and similar to git's .git-folder seeking
+logic when running git commands in a working dir.)
+
+If no package root is found, then the current folder is used.
+
+When you run `npm install foo@1.2.3`, then the package is loaded into
+the cache, and then unpacked into `./node_modules/foo`. Then, any of
+foo's dependencies are similarly unpacked into
+`./node_modules/foo/node_modules/...`.
+
+Any bin files are symlinked to `./node_modules/.bin/`, so that they may
+be found by npm scripts when necessary.
+
+### Global Installation
+
+If the `global` configuration is set to true, then npm will
+install packages "globally".
+
+For global installation, packages are installed roughly the same way,
+but using the folders described above.
+
+### Cycles, Conflicts, and Folder Parsimony
+
+Cycles are handled using the property of node's module system that it
+walks up the directories looking for `node_modules` folders. So, at every
+stage, if a package is already installed in an ancestor `node_modules`
+folder, then it is not installed at the current location.
+
+Consider the case above, where `foo -> bar -> baz`. Imagine if, in
+addition to that, baz depended on bar, so you'd have:
+`foo -> bar -> baz -> bar -> baz ...`. However, since the folder
+structure is: `foo/node_modules/bar/node_modules/baz`, there's no need to
+put another copy of bar into `.../baz/node_modules`, since when it calls
+require("bar"), it will get the copy that is installed in
+`foo/node_modules/bar`.
+
+This shortcut is only used if the exact same
+version would be installed in multiple nested `node_modules` folders. It
+is still possible to have `a/node_modules/b/node_modules/a` if the two
+"a" packages are different versions. However, without repeating the
+exact same package multiple times, an infinite regress will always be
+prevented.
+
+Another optimization can be made by installing dependencies at the
+highest level possible, below the localized "target" folder.
+
+#### Example
+
+Consider this dependency graph:
+
+ foo
+ +-- blerg@1.2.5
+ +-- bar@1.2.3
+ | +-- blerg@1.x (latest=1.3.7)
+ | +-- baz@2.x
+ | | `-- quux@3.x
+ | | `-- bar@1.2.3 (cycle)
+ | `-- asdf@*
+ `-- baz@1.2.3
+ `-- quux@3.x
+ `-- bar
+
+In this case, we might expect a folder structure like this:
+
+ foo
+ +-- node_modules
+ +-- blerg (1.2.5) <---[A]
+ +-- bar (1.2.3) <---[B]
+ | +-- node_modules
+ | | `-- baz (2.0.2) <---[C]
+ | | `-- node_modules
+ | | `-- quux (3.2.0)
+ | `-- asdf (2.3.4)
+ `-- baz (1.2.3) <---[D]
+ `-- node_modules
+ `-- quux (3.2.0) <---[E]
+
+Since foo depends directly on bar@1.2.3 and baz@1.2.3, those are
+installed in foo's `node_modules` folder.
+
+Even though the latest copy of blerg is 1.3.7, foo has a specific
+dependency on version 1.2.5. So, that gets installed at [A]. Since the
+parent installation of blerg satisfie's bar's dependency on blerg@1.x,
+it does not install another copy under [B].
+
+Bar [B] also has dependencies on baz and asdf, so those are installed in
+bar's `node_modules` folder. Because it depends on `baz@2.x`, it cannot
+re-use the `baz@1.2.3` installed in the parent `node_modules` folder [D],
+and must install its own copy [C].
+
+Underneath bar, the `baz->quux->bar` dependency creates a cycle.
+However, because `bar` is already in `quux`'s ancestry [B], it does not
+unpack another copy of bar into that folder.
+
+Underneath `foo->baz` [D], quux's [E] folder tree is empty, because its
+dependency on bar is satisfied by the parent folder copy installed at [B].
+
+For a graphical breakdown of what is installed where, use `npm ls`.
+
+### Publishing
+
+Upon publishing, npm will look in the `node_modules` folder. If any of
+the items there are not in the `bundledDependencies` array, then they will
+not be included in the package tarball.
+
+This allows a package maintainer to install all of their dependencies
+(and dev dependencies) locally, but only re-publish those items that
+cannot be found elsewhere. See `npm-json(1)` for more information.
+
+## SEE ALSO
+
+* npm-faq(1)
+* npm-json(1)
+* npm-install(1)
+* npm-pack(1)
+* npm-cache(1)
+* npm-config(1)
+* npm-publish(1)
View
3  doc/cli/install.md
@@ -165,6 +165,9 @@ rather than locally. See `npm-folders(1)`.
The `--link` argument will cause npm to link global installs into the
local space in some cases.
+The `--no-bin-links` argument will prevent npm from creating symlinks for
+any binaries the package might contain.
+
See `npm-config(1)`. Many of the configuration params have some
effect on installation, since that's most of what npm does.
View
31 doc/cli/json.md
@@ -118,6 +118,27 @@ you can specify the value for "bugs" as a simple string instead of an object.
If a url is provided, it will be used by the `npm bugs` command.
+## license
+
+You should specify a license for your package so that people know how they are
+permitted to use it, and any restrictions you're placing on it.
+
+The simplest way, assuming you're using a common license such as BSD or MIT, is
+to just specify the name of the license you're using, like this:
+
+ { "license" : "BSD" }
+
+If you have more complex licensing terms, or you want to provide more detail
+in your package.json file, you can use the more verbose plural form, like this:
+
+ "licenses" : [
+ { "type" : "MyLicense"
+ , "url" : "http://github.com/owner/project/path/to/license"
+ }
+ ]
+
+It's also a good idea to include a license file at the top level in your package.
+
## people fields: author, contributors
The "author" is one person. "contributors" is an array of people. A "person"
@@ -366,8 +387,8 @@ a version in the following fashion.
For example, the following are equivalent:
* `"~1.2.3" = ">=1.2.3 <1.3.0"`
-* `"~1.2" = ">=1.2.0 <2.0.0"`
-* `"~1" = ">=1.0.0 <2.0.0"`
+* `"~1.2" = ">=1.2.0 <1.3.0"`
+* `"~1" = ">=1.0.0 <1.1.0"`
### X Version Ranges
@@ -416,9 +437,9 @@ In this case, it's best to list these additional items in a
`devDependencies` hash.
These things will be installed whenever the `--dev` configuration flag
-is set. This flag is set automatically when doing `npm link`, and can
-be managed like any other npm configuration param. See `npm-config(1)`
-for more on the topic.
+is set. This flag is set automatically when doing `npm link` or when doing
+`npm install` from the root of a package, and can be managed like any other npm
+configuration param. See `npm-config(1)` for more on the topic.
## bundledDependencies
View
4 doc/cli/registry.md
@@ -82,9 +82,7 @@ ask for help on the <npm-@googlegroups.com> mailing list.
## Is there a website or something to see package docs and such?
-No, but such a thing is planned, and a tiny bit developed.
-
-Stay tuned!
+Yes, head over to <https://npmjs.org/>
## SEE ALSO
View
19 doc/cli/rm.md
@@ -0,0 +1,19 @@
+npm-rm(1) -- Remove a package
+=============================
+
+## SYNOPSIS
+
+ npm rm <name>
+ npm uninstall <name>
+
+## DESCRIPTION
+
+This uninstalls a package, completely removing everything npm installed
+on its behalf.
+
+## SEE ALSO
+
+* npm-prune(1)
+* npm-install(1)
+* npm-folders(1)
+* npm-config(1)
View
53 doc/cli/scripts.md
@@ -6,6 +6,11 @@ npm-scripts(1) -- How npm handles the "scripts" field
npm supports the "scripts" member of the package.json script, for the
following scripts:
+* prepublish:
+ Run BEFORE the package is published. (Also run on local `npm
+ install` without any arguments.)
+* publish, postpublish:
+ Run AFTER the package is published.
* preinstall:
Run BEFORE the package is installed
* install, postinstall:
@@ -18,10 +23,6 @@ following scripts:
Run BEFORE the package is updated with the update command.
* update, postupdate:
Run AFTER the package is updated with the update command.
-* prepublish:
- Run BEFORE the package is published.
-* publish, postpublish:
- Run AFTER the package is published.
* pretest, test, posttest:
Run by the `npm test` command.
* prestop, stop, poststop:
@@ -35,6 +36,50 @@ following scripts:
Additionally, arbitrary scrips can be run by doing
`npm run-script <stage> <pkg>`.
+## NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN
+
+**tl;dr** Don't use `install`. Use a `.gyp` file for compilation, and
+`prepublish` for anything else.
+
+You should almost never have to explicitly set a `preinstall` or
+`install` script. If you are doing this, please consider if there is
+another option.
+
+The only valid use of `install` or `preinstall` scripts is for
+compilation which must be done on the target architecture. In early
+versions of node, this was often done using the `node-waf` scripts, or
+a standalone `Makefile`, and early versions of npm required that it be
+explicitly set in package.json. This was not portable, and harder to
+do properly.
+
+In the current version of node, the standard way to do this is using a
+`.gyp` file. If you have a file with a `.gyp` extension in the root
+of your package, then npm will run the appropriate `node-gyp` commands
+automatically at install time. This is the only officially supported
+method for compiling binary addons, and does not require that you add
+anything to your package.json file.
+
+If you have to do other things before your package is used, in a way
+that is not dependent on the operating system or architecture of the
+target system, then use a `prepublish` script instead. This includes
+tasks such as:
+
+* Compile CoffeeScript source code into JavaScript.
+* Create minified versions of JavaScript source code.
+* Fetching remote resources that your package will use.
+
+The advantage of doing these things at `prepublish` time instead of
+`preinstall` or `install` time is that they can be done once, in a
+single place, and thus greatly reduce complexity and variability.
+Additionally, this means that:
+
+* You can depend on `coffee-script` as a `devDependency`, and thus
+ your users don't need to have it installed.
+* You don't need to include the minifiers in your package, reducing
+ the size for your users.
+* You don't need to rely on your users having `curl` or `wget` or
+ other system tools on the target machines.
+
## DEFAULT VALUES
npm will default some script values based on package contents.
View
6 doc/cli/semver.md
@@ -11,8 +11,8 @@ As a node module:
$ npm install semver
- semver.valid('1.2.3') // true
- semver.valid('a.b.c') // false
+ semver.valid('1.2.3') // '1.2.3'
+ semver.valid('a.b.c') // null
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
@@ -83,7 +83,7 @@ The following range styles are supported:
* `<1.2.3` Less than
* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`
* `~1.2.3` := `>=1.2.3 <1.3.0`
-* `~1.2` := `>=1.2.0 <2.0.0`
+* `~1.2` := `>=1.2.0 <1.3.0`
* `~1` := `>=1.0.0 <2.0.0`
* `1.2.x` := `>=1.2.0 <1.3.0`
* `1.x` := `>=1.0.0 <2.0.0`
View
22 doc/cli/stars.md
@@ -0,0 +1,22 @@
+npm-stars(1) -- View packages marked as favorites
+=================================================
+
+## SYNOPSIS
+
+ npm stars
+ npm stars [username]
+
+## DESCRIPTION
+
+If you have starred a lot of neat things and want to find them again
+quickly this command lets you do just that.
+
+You may also want to see your friend's favorite packages, in this case
+you will most certainly enjoy this command.
+
+## SEE ALSO
+
+* npm-star(1)
+* npm-view(1)
+* npm-whoami(1)
+* npm-adduser(1)
View
5 doc/cli/update.md
@@ -3,7 +3,7 @@ npm-update(1) -- Update a package
## SYNOPSIS
- npm update [<name> [<name> ...]]
+ npm update [-g] [<name> [<name> ...]]
## DESCRIPTION
@@ -12,6 +12,9 @@ This command will update all the packages listed to the latest version
It will also install missing packages.
+If the `-g` flag is specified, this command will update globally installed packages.
+If no package name is specified, all packages in the specified location (global or local) will be updated.
+
## SEE ALSO
* npm-install(1)
View
11 doc/cli/version.md
@@ -27,7 +27,16 @@ resulting version number. For example:
If the `sign-git-tag` config is set, then the tag will be signed using
the `-s` flag to git. Note that you must have a default GPG key set up
-in your git config for this to work properly.
+in your git config for this to work properly. For example:
+
+ $ npm config set sign-git-tag true
+ $ npm version patch
+
+ You need a passphrase to unlock the secret key for
+ user: "isaacs (http://blog.izs.me/) <i@izs.me>"
+ 2048-bit RSA key, ID 6C481CF6, created 2010-08-31
+
+ Enter passphrase:
## SEE ALSO
View
4 doc/cli/view.md
@@ -69,7 +69,9 @@ was required by each matching version of yui3:
If only a single string field for a single version is output, then it
will not be colorized or quoted, so as to enable piping the output to
-another command.
+another command. If the field is an object, it will be output as a JavaScript object literal.
+
+If the --json flag is given, the outputted fields will be JSON.
If the version range matches multiple versions, than each printed value
will be prefixed with the version it applies to.
View
5 lib/build.js
@@ -69,6 +69,9 @@ function writeBuiltinConf (folder, cb) {
}
function linkStuff (pkg, folder, global, didRB, cb) {
+ // allow to opt out of linking binaries.
+ if (npm.config.get("bin-links") === false) return cb()
+
// if it's global, and folder is in {prefix}/node_modules,
// then bins are in {prefix}/bin
// otherwise, then bins are in folder/../.bin
@@ -109,7 +112,7 @@ function rebuildBundles (pkg, folder, parent, gtop, cb) {
chain(files.filter(function (file) {
// rebuild if:
// not a .folder, like .bin or .hooks
- return file.charAt(0) !== "."
+ return !file.match(/^[\._-]/)
// not some old 0.x style bundle
&& file.indexOf("@") === -1
// either not a dep, or explicitly bundled
View
387 lib/cache.js
@@ -51,14 +51,16 @@ adding a local tarball:
*/
exports = module.exports = cache
-exports.read = read
-exports.clean = clean
-exports.unpack = unpack
-exports.lock = lock
-exports.unlock = unlock
+cache.read = read
+cache.clean = clean
+cache.unpack = unpack
+cache.lock = lock
+cache.unlock = unlock
var mkdir = require("mkdirp")
, exec = require("./utils/exec.js")
+ , spawn = require("child_process").spawn
+ , once = require("once")
, fetch = require("./utils/fetch.js")
, npm = require("./npm.js")
, fs = require("graceful-fs")
@@ -77,6 +79,8 @@ var mkdir = require("mkdirp")
, lockFile = require("lockfile")
, crypto = require("crypto")
, retry = require("retry")
+ , zlib = require("zlib")
+ , chmodr = require("chmodr")
cache.usage = "npm cache add <tarball file>"
+ "\nnpm cache add <folder>"
@@ -136,6 +140,8 @@ function read (name, ver, forceBypass, cb) {
}
readJson(jsonFile, function (er, data) {
+ er = needVersion(er, data)
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
if (er) return addNamed(name, ver, c)
deprCheck(data)
c(er, data)
@@ -150,7 +156,7 @@ function ls (args, cb) {
if (0 === prefix.indexOf(process.env.HOME)) {
prefix = "~" + prefix.substr(process.env.HOME.length)
}
- ls_(args, npm.config.get("depth"), function(er, files) {
+ ls_(args, npm.config.get("depth"), function (er, files) {
console.log(files.map(function (f) {
return path.join(prefix, f)
}).join("\n").trim())
@@ -187,7 +193,7 @@ function clean (args, cb) {
// npm cache add <pkg> <ver>
// npm cache add <tarball>
// npm cache add <folder>
-exports.add = function (pkg, ver, scrub, cb) {
+cache.add = function (pkg, ver, scrub, cb) {
if (typeof cb !== "function") cb = scrub, scrub = false
if (typeof cb !== "function") cb = ver, ver = null
if (scrub) {
@@ -229,7 +235,7 @@ function add (args, cb) {
spec = args[0]
}
- log.silly("cache add", "name=%j spec=%j args=%j", name, spec, args)
+ log.verbose("cache add", "name=%j spec=%j args=%j", name, spec, args)
if (!name && !spec) return cb(usage)
@@ -278,9 +284,11 @@ function fetchAndShaCheck (u, tmp, shasum, cb) {
log.error("fetch failed", u)
return cb(er, response)
}
- if (!shasum) return cb()
+ if (!shasum) return cb(null, response)
// validate that the url we just downloaded matches the expected shasum.
- sha.check(tmp, shasum, cb)
+ sha.check(tmp, shasum, function (er) {
+ return cb(er, response, shasum)
+ })
})
}
@@ -297,6 +305,10 @@ function addRemoteTarball (u, shasum, name, cb_) {
if (iF.length > 1) return
function cb (er, data) {
+ if (data) {
+ data._from = u
+ data._resolved = u
+ }
unlock(u, function () {
var c
while (c = iF.shift()) c(er, data)
@@ -304,46 +316,55 @@ function addRemoteTarball (u, shasum, name, cb_) {
})
}
+ var tmp = path.join(npm.tmp, Date.now()+"-"+Math.random(), "tmp.tgz")
+
lock(u, function (er) {
if (er) return cb(er)
log.verbose("addRemoteTarball", [u, shasum])
- var tmp = path.join(npm.tmp, Date.now()+"-"+Math.random(), "tmp.tgz")
mkdir(path.dirname(tmp), function (er) {
if (er) return cb(er)
- // Tuned to spread 3 attempts over about a minute.
- // See formula at <https://github.com/tim-kos/node-retry>.
- var operation = retry.operation
- ( { retries: npm.config.get("fetch-retries")
- , factor: npm.config.get("fetch-retry-factor")
- , minTimeout: npm.config.get("fetch-retry-mintimeout")
- , maxTimeout: npm.config.get("fetch-retry-maxtimeout") })
-
- operation.attempt(function (currentAttempt) {
- log.info("retry", "fetch attempt " + currentAttempt
- + " at " + (new Date()).toLocaleTimeString())
- fetchAndShaCheck(u, tmp, shasum, function (er, response) {
- // Only retry on 408, 5xx or no `response`.
- var statusCode = response && response.statusCode
- var statusRetry = !statusCode || (statusCode === 408 || statusCode >= 500)
- if (er && statusRetry && operation.retry(er)) {
- log.info("retry", "will retry, error on last attempt: " + er)
- return
- }
- done(er)
- })
- })
+ addRemoteTarball_(u, tmp, shasum, done)
})
- function done (er) {
- if (er) return cb(er)
- addLocalTarball(tmp, name, cb)
- }
})
+
+ function done (er, resp, shasum) {
+ if (er) return cb(er)
+ addLocalTarball(tmp, name, shasum, cb)
+ }
}
-// For now, this is kind of dumb. Just basically treat git as
-// yet another "fetch and scrub" kind of thing.
-// Clone to temp folder, then proceed with the addLocal stuff.
+function addRemoteTarball_(u, tmp, shasum, cb) {
+ // Tuned to spread 3 attempts over about a minute.
+ // See formula at <https://github.com/tim-kos/node-retry>.
+ var operation = retry.operation
+ ( { retries: npm.config.get("fetch-retries")
+ , factor: npm.config.get("fetch-retry-factor")
+ , minTimeout: npm.config.get("fetch-retry-mintimeout")
+ , maxTimeout: npm.config.get("fetch-retry-maxtimeout") })
+
+ operation.attempt(function (currentAttempt) {
+ log.info("retry", "fetch attempt " + currentAttempt
+ + " at " + (new Date()).toLocaleTimeString())
+ fetchAndShaCheck(u, tmp, shasum, function (er, response, shasum) {
+ // Only retry on 408, 5xx or no `response`.
+ var sc = response && response.statusCode
+ var statusRetry = !sc || (sc === 408 || sc >= 500)
+ if (er && statusRetry && operation.retry(er)) {
+ log.info("retry", "will retry, error on last attempt: " + er)
+ return
+ }
+ cb(er, response, shasum)
+ })
+ })
+}
+
+// 1. cacheDir = path.join(cache,'_git-remotes',sha1(u))
+// 2. checkGitDir(cacheDir) ? 4. : 3. (rm cacheDir if necessary)
+// 3. git clone --mirror u cacheDir
+// 4. cd cacheDir && git fetch -a origin
+// 5. git archive /tmp/random.tgz
+// 6. addLocalTarball(/tmp/random.tgz) <gitref> --format=tar --prefix=package/
function addRemoteGit (u, parsed, name, cb_) {
if (typeof cb_ !== "function") cb_ = name, name = null
@@ -360,6 +381,8 @@ function addRemoteGit (u, parsed, name, cb_) {
})
}
+ var p, co // cachePath, git-ref we want to check out
+
lock(u, function (er) {
if (er) return cb(er)
@@ -370,6 +393,7 @@ function addRemoteGit (u, parsed, name, cb_) {
// it needs the ssh://
// If the path is like ssh://foo:some/path then it works, but
// only if you remove the ssh://
+ var origUrl = u
u = u.replace(/^git\+/, "")
.replace(/#.*$/, "")
@@ -378,34 +402,128 @@ function addRemoteGit (u, parsed, name, cb_) {
u = u.replace(/^ssh:\/\//, "")
}
+ var v = crypto.createHash("sha1").update(u).digest("hex").slice(0, 8)
+ v = u.replace(/[^a-zA-Z0-9]+/g, '-') + '-' + v
+
log.verbose("addRemoteGit", [u, co])
- var tmp = path.join(npm.tmp, Date.now()+"-"+Math.random())
- mkdir(path.dirname(tmp), function (er) {
+ p = path.join(npm.config.get("cache"), "_git-remotes", v)
+
+ checkGitDir(p, u, co, origUrl, function(er, data) {
+ chmodr(p, npm.modes.file, function(erChmod) {
+ if (er) return cb(er, data)
+ return cb(erChmod, data)
+ })
+ })
+ })
+}
+
+function checkGitDir (p, u, co, origUrl, cb) {
+ fs.stat(p, function (er, s) {
+ if (er) return cloneGitRemote(p, u, co, origUrl, cb)
+ if (!s.isDirectory()) return rm(p, function (er){
if (er) return cb(er)
- exec( npm.config.get("git"), ["clone", u, tmp], gitEnv(), false
- , function (er, code, stdout, stderr) {
- stdout = (stdout + "\n" + stderr).trim()
- if (er) {
- log.error("git clone " + u, stdout)
- return cb(er)
- }
- log.verbose("git clone "+u, stdout)
- exec( npm.config.get("git"), ["checkout", co], gitEnv(), false, tmp
- , function (er, code, stdout, stderr) {
- stdout = (stdout + "\n" + stderr).trim()
- if (er) {
- log.error("git checkout " + co, stdout)
- return cb(er)
- }
- log.verbose("git checkout " + co, stdout)
- addLocalDirectory(tmp, cb)
+ cloneGitRemote(p, u, co, origUrl, cb)
+ })
+
+ var git = npm.config.get("git")
+ var args = ["config", "--get", "remote.origin.url"]
+ var env = gitEnv()
+
+ exec(git, args, env, false, p, function (er, code, stdout, stderr) {
+ stdoutTrimmed = (stdout + "\n" + stderr).trim()
+ if (er || u !== stdout.trim()) {
+ log.warn( "`git config --get remote.origin.url` returned "
+ + "wrong result ("+u+")", stdoutTrimmed )
+ return rm(p, function (er){
+ if (er) return cb(er)
+ cloneGitRemote(p, u, co, origUrl, cb)
})
- })
+ }
+ log.verbose("git remote.origin.url", stdoutTrimmed)
+ archiveGitRemote(p, u, co, origUrl, cb)
+ })
+ })
+}
+
+function cloneGitRemote (p, u, co, origUrl, cb) {
+ mkdir(p, function (er) {
+ if (er) return cb(er)
+ exec( npm.config.get("git"), ["clone", "--mirror", u, p], gitEnv(), false
+ , function (er, code, stdout, stderr) {
+ stdout = (stdout + "\n" + stderr).trim()
+ if (er) {
+ log.error("git clone " + u, stdout)
+ return cb(er)
+ }
+ log.verbose("git clone " + u, stdout)
+ archiveGitRemote(p, u, co, origUrl, cb)
})
})
}
+function archiveGitRemote (p, u, co, origUrl, cb) {
+ var git = npm.config.get("git")
+ var archive = ["fetch", "-a", "origin"]
+ var resolve = ["rev-list", "-n1", co]
+ var env = gitEnv()
+
+ var errState = null
+ var n = 0
+ var resolved = null
+ var tmp
+
+ exec(git, archive, env, false, p, function (er, code, stdout, stderr) {
+ stdout = (stdout + "\n" + stderr).trim()
+ if (er) {
+ log.error("git fetch -a origin ("+u+")", stdout)
+ return cb(er)
+ }
+ log.verbose("git fetch -a origin ("+u+")", stdout)
+ tmp = path.join(npm.tmp, Date.now()+"-"+Math.random(), "tmp.tgz")
+ resolveHead()
+ })
+
+ function resolveHead () {
+ exec(git, resolve, env, false, p, function (er, code, stdout, stderr) {
+ stdout = (stdout + "\n" + stderr).trim()
+ if (er) {
+ log.error("Failed resolving git HEAD (" + u + ")", stderr)
+ return cb(er)
+ }
+ log.verbose("git rev-list -n1 " + co, stdout)
+ var parsed = url.parse(origUrl)
+ parsed.hash = stdout
+ resolved = url.format(parsed)
+ log.verbose('resolved git url', resolved)
+ next()
+ })
+ }
+
+ function next () {
+ mkdir(path.dirname(tmp), function (er) {
+ if (er) return cb(er)
+ var gzip = zlib.createGzip({ level: 9 })
+ var git = npm.config.get("git")
+ var args = ["archive", co, "--format=tar", "--prefix=package/"]
+ var out = fs.createWriteStream(tmp)
+ var env = gitEnv()
+ cb = once(cb)
+ var cp = spawn(git, args, { env: env, cwd: p })
+ cp.on("error", cb)
+ cp.stderr.on("data", function(chunk) {
+ log.silly(chunk.toString(), "git archive")
+ })
+
+ cp.stdout.pipe(gzip).pipe(out).on("close", function() {
+ addLocalTarball(tmp, function(er, data) {
+ if (data) data._resolved = resolved
+ cb(er, data)
+ })
+ })
+ })
+ }
+}
var gitEnv_
function gitEnv () {
@@ -414,7 +532,7 @@ function gitEnv () {
if (gitEnv_) return gitEnv_
gitEnv_ = {}
for (var k in process.env) {
- if (!~['GIT_PROXY_COMMAND'].indexOf(k) && k.match(/^GIT/)) continue
+ if (!~['GIT_PROXY_COMMAND','GIT_SSH'].indexOf(k) && k.match(/^GIT/)) continue
gitEnv_[k] = process.env[k]
}
return gitEnv_
@@ -435,6 +553,7 @@ function addNamed (name, x, data, cb_) {
if (iF.length > 1) return
function cb (er, data) {
+ if (data && !data._fromGithub) data._from = k
unlock(k, function () {
var c
while (c = iF.shift()) c(er, data)
@@ -454,8 +573,8 @@ function addNamed (name, x, data, cb_) {
})
}
-function addNameTag (name, tag, data, cb) {
- if (typeof cb !== "function") cb = data, data = null
+function addNameTag (name, tag, data, cb_) {
+ if (typeof cb_ !== "function") cb_ = data, data = null
log.info("addNameTag", [name, tag])
var explicit = true
if (!tag) {
@@ -463,6 +582,15 @@ function addNameTag (name, tag, data, cb) {
tag = npm.config.get("tag")
}
+ function cb(er) {
+ // might be username/project
+ // in that case, try it as a github url.
+ if (er && tag.split("/").length === 2) {
+ return maybeGithub(tag, name, er, cb_)
+ }
+ return cb_(er)
+ }
+
registry.get(name, function (er, data, json, response) {
if (er) return cb(er)
engineFilter(data)
@@ -476,13 +604,6 @@ function addNameTag (name, tag, data, cb) {
}
er = installTargetsError(tag, data)
-
- // might be username/project
- // in that case, try it as a github url.
- if (tag.split("/").length === 2) {
- return maybeGithub(tag, name, er, cb)
- }
-
return cb(er)
})
}
@@ -601,6 +722,8 @@ function addNameVersion (name, ver, data, cb) {
if (!er) readJson( path.join( npm.cache, name, ver
, "package", "package.json" )
, function (er, data) {
+ er = needVersion(er, data)
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
if (er) return fetchit()
return cb(null, data)
})
@@ -618,6 +741,11 @@ function addNameVersion (name, ver, data, cb) {
tb.protocol = url.parse(npm.config.get("registry")).protocol
delete tb.href
tb = url.format(tb)
+ // only add non-shasum'ed packages if --forced.
+ // only ancient things would lack this for good reasons nowadays.
+ if (!dist.shasum && !npm.config.get("force")) {
+ return cb(new Error("package lacks shasum: " + data._id))
+ }
return addRemoteTarball( tb
, dist.shasum
, name+"-"+ver
@@ -641,6 +769,7 @@ function addLocal (p, name, cb_) {
log.error("addLocal", "Could not install %s", p)
return cb_(er)
}
+ if (data && !data._fromGithub) data._from = p
return cb_(er, data)
})
}
@@ -667,22 +796,32 @@ function maybeGithub (p, name, er, cb) {
var u = "git://github.com/" + p
, up = url.parse(u)
log.info("maybeGithub", "Attempting to fetch %s from %s", p, u)
+
return addRemoteGit(u, up, name, function (er2, data) {
if (er2) return cb(er)
+ data._from = u
+ data._fromGithub = true
return cb(null, data)
})
}
-function addLocalTarball (p, name, cb) {
- if (typeof cb !== "function") cb = name, name = ""
+function addLocalTarball (p, name, shasum, cb_) {
+ if (typeof cb_ !== "function") cb_ = shasum, shasum = null
+ if (typeof cb_ !== "function") cb_ = name, name = ""
// if it's a tar, and not in place,
// then unzip to .tmp, add the tmp folder, and clean up tmp
- if (p.indexOf(npm.tmp) === 0) return addTmpTarball(p, name, cb)
+ if (p.indexOf(npm.tmp) === 0)
+ return addTmpTarball(p, name, shasum, cb_)
if (p.indexOf(npm.cache) === 0) {
- if (path.basename(p) !== "package.tgz") return cb(new Error(
+ if (path.basename(p) !== "package.tgz") return cb_(new Error(
"Not a valid cache tarball name: "+p))
- return addPlacedTarball(p, name, cb)
+ return addPlacedTarball(p, name, shasum, cb_)
+ }
+
+ function cb (er, data) {
+ if (data) data._resolved = p
+ return cb_(er, data)
}
// just copy it over and then add the temp tarball file.
@@ -704,7 +843,7 @@ function addLocalTarball (p, name, cb) {
log.verbose("chmod", tmp, npm.modes.file.toString(8))
fs.chmod(tmp, npm.modes.file, function (er) {
if (er) return cb(er)
- addTmpTarball(tmp, name, cb)
+ addTmpTarball(tmp, name, shasum, cb)
})
})
from.pipe(to)
@@ -767,15 +906,74 @@ function makeCacheDir (cb) {
-function addPlacedTarball (p, name, cb) {
+function addPlacedTarball (p, name, shasum, cb) {
if (!cb) cb = name, name = ""
getCacheStat(function (er, cs) {
if (er) return cb(er)
- return addPlacedTarball_(p, name, cs.uid, cs.gid, cb)
+ return addPlacedTarball_(p, name, cs.uid, cs.gid, shasum, cb)
})
}
-function addPlacedTarball_ (p, name, uid, gid, cb) {
+// Resolved sum is the shasum from the registry dist object, but
+// *not* necessarily the shasum of this tarball, because for stupid
+// historical reasons, npm re-packs each package an extra time through
+// a temp directory, so all installed packages are actually built with
+// *this* version of npm, on this machine.
+//
+// Once upon a time, this meant that we could change package formats
+// around and fix junk that might be added by incompatible tar
+// implementations. Then, for a while, it was a way to correct bs
+// added by bugs in our own tar implementation. Now, it's just
+// garbage, but cleaning it up is a pain, and likely to cause issues
+// if anything is overlooked, so it's not high priority.
+//
+// If you're bored, and looking to make npm go faster, and you've
+// already made it this far in this file, here's a better methodology:
+//
+// cache.add should really be cache.place. That is, it should take
+// a set of arguments like it does now, but then also a destination
+// folder.
+//
+// cache.add('foo@bar', '/path/node_modules/foo', cb)
+//
+// 1. Resolve 'foo@bar' to some specific:
+// - git url
+// - local folder
+// - local tarball
+// - tarball url
+// 2. If resolved through the registry, then pick up the dist.shasum
+// along the way.
+// 3. Acquire request() stream fetching bytes: FETCH
+// 4. FETCH.pipe(tar unpack stream to dest)
+// 5. FETCH.pipe(shasum generator)
+// When the tar and shasum streams both finish, make sure that the
+// shasum matches dist.shasum, and if not, clean up and bail.
+//
+// publish(cb)
+//
+// 1. read package.json
+// 2. get root package object (for rev, and versions)
+// 3. update root package doc with version info
+// 4. remove _attachments object
+// 5. remove versions object
+// 5. jsonify, remove last }
+// 6. get stream: registry.put(/package)
+// 7. write trailing-}-less JSON
+// 8. write "_attachments":
+// 9. JSON.stringify(attachments), remove trailing }
+// 10. Write start of attachments (stubs)
+// 11. JSON(filename)+':{"type":"application/octet-stream","data":"'
+// 12. acquire tar packing stream, PACK
+// 13. PACK.pipe(PUT)
+// 14. PACK.pipe(shasum generator)
+// 15. when PACK finishes, get shasum
+// 16. PUT.write('"}},') (finish _attachments
+// 17. update "versions" object with current package version
+// (including dist.shasum and dist.tarball)
+// 18. write '"versions":' + JSON(versions)
+// 19. write '}}' (versions, close main doc)
+
+function addPlacedTarball_ (p, name, uid, gid, resolvedSum, cb) {
// now we know it's in place already as .cache/name/ver/package.tgz
// unpack to .cache/name/ver/package/, read the package.json,
// and fire cb with the json data.
@@ -813,13 +1011,15 @@ function addPlacedTarball_ (p, name, uid, gid, cb) {
return cb(er)
}
readJson(path.join(folder, "package.json"), function (er, data) {
+ er = needVersion(er, data)
if (er) {
log.error("addPlacedTarball", "Couldn't read json in %j"
, folder)
return cb(er)
}
+
data.dist = data.dist || {}
- if (shasum) data.dist.shasum = shasum
+ data.dist.shasum = shasum
deprCheck(data)
asyncMap([p], function (f, cb) {
log.verbose("chmod", f, npm.modes.file.toString(8))
@@ -847,13 +1047,17 @@ function addPlacedTarball_ (p, name, uid, gid, cb) {
}
}
-function addLocalDirectory (p, name, cb) {
+// At this point, if shasum is set, it's something that we've already
+// read and checked. Just stashing it in the data at this point.
+function addLocalDirectory (p, name, shasum, cb) {
+ if (typeof cb !== "function") cb = shasum, shasum = ""
if (typeof cb !== "function") cb = name, name = ""
// if it's a folder, then read the package.json,
// tar it to the proper place, and add the cache tar
if (p.indexOf(npm.cache) === 0) return cb(new Error(
"Adding a cache directory to the cache will make the world implode."))
readJson(path.join(p, "package.json"), function (er, data) {
+ er = needVersion(er, data)
if (er) return cb(er)
deprCheck(data)
var random = Date.now() + "-" + Math.random()
@@ -881,7 +1085,7 @@ function addLocalDirectory (p, name, cb) {
chownr(made || tgz, cs.uid, cs.gid, function (er) {
if (er) return cb(er)
- addLocalTarball(tgz, name, cb)
+ addLocalTarball(tgz, name, shasum, cb)
})
})
})
@@ -889,7 +1093,7 @@ function addLocalDirectory (p, name, cb) {
})
}
-function addTmpTarball (tgz, name, cb) {
+function addTmpTarball (tgz, name, shasum, cb) {
if (!cb) cb = name, name = ""
getCacheStat(function (er, cs) {
if (er) return cb(er)
@@ -901,7 +1105,7 @@ function addTmpTarball (tgz, name, cb) {
if (er) {
return cb(er)
}
- addLocalDirectory(path.resolve(contents, "package"), name, cb)
+ addLocalDirectory(path.resolve(contents, "package"), name, shasum, cb)
})
})
}
@@ -950,6 +1154,7 @@ function lockFileName (u) {
}
var madeCache = false
+var myLocks = {}
function lock (u, cb) {
// the cache dir needs to exist already for this.
if (madeCache) then()
@@ -964,10 +1169,22 @@ function lock (u, cb) {
, wait: npm.config.get("cache-lock-wait") }
var lf = lockFileName(u)
log.verbose("lock", u, lf)
- lockFile.lock(lf, opts, cb)
+ lockFile.lock(lf, opts, function(er) {
+ if (!er) myLocks[lf] = true
+ cb(er)
+ })
}
}
function unlock (u, cb) {
+ var lf = lockFileName(u)
+ if (!myLocks[lf]) return process.nextTick(cb)
+ myLocks[lf] = false
lockFile.unlock(lockFileName(u), cb)
}
+
+function needVersion(er, data) {
+ return er ? er
+ : (data && !data.version) ? new Error("No version provided")
+ : null
+}
View
16 lib/dedupe.js
@@ -35,8 +35,16 @@ function dedupe (args, silent, cb) {
function dedupe_ (dir, filter, unavoidable, dryrun, silent, cb) {
readInstalled(path.resolve(dir), {}, null, function (er, data, counter) {
+ if (er) {
+ return cb(er)
+ }
+
+ if (!data) {
+ return cb()
+ }
+
// find out which things are dupes
- var dupes = Object.keys(counter).filter(function (k) {
+ var dupes = Object.keys(counter || {}).filter(function (k) {
if (filter.length && -1 === filter.indexOf(k)) return false
return counter[k] > 1 && !unavoidable[k]
}).reduce(function (s, k) {
@@ -225,7 +233,7 @@ function findVersions (npm, summary, cb) {
// not actually a dupe, or perhaps all the other copies were
// children of a dupe, so this'll maybe be picked up later.
if (locs.length === 0) {
- return cb()
+ return cb(null, [])
}
// { <folder>: <version> }
@@ -265,6 +273,7 @@ function readInstalled (dir, counter, parent, cb) {
})
readJson(path.resolve(dir, "package.json"), function (er, data) {
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
if (er) return cb() // not a package, probably.
counter[data.name] = counter[data.name] || 0
counter[data.name]++
@@ -293,6 +302,9 @@ function readInstalled (dir, counter, parent, cb) {
fs.readdir(path.resolve(dir, "node_modules"), function (er, c) {
children = c || [] // error is ok, just means no children.
+ children = children.filter(function (p) {
+ return !p.match(/^[\._-]/)
+ })
next()
})
View
2  lib/deprecate.js
@@ -25,7 +25,7 @@ var semver = require("semver")
function deprecate (args, cb) {
var pkg = args[0]
, msg = args[1]
- if (msg === undefined) return cb(new Error(deprecate.usage))
+ if (msg === undefined) return cb("Usage: " + deprecate.usage)
// fetch the data and make sure it exists.
pkg = pkg.split(/@/)
var name = pkg.shift()
View
229 lib/install.js
@@ -13,13 +13,16 @@
module.exports = install
-install.usage = "npm install <tarball file>"
- + "\nnpm install <tarball url>"
- + "\nnpm install <folder>"
+install.usage = "npm install"
+ "\nnpm install <pkg>"
+ "\nnpm install <pkg>@<tag>"
+ "\nnpm install <pkg>@<version>"
+ "\nnpm install <pkg>@<version range>"
+ + "\nnpm install <folder>"
+ + "\nnpm install <tarball file>"
+ + "\nnpm install <tarball url>"
+ + "\nnpm install <git:// url>"
+ + "\nnpm install <github username>/<github project>"
+ "\n\nCan specify one or more: npm install ./foo.tgz bar@stable /some/folder"
+ "\nIf no argument is supplied and ./npm-shrinkwrap.json is "
+ "\npresent, installs dependencies specified in the shrinkwrap."
@@ -58,6 +61,7 @@ install.completion = function (opts, cb) {
var npm = require("./npm.js")
, semver = require("semver")
, readJson = require("read-package-json")
+ , readInstalled = require("read-installed")
, log = require("npmlog")
, path = require("path")
, fs = require("graceful-fs")
@@ -74,12 +78,24 @@ function install (args, cb_) {
function cb (er, installed) {
if (er) return cb_(er)
- var tree = treeify(installed || [])
- , pretty = prettify(tree, installed).trim()
+ findPeerInvalid(where, function (er, problem) {
+ if (er) return cb_(er)
- if (pretty) console.log(pretty)
- if (er) return cb_(er)
- save(where, installed, tree, pretty, cb_)
+ if (problem) {
+ var peerInvalidError = new Error("The package " + problem.name +
+ " does not satisfy its siblings' peerDependencies requirements!")
+ peerInvalidError.code = "EPEERINVALID"
+ peerInvalidError.packageName = problem.name
+ peerInvalidError.peersDepending = problem.peersDepending
+ return cb(peerInvalidError)
+ }
+
+ var tree = treeify(installed || [])
+ , pretty = prettify(tree, installed).trim()
+
+ if (pretty) console.log(pretty)
+ save(where, installed, tree, pretty, cb_)
+ })
}
// the /path/to/node_modules/..
@@ -133,13 +149,19 @@ function install (args, cb_) {
, parsed = url.parse(target.replace(/^git\+/, "git"))
target = dep + "@" + target
return target
- }), where, context, cb)
+ }), where, context, function(er, results) {
+ if (er) return cb(er, results)
+ lifecycle(data, "prepublish", where, function(er) {
+ return cb(er, results)
+ })
+ })
})
}
// initial "family" is the name:version of the root, if it's got
// a package.json file.
readJson(path.resolve(where, "package.json"), function (er, data) {
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
if (er) data = null
var context = { family: {}
, ancestors: {}
@@ -155,6 +177,45 @@ function install (args, cb_) {
})
}
+function findPeerInvalid (where, cb) {
+ readInstalled(where, function (er, data) {
+ if (er) return cb(er)
+
+ cb(null, findPeerInvalid_(data.dependencies, []))
+ })
+}
+
+function findPeerInvalid_ (packageMap, fpiList) {
+ if (fpiList.indexOf(packageMap) !== -1)
+ return
+
+ fpiList.push(packageMap)
+