bpm 0.1.4 → 1.0.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (341) hide show
  1. data/CHANGELOG.md +20 -0
  2. data/README.md +1 -1
  3. data/TODO.md +90 -2
  4. data/bpm.gemspec +3 -3
  5. data/lib/bpm/cli/base.rb +103 -52
  6. data/lib/bpm/errors.rb +51 -0
  7. data/lib/bpm/init_generator.rb +1 -8
  8. data/lib/bpm/libgems_ext/libgems.rb +9 -0
  9. data/lib/bpm/local.rb +6 -11
  10. data/lib/bpm/package.rb +272 -178
  11. data/lib/bpm/pipeline/generated_asset.rb +88 -28
  12. data/lib/bpm/pipeline/plugin_asset.rb +8 -2
  13. data/lib/bpm/pipeline/source_url_processor.rb +16 -0
  14. data/lib/bpm/pipeline/transport_processor.rb +5 -3
  15. data/lib/bpm/pipeline.rb +33 -23
  16. data/lib/bpm/project.rb +492 -167
  17. data/lib/bpm/project_generator.rb +14 -1
  18. data/lib/bpm/remote.rb +6 -4
  19. data/lib/bpm/server.rb +4 -15
  20. data/lib/bpm/version.rb +2 -1
  21. data/lib/bpm.rb +2 -0
  22. data/man/bpm-add.1.ronn +22 -0
  23. data/man/bpm-build.1.ronn +22 -0
  24. data/man/bpm-compile.1.ronn +23 -0
  25. data/man/bpm-config.7.ronn +21 -0
  26. data/man/bpm-fetch.1.ronn +22 -0
  27. data/man/bpm-fetched.1.ronn +22 -0
  28. data/man/bpm-init.1.ronn +22 -0
  29. data/man/bpm-list.1.ronn +22 -0
  30. data/man/bpm-login.1.ronn +22 -0
  31. data/man/bpm-new.1.ronn +22 -0
  32. data/man/bpm-owner.1.ronn +22 -0
  33. data/man/bpm-preview.1.ronn +22 -0
  34. data/man/bpm-push.1.ronn +22 -0
  35. data/man/bpm-remove.1.ronn +22 -0
  36. data/man/bpm-unpack.1.ronn +22 -0
  37. data/man/bpm-yank.1.ronn +22 -0
  38. data/man/bpm.1.ronn +31 -0
  39. data/spec/cli/add_spec.rb +26 -7
  40. data/spec/cli/fetch_spec.rb +15 -6
  41. data/spec/cli/init_spec.rb +165 -25
  42. data/spec/cli/{build_spec.rb → pack_spec.rb} +9 -10
  43. data/spec/cli/push_spec.rb +4 -4
  44. data/spec/cli/rebuild_spec.rb +181 -0
  45. data/spec/cli/remove_spec.rb +3 -4
  46. data/spec/cli/unpack_spec.rb +6 -6
  47. data/spec/fixtures/gems/core-test-0.4.9.bpkg +0 -0
  48. data/spec/fixtures/{core-test-0.4.9.bpkg → gems/uglify-js-1.0.4.bpkg} +0 -0
  49. data/spec/fixtures/packages/core-test/extras/extra_file.html +3 -0
  50. data/spec/fixtures/packages/core-test/index.html +3 -0
  51. data/spec/fixtures/{core-test → packages/core-test}/package.json +9 -3
  52. data/spec/fixtures/packages/invalid_json/package.json +3 -0
  53. data/spec/fixtures/packages/uglify-js/README.html +825 -0
  54. data/spec/fixtures/packages/uglify-js/README.org +431 -0
  55. data/spec/fixtures/packages/uglify-js/bin/uglifyjs +305 -0
  56. data/spec/fixtures/packages/uglify-js/docstyle.css +75 -0
  57. data/spec/fixtures/packages/uglify-js/lib/parse-js.js +1 -0
  58. data/spec/fixtures/packages/uglify-js/lib/process.js +1 -0
  59. data/spec/fixtures/packages/uglify-js/lib/squeeze-more.js +1 -0
  60. data/spec/fixtures/packages/uglify-js/package.json +27 -0
  61. data/spec/fixtures/packages/uglify-js/plugins/minifier.js +6 -0
  62. data/spec/fixtures/packages/uglify-js/uglify-js.js +17 -0
  63. data/spec/fixtures/projects/hello2/README.md +21 -0
  64. data/{templates/init → spec/fixtures/projects/hello2}/assets/bpm_packages.js +6 -1
  65. data/{templates/init → spec/fixtures/projects/hello2}/assets/bpm_styles.css +1 -1
  66. data/spec/fixtures/projects/hello2/hello2.json +16 -0
  67. data/spec/fixtures/projects/hello2/index.html +13 -0
  68. data/spec/fixtures/projects/hello2/packages/a/lib/main.js +2 -0
  69. data/spec/fixtures/projects/hello2/packages/a/package.json +17 -0
  70. data/spec/fixtures/projects/hello2/packages/b/lib/main.js +2 -0
  71. data/spec/fixtures/projects/hello2/packages/b/package.json +17 -0
  72. data/spec/fixtures/projects/hello2/packages/c/lib/main.js +2 -0
  73. data/spec/fixtures/projects/hello2/packages/c/package.json +16 -0
  74. data/spec/fixtures/projects/hello_dev/LICENSE +19 -0
  75. data/spec/fixtures/projects/hello_dev/README.md +21 -0
  76. data/spec/fixtures/projects/hello_dev/app/main.js +6 -0
  77. data/spec/fixtures/projects/hello_dev/assets/bpm_libs.js +5 -0
  78. data/spec/fixtures/projects/hello_dev/assets/bpm_styles.css +6 -0
  79. data/spec/fixtures/projects/hello_dev/css/main.css +1 -0
  80. data/spec/fixtures/projects/hello_dev/hello_dev.json +25 -0
  81. data/spec/fixtures/projects/hello_dev/index.html +14 -0
  82. data/spec/fixtures/projects/hello_dev/packages/style_package/css/some_style.css +3 -0
  83. data/spec/fixtures/{minitest/minitest.json → projects/hello_dev/packages/style_package/package.json} +5 -9
  84. data/spec/fixtures/projects/hello_world/LICENSE +19 -0
  85. data/spec/fixtures/projects/hello_world/assets/bpm_packages.js +1 -0
  86. data/spec/fixtures/projects/hello_world/assets/bpm_styles.css +1 -0
  87. data/spec/fixtures/projects/hello_world/custom_dir/custom.js +1 -0
  88. data/spec/fixtures/projects/hello_world/hello_world.json +41 -0
  89. data/spec/fixtures/projects/hello_world/lib/another.js +1 -0
  90. data/spec/fixtures/{hello_world → projects/hello_world}/packages/custom_package/package.json +5 -2
  91. data/spec/fixtures/projects/hello_world/vendor/lib/something.js +1 -0
  92. data/spec/fixtures/projects/init_app/assets/bpm_libs.js +6 -0
  93. data/spec/fixtures/projects/init_app/assets/bpm_styles.css +5 -0
  94. data/spec/fixtures/projects/init_app/assets/new_project/bpm_libs.js +6 -0
  95. data/spec/fixtures/projects/init_app/assets/new_project/bpm_styles.css +5 -0
  96. data/spec/fixtures/projects/init_app/new_project.json +27 -0
  97. data/spec/fixtures/projects/init_default/assets/bpm_libs.js +6 -0
  98. data/spec/fixtures/projects/init_default/assets/bpm_styles.css +5 -0
  99. data/spec/fixtures/projects/init_default/new_project.json +15 -0
  100. data/spec/fixtures/projects/minitest/minitest.json +26 -0
  101. data/spec/fixtures/{minitest → projects/minitest}/packages/uglyduck/package.json +1 -1
  102. data/spec/fixtures/projects/needs_rake/needs_rake.json +7 -0
  103. data/spec/fixtures/{transporter → projects/transporter}/packages/transport/package.json +1 -1
  104. data/spec/package_spec.rb +343 -315
  105. data/spec/pipeline_spec.rb +89 -71
  106. data/spec/plugins/minifier_spec.rb +25 -16
  107. data/spec/plugins/transport_spec.rb +1 -1
  108. data/spec/project_spec.rb +97 -34
  109. data/spec/spec_helper.rb +41 -0
  110. data/spec/support/fake_gem_server.rb +8 -4
  111. data/spec/support/path.rb +8 -0
  112. data/spec/support/project.rb +50 -17
  113. data/templates/init/project.json +12 -14
  114. data/templates/project/LICENSE +1 -1
  115. data/templates/project/app/main.js +6 -0
  116. data/templates/project/css/main.css +1 -0
  117. data/templates/project/index.html +4 -3
  118. data/vendor/sprockets/.travis.yml +3 -2
  119. data/vendor/sprockets/Gemfile +0 -6
  120. data/vendor/sprockets/lib/sprockets/asset.rb +7 -12
  121. data/vendor/sprockets/lib/sprockets/asset_attributes.rb +70 -53
  122. data/vendor/sprockets/lib/sprockets/base.rb +1 -14
  123. data/vendor/sprockets/lib/sprockets/bundled_asset.rb +72 -45
  124. data/vendor/sprockets/lib/sprockets/caching.rb +28 -23
  125. data/vendor/sprockets/lib/sprockets/context.rb +56 -26
  126. data/vendor/sprockets/lib/sprockets/directive_processor.rb +21 -4
  127. data/vendor/sprockets/lib/sprockets/eco_template.rb +3 -4
  128. data/vendor/sprockets/lib/sprockets/ejs_template.rb +3 -4
  129. data/vendor/sprockets/lib/sprockets/engines.rb +26 -1
  130. data/vendor/sprockets/lib/sprockets/environment.rb +2 -1
  131. data/vendor/sprockets/lib/sprockets/index.rb +1 -0
  132. data/vendor/sprockets/lib/sprockets/mime.rb +38 -0
  133. data/vendor/sprockets/lib/sprockets/processing.rb +4 -45
  134. data/vendor/sprockets/lib/sprockets/static_asset.rb +5 -6
  135. data/vendor/sprockets/lib/sprockets/static_compilation.rb +4 -12
  136. data/vendor/sprockets/lib/sprockets/trail.rb +2 -1
  137. data/vendor/sprockets/test/fixtures/default/blank.gif +0 -0
  138. data/vendor/sprockets/test/fixtures/default/with_data_uri.css.erb +3 -0
  139. data/vendor/sprockets/test/test_asset.rb +121 -15
  140. data/vendor/sprockets/test/test_asset_attributes.rb +85 -21
  141. data/vendor/sprockets/test/test_environment.rb +13 -36
  142. metadata +564 -444
  143. data/spec/cli/new_spec.rb +0 -118
  144. data/spec/fixtures/hello_world/assets/bpm_packages.js +0 -13
  145. data/spec/fixtures/hello_world/assets/bpm_styles.css +0 -14
  146. data/spec/fixtures/hello_world/hello_world.json +0 -20
  147. /data/spec/fixtures/{badrake-0.8.7.bpkg → gems/badrake-0.8.7.bpkg} +0 -0
  148. /data/spec/fixtures/{builder-3.0.0.bpkg → gems/builder-3.0.0.bpkg} +0 -0
  149. /data/spec/fixtures/{bundler-1.1.pre.bpkg → gems/bundler-1.1.pre.bpkg} +0 -0
  150. /data/spec/fixtures/{coffee-1.0.1.pre.bpkg → gems/coffee-1.0.1.pre.bpkg} +0 -0
  151. /data/spec/fixtures/{custom_generator-1.0.bpkg → gems/custom_generator-1.0.bpkg} +0 -0
  152. /data/spec/fixtures/{highline-1.6.1.bpkg → gems/highline-1.6.1.bpkg} +0 -0
  153. /data/spec/fixtures/{ivory-0.0.1.bpkg → gems/ivory-0.0.1.bpkg} +0 -0
  154. /data/spec/fixtures/{jquery-1.4.3.bpkg → gems/jquery-1.4.3.bpkg} +0 -0
  155. /data/spec/fixtures/{optparse-1.0.1.bpkg → gems/optparse-1.0.1.bpkg} +0 -0
  156. /data/spec/fixtures/{rake-0.8.6.bpkg → gems/rake-0.8.6.bpkg} +0 -0
  157. /data/spec/fixtures/{rake-0.8.7.bpkg → gems/rake-0.8.7.bpkg} +0 -0
  158. /data/spec/fixtures/{spade-0.5.0.bpkg → gems/spade-0.5.0.bpkg} +0 -0
  159. /data/spec/fixtures/{src → packages}/README.txt +0 -0
  160. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/.gitignore +0 -0
  161. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/CHANGELOG.md +0 -0
  162. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/ISSUES.md +0 -0
  163. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/LICENSE +0 -0
  164. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/README.md +0 -0
  165. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/UPGRADING.md +0 -0
  166. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/bin/bundle +0 -0
  167. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/lib/bundler/definition.js +0 -0
  168. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/lib/bundler/dependency.js +0 -0
  169. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/lib/bundler/dsl.js +0 -0
  170. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/lib/bundler/ui.js +0 -0
  171. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/lib/bundler.js +0 -0
  172. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/bundle-config.ronn +0 -0
  173. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/bundle-exec.ronn +0 -0
  174. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/bundle-install.ronn +0 -0
  175. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/bundle-package.ronn +0 -0
  176. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/bundle-update.ronn +0 -0
  177. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/bundle.ronn +0 -0
  178. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/gemfile.5.ronn +0 -0
  179. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/man/index.txt +0 -0
  180. /data/spec/fixtures/{src → packages}/bundler-1.1.pre/package.json +0 -0
  181. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/bin/cake +0 -0
  182. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/bin/coffee +0 -0
  183. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/lib/coffee/base.js +0 -0
  184. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/lib/coffee/mocha/chai.js +0 -0
  185. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/lib/coffee.js +0 -0
  186. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/package.json +0 -0
  187. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/qunit/coffee/test.js +0 -0
  188. /data/spec/fixtures/{src → packages}/coffee-1.0.1.pre/qunit/test.js +0 -0
  189. /data/spec/fixtures/{core-test → packages/core-test}/bin/cot +0 -0
  190. /data/spec/fixtures/{core-test → packages/core-test}/lib/main.js +0 -0
  191. /data/spec/fixtures/{core-test → packages/core-test}/resources/runner.css +0 -0
  192. /data/spec/fixtures/{core-test → packages/core-test}/tests/test.js +0 -0
  193. /data/spec/fixtures/{custom_generator → packages/custom_generator}/lib/main.js +0 -0
  194. /data/spec/fixtures/{custom_generator → packages/custom_generator}/package.json +0 -0
  195. /data/spec/fixtures/{custom_generator → packages/custom_generator}/templates/init/project.json +0 -0
  196. /data/spec/fixtures/{custom_generator → packages/custom_generator}/templates/project/app.js +0 -0
  197. /data/spec/fixtures/{custom_generator → packages/custom_generator}/templates/project/lib/main.js +0 -0
  198. /data/spec/fixtures/{custom_generator → packages/custom_generator}/templates/project_generator.rb +0 -0
  199. /data/spec/fixtures/{src → packages}/jquery/lib/main.js +0 -0
  200. /data/spec/fixtures/{src → packages}/jquery/package.json +0 -0
  201. /data/spec/fixtures/{src → packages}/rake-0.8.6/CHANGES +0 -0
  202. /data/spec/fixtures/{src → packages}/rake-0.8.6/MIT-LICENSE +0 -0
  203. /data/spec/fixtures/{src → packages}/rake-0.8.6/README +0 -0
  204. /data/spec/fixtures/{src → packages}/rake-0.8.6/Rakefile +0 -0
  205. /data/spec/fixtures/{src → packages}/rake-0.8.6/TODO +0 -0
  206. /data/spec/fixtures/{src → packages}/rake-0.8.6/bin/rake +0 -0
  207. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/command_line_usage.rdoc +0 -0
  208. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/example/Rakefile1 +0 -0
  209. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/example/Rakefile2 +0 -0
  210. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/example/a.c +0 -0
  211. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/example/b.c +0 -0
  212. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/example/main.c +0 -0
  213. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/glossary.rdoc +0 -0
  214. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/jamis.rb +0 -0
  215. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/proto_rake.rdoc +0 -0
  216. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/rake.1.gz +0 -0
  217. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/rakefile.rdoc +0 -0
  218. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/rational.rdoc +0 -0
  219. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.4.14.rdoc +0 -0
  220. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.4.15.rdoc +0 -0
  221. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.5.0.rdoc +0 -0
  222. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.5.3.rdoc +0 -0
  223. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.5.4.rdoc +0 -0
  224. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.6.0.rdoc +0 -0
  225. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.7.0.rdoc +0 -0
  226. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.7.1.rdoc +0 -0
  227. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.7.2.rdoc +0 -0
  228. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.7.3.rdoc +0 -0
  229. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.8.0.rdoc +0 -0
  230. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.8.2.rdoc +0 -0
  231. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.8.3.rdoc +0 -0
  232. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.8.4.rdoc +0 -0
  233. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.8.5.rdoc +0 -0
  234. /data/spec/fixtures/{src → packages}/rake-0.8.6/doc/release_notes/rake-0.8.6.rdoc +0 -0
  235. /data/spec/fixtures/{src → packages}/rake-0.8.6/install.rb +0 -0
  236. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/alt_system.rb +0 -0
  237. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/classic_namespace.rb +0 -0
  238. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/clean.rb +0 -0
  239. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/contrib/compositepublisher.rb +0 -0
  240. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/contrib/ftptools.rb +0 -0
  241. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/contrib/publisher.rb +0 -0
  242. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/contrib/rubyforgepublisher.rb +0 -0
  243. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/contrib/sshpublisher.rb +0 -0
  244. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/contrib/sys.rb +0 -0
  245. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/gempackagetask.rb +0 -0
  246. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/loaders/makefile.rb +0 -0
  247. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/packagetask.rb +0 -0
  248. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/rake_test_loader.rb +0 -0
  249. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/rdoctask.rb +0 -0
  250. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/ruby182_test_unit_fix.rb +0 -0
  251. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/runtest.rb +0 -0
  252. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/tasklib.rb +0 -0
  253. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/testtask.rb +0 -0
  254. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake/win32.rb +0 -0
  255. /data/spec/fixtures/{src → packages}/rake-0.8.6/lib/rake.rb +0 -0
  256. /data/spec/fixtures/{src → packages}/rake-0.8.6/package.json +0 -0
  257. /data/spec/fixtures/{src → packages}/rake-0.8.6/test/capture_stdout.rb +0 -0
  258. /data/spec/fixtures/{src → packages}/rake-0.8.7/CHANGES +0 -0
  259. /data/spec/fixtures/{src → packages}/rake-0.8.7/MIT-LICENSE +0 -0
  260. /data/spec/fixtures/{src → packages}/rake-0.8.7/README +0 -0
  261. /data/spec/fixtures/{src → packages}/rake-0.8.7/Rakefile +0 -0
  262. /data/spec/fixtures/{src → packages}/rake-0.8.7/TODO +0 -0
  263. /data/spec/fixtures/{src → packages}/rake-0.8.7/bin/rake +0 -0
  264. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/command_line_usage.rdoc +0 -0
  265. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/example/Rakefile1 +0 -0
  266. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/example/Rakefile2 +0 -0
  267. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/example/a.c +0 -0
  268. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/example/b.c +0 -0
  269. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/example/main.c +0 -0
  270. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/glossary.rdoc +0 -0
  271. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/jamis.rb +0 -0
  272. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/proto_rake.rdoc +0 -0
  273. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/rake.1.gz +0 -0
  274. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/rakefile.rdoc +0 -0
  275. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/rational.rdoc +0 -0
  276. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.4.14.rdoc +0 -0
  277. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.4.15.rdoc +0 -0
  278. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.5.0.rdoc +0 -0
  279. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.5.3.rdoc +0 -0
  280. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.5.4.rdoc +0 -0
  281. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.6.0.rdoc +0 -0
  282. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.7.0.rdoc +0 -0
  283. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.7.1.rdoc +0 -0
  284. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.7.2.rdoc +0 -0
  285. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.7.3.rdoc +0 -0
  286. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.8.0.rdoc +0 -0
  287. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.8.2.rdoc +0 -0
  288. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.8.3.rdoc +0 -0
  289. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.8.4.rdoc +0 -0
  290. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.8.5.rdoc +0 -0
  291. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.8.6.rdoc +0 -0
  292. /data/spec/fixtures/{src → packages}/rake-0.8.7/doc/release_notes/rake-0.8.7.rdoc +0 -0
  293. /data/spec/fixtures/{src → packages}/rake-0.8.7/install.rb +0 -0
  294. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/alt_system.rb +0 -0
  295. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/classic_namespace.rb +0 -0
  296. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/clean.rb +0 -0
  297. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/contrib/compositepublisher.rb +0 -0
  298. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/contrib/ftptools.rb +0 -0
  299. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/contrib/publisher.rb +0 -0
  300. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/contrib/rubyforgepublisher.rb +0 -0
  301. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/contrib/sshpublisher.rb +0 -0
  302. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/contrib/sys.rb +0 -0
  303. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/gempackagetask.rb +0 -0
  304. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/loaders/makefile.rb +0 -0
  305. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/packagetask.rb +0 -0
  306. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/rake_test_loader.rb +0 -0
  307. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/rdoctask.rb +0 -0
  308. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/ruby182_test_unit_fix.rb +0 -0
  309. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/runtest.rb +0 -0
  310. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/tasklib.rb +0 -0
  311. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/testtask.rb +0 -0
  312. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake/win32.rb +0 -0
  313. /data/spec/fixtures/{src → packages}/rake-0.8.7/lib/rake.rb +0 -0
  314. /data/spec/fixtures/{src → packages}/rake-0.8.7/package.json +0 -0
  315. /data/spec/fixtures/{src → packages}/rake-0.8.7/test/capture_stdout.rb +0 -0
  316. /data/spec/fixtures/{src → packages}/spade/lib/main.js +0 -0
  317. /data/spec/fixtures/{src → packages}/spade/package.json +0 -0
  318. /data/spec/fixtures/{custom_name → projects/custom_name}/MyProject.json +0 -0
  319. /data/spec/fixtures/{hello_world → projects/hello2}/LICENSE +0 -0
  320. /data/{templates/project → spec/fixtures/projects/hello2}/app.js +0 -0
  321. /data/spec/fixtures/{hello_world → projects/hello_world}/README.md +0 -0
  322. /data/spec/fixtures/{hello_world → projects/hello_world}/assets/papa-smurf.jpg +0 -0
  323. /data/spec/fixtures/{hello_world → projects/hello_world}/css/dummy.css +0 -0
  324. /data/spec/fixtures/{hello_world → projects/hello_world}/lib/main.js +0 -0
  325. /data/spec/fixtures/{hello_world → projects/hello_world}/packages/custom_package/assets/dummy.txt +0 -0
  326. /data/spec/fixtures/{hello_world → projects/hello_world}/packages/custom_package/css/sample_styles.css +0 -0
  327. /data/spec/fixtures/{hello_world → projects/hello_world}/packages/custom_package/custom_dir/basic-module.js +0 -0
  328. /data/spec/fixtures/{hello_world → projects/hello_world}/packages/custom_package/lib/main.js +0 -0
  329. /data/spec/fixtures/{hello_world → projects/hello_world}/tests/main-test.js +0 -0
  330. /data/spec/fixtures/{minitest → projects/minitest}/assets/bpm_packages.js +0 -0
  331. /data/spec/fixtures/{minitest → projects/minitest}/assets/bpm_styles.css +0 -0
  332. /data/spec/fixtures/{minitest → projects/minitest}/assets/minitest/app_package.js +0 -0
  333. /data/spec/fixtures/{minitest → projects/minitest}/lib/main.js +0 -0
  334. /data/spec/fixtures/{minitest → projects/minitest}/packages/uglyduck/lib/main.js +0 -0
  335. /data/spec/fixtures/{minitest → projects/minitest}/packages/uglyduck/minifier/main.js +0 -0
  336. /data/spec/fixtures/{simple_hello/assets/bpm_packages.js → projects/simple_hello/assets/bpm_libs.js} +0 -0
  337. /data/spec/fixtures/{simple_hello → projects/simple_hello}/lib/main.js +0 -0
  338. /data/spec/fixtures/{transporter → projects/transporter}/lib/main.js +0 -0
  339. /data/spec/fixtures/{transporter → projects/transporter}/packages/transport/lib/main.js +0 -0
  340. /data/spec/fixtures/{transporter → projects/transporter}/packages/transport/transports/wrapper.js +0 -0
  341. /data/spec/fixtures/{transporter → projects/transporter}/transporter.json +0 -0
data/lib/bpm/project.rb CHANGED
@@ -20,7 +20,7 @@ module BPM
20
20
 
21
21
  def self.is_project_root?(path)
22
22
  !!project_file_path(path) ||
23
- File.exists?(File.join(path, 'assets', 'bpm_packages.js'))
23
+ File.exists?(File.join(path, 'assets', 'bpm_libs.js'))
24
24
  end
25
25
 
26
26
  def self.nearest_project(path)
@@ -53,73 +53,206 @@ module BPM
53
53
  end
54
54
 
55
55
  def bpm
56
- @bpm || BPM::VERSION
56
+ @bpm || BPM::COMPAT_VERSION
57
57
  end
58
58
 
59
- def add_dependencies(new_deps, verbose=false)
59
+ def validate_name_and_path
60
+ # do nothing. never an error
61
+ end
62
+
63
+ # Returns a fully normalized hash of build settings
64
+ def build_settings(mode=:debug)
65
+ ret = {}
66
+ deps = mode == :debug ? sorted_deps : sorted_runtime_deps
67
+ deps.each { |dep| merge_build_settings(ret, dep, mode) }
68
+ merge_build_settings ret, self, mode, false
69
+ ret
70
+ end
71
+
72
+ def all_dependencies
73
+ deps = dependencies.merge(dependencies_development || {})
74
+ deps.merge(dependencies_build)
75
+ end
76
+
77
+ def local_package_root(package_name=nil)
78
+ File.join([@root_path, 'packages', package_name].compact)
79
+ end
80
+
81
+ def internal_package_root(package_name=nil)
82
+ File.join([@root_path, BPM_DIR, 'packages', package_name].compact)
83
+ end
60
84
 
61
- old_deps = build_local_deps(false) || []
85
+ def assets_root(*paths)
86
+ File.join @root_path, 'assets', *paths
87
+ end
88
+
89
+ def preview_root(*paths)
90
+ File.join @root_path, '.bpm', 'preview', *paths
91
+ end
92
+
93
+ def build_app?
94
+ !!(bpm_build && bpm_build["#{name}/bpm_libs.js"])
95
+ end
96
+
97
+ def build_app=(value)
62
98
 
63
- hard_deps = dependencies.dup
64
- new_deps.each { |pkg_name, pkg_vers| hard_deps[pkg_name] = pkg_vers }
99
+ bpm_libs = "#{name}/bpm_libs.js"
100
+ bpm_styles = "#{name}/bpm_styles.css"
101
+
102
+ if value
103
+ if bpm_build[bpm_libs].nil?
104
+ bpm_build[bpm_libs] = {
105
+ "directories" => ["app"],
106
+ "minifier" => "uglify-js"
107
+ }
108
+ end
109
+
110
+ if bpm_build[bpm_styles].nil?
111
+ bpm_build[bpm_styles] = {
112
+ "directories" => ["css"]
113
+ }
114
+ end
115
+
116
+ else
117
+ bpm_build.delete bpm_libs
118
+ bpm_build.delete bpm_styles
119
+ end
120
+ value
121
+ end
122
+
123
+ # returns array of all assets that should be generated for this project
124
+ def buildable_asset_filenames(mode)
125
+ build_settings(mode).keys.reject { |x| !(x =~ /\..+$/) }
126
+ end
127
+
128
+ # Validates that all required files are present in the project needed
129
+ # for compile to run. This will not fetch new dependencies from remote.
130
+ def verify_and_repair(mode=:debug, verbose=false)
131
+ valid_deps = find_dependencies rescue nil
132
+ fetch_dependencies(verbose) if valid_deps.nil?
133
+ rebuild_dependency_list nil, verbose
134
+ rebuild_preview verbose
135
+ end
136
+
137
+ def rebuild_preview(verbose=false)
65
138
 
66
- exp_deps = expand_local_packages hard_deps, true
67
- core_fetch_dependencies exp_deps, :runtime, true
139
+ needs_rebuild = true
68
140
 
69
- @dependencies = hard_deps
70
- rebuild_dependencies hard_deps, verbose
141
+ if File.directory?(preview_root)
142
+ cur_previews = Dir[preview_root('**', '*')].sort.reject { |x| File.directory?(x) }
143
+ exp_filenames = buildable_asset_filenames(:debug)
144
+ exp_previews = exp_filenames.map { |x| preview_root(x) }.sort
145
+ needs_rebuild = cur_previews != exp_previews
146
+ end
147
+
148
+ if needs_rebuild
149
+ FileUtils.rm_r preview_root if File.exists? preview_root
150
+ buildable_asset_filenames(:debug).each do |filename|
151
+ next if File.exists? preview_root(filename)
152
+ FileUtils.mkdir_p File.dirname(preview_root(filename))
153
+ FileUtils.touch preview_root(filename)
154
+ end
155
+ end
71
156
 
157
+ end
158
+
159
+ # Add a new dependency
160
+ #
161
+ # Adds to the project json and installs dependency
162
+
163
+ def add_dependencies(new_deps, development=false, verbose=false)
164
+ old_deps = build_local_dependency_list(false) || []
165
+ hard_deps = (development ? dependencies_development : dependencies).merge(new_deps)
166
+ all_hard_deps = all_dependencies.merge(new_deps)
167
+ exp_deps = find_non_local_dependencies(hard_deps, true)
168
+
169
+ puts "Fetching packages from remote..." if verbose
170
+ core_fetch_dependencies(exp_deps, verbose)
171
+
172
+ if development
173
+ self.dependencies_development = hard_deps
174
+ else
175
+ self.dependencies = hard_deps
176
+ end
177
+
178
+ rebuild_dependency_list(all_hard_deps, verbose)
179
+
72
180
  local_deps.each do |dep|
73
181
  next if old_deps.find { |pkg| (pkg.name == dep.name) && (pkg.version == dep.version) }
74
- puts "Added package '#{dep.name}' (#{dep.version})"
182
+ puts "Added #{development ? "development " : ""}package '#{dep.name}' (#{dep.version})"
75
183
  end
76
184
 
77
185
  save!
78
-
79
186
  end
80
187
 
188
+
189
+ # Remove a dependency
190
+ #
191
+ # Remove dependency from json. Does not remove from system.
192
+
81
193
  def remove_dependencies(package_names, verbose=false)
82
194
 
83
195
  hard_deps = dependencies.dup
84
- old_deps = build_local_deps false
85
-
196
+ old_deps = build_local_dependency_list(false)
197
+
86
198
  package_names.each do |pkg_name|
87
199
  raise "'#{pkg_name}' is not a dependency" if hard_deps[pkg_name].nil?
88
200
  hard_deps.delete pkg_name
89
201
  end
90
202
 
91
203
  @dependencies = hard_deps
92
- rebuild_dependencies hard_deps, verbose
93
-
204
+ rebuild_dependency_list hard_deps, verbose
205
+
94
206
  old_deps.each do |dep|
95
207
  next if local_deps.find { |pkg| (pkg.name == dep.name) && (pkg.version == dep.version) }
96
208
  puts "Removed package '#{dep.name}' (#{dep.version})"
97
209
  end
98
-
210
+
99
211
  save!
100
-
212
+
101
213
  end
102
214
 
215
+
216
+ # Save to json
217
+
103
218
  def save!
104
219
  @had_changes = false
105
220
  File.open @json_path, 'w+' do |fd|
106
221
  fd.write JSON.pretty_generate as_json
107
222
  end
108
223
  end
109
-
224
+
225
+
226
+ # Get dependencies from server if not installed
227
+
110
228
  def fetch_dependencies(verbose=false)
111
- exp_deps = expand_local_packages dependencies, true
112
- core_fetch_dependencies(exp_deps, :runtime, verbose)
229
+ puts "Fetching packages from remote..." if verbose
230
+ exp_deps = find_non_local_dependencies(all_dependencies, true)
231
+ core_fetch_dependencies(exp_deps, verbose)
113
232
  end
114
233
 
234
+
115
235
  # Builds assets directory for dependent packages
236
+
116
237
  def build(mode=:debug, verbose=false)
238
+
239
+ verify_and_repair mode, verbose
240
+
117
241
  puts "Building static assets..." if verbose
118
- pipeline = BPM::Pipeline.new self
119
- asset_root = File.join root_path, 'assets'
120
242
 
243
+ report_package_locations if verbose
244
+
245
+ # Seed the project with any required files to ensure they are built
246
+ buildable_asset_filenames(mode).each do |filename|
247
+ dst_path = assets_root filename
248
+ next if File.exists? dst_path
249
+ FileUtils.mkdir_p File.dirname(dst_path)
250
+ FileUtils.touch dst_path
251
+ end
252
+
253
+ pipeline = BPM::Pipeline.new self, mode
121
254
  pipeline.buildable_assets.each do |asset|
122
- dst_path = File.join asset_root, asset.logical_path
255
+ dst_path = assets_root asset.logical_path
123
256
  FileUtils.mkdir_p File.dirname(dst_path)
124
257
 
125
258
  if asset.kind_of? Sprockets::StaticAsset
@@ -127,20 +260,26 @@ module BPM
127
260
  FileUtils.rm dst_path if File.exists? dst_path
128
261
  FileUtils.cp asset.pathname, dst_path
129
262
  else
130
- puts "~ Building #{asset.logical_path}" if verbose
263
+ $stdout << "~ Building #{asset.logical_path}..." if verbose
131
264
  File.open(dst_path, 'w+') { |fd| fd << asset.to_s }
265
+ if verbose
266
+ gzip_size = `gzip -c #{dst_path}`.size
267
+ gzip_size = gzip_size < 1024 ? "#{gzip_size} bytes" : "#{gzip_size / 1024} Kb"
268
+ $stdout << " (gzipped size: #{gzip_size})\n"
269
+ end
132
270
  end
133
271
  end
134
-
272
+
135
273
  puts "\n" if verbose
136
274
  end
137
-
275
+
276
+
138
277
  # Removes any built assets from the project. Usually called before a
139
278
  # package is removed from the project to cleanup any assets
279
+
140
280
  def unbuild(verbose=false)
141
-
142
281
  puts "Removing stale assets..." if verbose
143
-
282
+
144
283
  pipeline = BPM::Pipeline.new self
145
284
  asset_root = File.join root_path, 'assets'
146
285
  pipeline.buildable_assets.each do |asset|
@@ -149,59 +288,67 @@ module BPM
149
288
  next unless File.exists? asset_path
150
289
  puts "~ Removing #{asset.logical_path}" if verbose
151
290
  FileUtils.rm asset_path
152
-
291
+
153
292
  # cleanup empty directories
154
293
  while !File.exists?(asset_path)
155
294
  asset_path = File.dirname asset_path
156
295
  FileUtils.rmdir(asset_path) if File.directory?(asset_path)
157
- if verbose && !File.exists?(asset_path)
296
+ if verbose && !File.exists?(asset_path)
158
297
  puts "~ Removed empty directory #{File.basename asset_path}"
159
298
  end
160
299
  end
161
300
  end
162
-
301
+
163
302
  puts "\n" if verbose
164
303
  end
165
-
304
+
305
+
306
+ # Find package with name
307
+
166
308
  def package_from_name(package_name)
167
309
  return self if package_name == self.name
168
310
  local_deps.find { |pkg| pkg.name == package_name }
169
311
  end
170
-
312
+
313
+
171
314
  # Returns the path on disk to reach a given package name
315
+
172
316
  def path_from_package(package_name)
173
317
  ret = package_from_name package_name
174
318
  ret && ret.root_path
175
319
  end
176
-
320
+
321
+
177
322
  # Returns the path on disk for a given module id (relative to the project)
323
+
178
324
  def path_from_module(module_path)
179
325
  path_parts = module_path.to_s.split '/'
180
326
  package_name = path_parts.shift
181
327
  module_path = path_from_package(package_name)
328
+
182
329
  if module_path
183
330
  # expand package_name => package_name/main
184
331
  path_parts = ['main'] if path_parts.size == 0
185
-
332
+
186
333
  # expand package_name/~dirname => package_name/mapped_dirname
187
- if path_parts.first && path_parts.first =~ /^~/
188
- dirname = path_parts.shift[1..-1]
189
- else
190
- dirname = 'lib'
191
- end
334
+ dirname = (path_parts.first && path_parts.first =~ /^~/) ?
335
+ path_parts.shift[1..-1] : 'lib'
336
+
192
337
  pkg = BPM::Package.new(module_path)
193
338
  pkg.load_json
194
339
  dirname = (pkg && pkg.directories[dirname]) || dirname
195
-
340
+
196
341
  # join the rest of the path
197
342
  module_path = [package_name, dirname, *path_parts] * '/'
198
343
  end
199
-
344
+
200
345
  module_path
201
346
  end
202
-
347
+
348
+
203
349
  # Returns the package object and module id for the path. Path must match
204
350
  # a package known to the project.
351
+
205
352
  def package_and_module_from_path(path)
206
353
  path = File.expand_path path.to_s
207
354
  pkg = local_deps.find {|cur| path =~ /^#{Regexp.escape cur.root_path.to_s}\//}
@@ -238,51 +385,100 @@ module BPM
238
385
  [pkg, parts.join('/')]
239
386
  end
240
387
 
241
- def local_deps(verbose=false)
242
- @local_deps ||= build_local_deps
388
+
389
+ # List local dependency names, rebuilds list first time
390
+
391
+ def local_deps
392
+ @local_deps ||= build_local_dependency_list
243
393
  end
244
394
 
395
+ # List of local dependency names in order of dependency
245
396
 
246
- # Verifies that packages are available to meet all the dependencies
247
- def rebuild_dependencies(deps=nil, verbose=false)
397
+ def sorted_deps
398
+ dep_names = (dependencies.keys + dependencies_development.keys).uniq
399
+ ret = []
400
+
401
+ dep_names.each do |dep_name|
402
+ dep = local_deps.find { |x| x.name == dep_name }
403
+ add_sorted_dep(dep, local_deps, :both, ret)
404
+ end
405
+ ret
406
+ end
407
+
408
+ def sorted_runtime_deps
409
+
410
+ dep_names = dependencies.map { |name, vers| name }
411
+ deps = local_deps.reject { |dep| !dep_names.include?(dep.name) }
248
412
 
249
- puts "Selecting local dependencies..." if verbose
413
+ deps.inject([]) do |ret, dep|
414
+ add_sorted_dep(dep, local_deps, :runtime, ret)
415
+ ret
416
+ end
250
417
 
251
- found = locate_dependencies deps||dependencies, verbose
418
+ end
252
419
 
253
- install_root = File.join root_path, '.bpm', 'packages'
420
+ def sorted_development_deps
421
+ dep_names = dependencies_development.map { |name, vers| name }
422
+ deps = local_deps.reject { |dep| !dep_names.include?(dep.name) }
423
+
424
+ deps = deps.inject([]) do |ret, dep|
425
+ add_sorted_dep(dep, local_deps, :both, ret)
426
+ ret
427
+ end
428
+
429
+ # development deps should include all dependencies of dev deps excluding
430
+ # those that are bonafide runtime deps
431
+ runtime_deps = sorted_runtime_deps
432
+ deps.reject! { |pkg| runtime_deps.include?(pkg) }
433
+ deps
434
+ end
435
+
436
+
437
+ # Verifies that packages are available to meet all the dependencies
438
+ def rebuild_dependency_list(deps=nil, verbose=false)
439
+
440
+ found = find_dependencies(deps, verbose)
441
+
442
+ install_root = self.internal_package_root
254
443
  FileUtils.rm_r install_root if File.exists? install_root
255
444
  FileUtils.mkdir_p install_root
256
445
 
257
446
  found.each do |pkg|
258
- dst_path = File.join install_root, pkg.name
447
+ dst_path = File.join(install_root, pkg.name)
259
448
  FileUtils.ln_s pkg.root_path, dst_path
260
449
  end
261
-
450
+
262
451
  @local_deps = nil
263
452
  end
264
453
 
454
+
455
+ # Hash for conversion to json
456
+
265
457
  def as_json
266
458
  json = super
267
459
  json["bpm"] = self.bpm
268
460
  json
269
461
  end
270
-
271
- def minifier_name
272
- @attributes['pipeline'] && @attributes['pipeline']['minifier']
462
+
463
+
464
+ # Name of minifier
465
+
466
+ def minifier_name(asset_name)
467
+ build_settings[asset_name] && build_settings[asset_name]['bpm:minifier']
468
+ end
469
+
470
+ def load_json
471
+ return super if has_json?
472
+ FIELDS.keys.each{|f| send("#{c2u(f)}=", DEFAULT_CONFIG[f]) }
473
+ self.name = File.basename(@json_path, '.json')
474
+ self.version = "0.0.1"
475
+ true
273
476
  end
274
477
 
478
+
275
479
  private
276
480
 
277
- def read
278
- if File.exists? @json_path
279
- super
280
- else
281
- @attributes = DEFAULT_CONFIG.dup
282
- @attributes["name"] = File.basename(@json_path, '.json')
283
- @attributes["version"] = "0.0.1"
284
- end
285
- end
481
+ # Make sure fields are set up properly
286
482
 
287
483
  def validate_fields
288
484
  # TODO: Define other fields that are required for projects
@@ -295,56 +491,54 @@ module BPM
295
491
  end
296
492
  end
297
493
  end
298
-
494
+
495
+
299
496
  # builds a set of dependencies that excludes locally installed packages
300
497
  # and includes their dependencies instead.
301
- def expand_local_packages(deps, verbose)
302
- ret = {}
303
-
304
- todo = []
498
+
499
+ def find_non_local_dependencies(deps, verbose)
500
+ search_list = Array(deps)
305
501
  seen = []
306
-
307
- deps.each { |pkg_name, pkg_version| todo << [pkg_name, pkg_version] }
308
-
309
- while todo.size > 0
310
- package_name, package_version = todo.shift
311
- next if seen.include? package_name
312
- seen << package_name
313
-
314
- package_root = File.join(@root_path, 'packages', package_name)
315
-
316
- if File.exists? package_root
317
- pkg = BPM::Package.new package_root
502
+ ret = {}
503
+
504
+ until search_list.empty?
505
+ name, version = search_list.shift
506
+ next if seen.include?(name)
507
+ seen << name
508
+
509
+ package_root = local_package_root(name)
510
+ if File.exists?(package_root)
511
+ pkg = BPM::Package.new(package_root)
318
512
  pkg.load_json
319
513
 
320
- req = LibGems::Requirement.new(package_version)
321
- unless req.satisfied_by? LibGems::Version.new(pkg.version)
322
- raise "Local package '#{pkg.name}' (#{pkg.version}) is not compatible with required version #{package_version}"
514
+ unless satisfied_by?(version, pkg.version)
515
+ raise LocalPackageConflictError.new(pkg.name, version, pkg.version)
323
516
  end
324
-
325
- puts "~ Using local package '#{pkg.name}' (#{pkg.version})" if verbose
326
- pkg.dependencies.each do |pkg_name, pkg_vers|
327
- todo << [pkg_name, pkg_vers]
328
- end
329
-
517
+
518
+ search_list += Array(pkg.dependencies)
519
+ search_list += Array(pkg.dependencies_development)
520
+ search_list += Array(pkg.dependencies_build)
330
521
  else
331
- ret[package_name] = package_version
522
+ ret[name] = version
332
523
  end
333
524
  end
334
-
525
+
335
526
  ret
336
527
  end
337
-
528
+
529
+
338
530
  # Fetch any dependencies into local cache for the passed set of deps
339
- def core_fetch_dependencies(deps, kind, verbose)
340
- puts "Fetching packages from remote..." if verbose
531
+
532
+ def core_fetch_dependencies(deps, verbose)
341
533
  deps.each do |pkg_name, pkg_version|
342
- core_fetch_dependency pkg_name, pkg_version, kind, verbose
534
+ core_fetch_dependency pkg_name, pkg_version, :runtime, verbose
343
535
  end
344
- end
345
-
346
- def core_fetch_dependency(package_name, vers, kind, verbose)
347
-
536
+ end
537
+
538
+
539
+ # Fetch a single dependency into local cache
540
+
541
+ def core_fetch_dependency(package_name, vers, type, verbose)
348
542
  prerelease = false
349
543
  if vers == '>= 0-pre'
350
544
  prerelease = true
@@ -353,7 +547,7 @@ module BPM
353
547
  prerelease = vers =~ /[a-zA-Z]/
354
548
  end
355
549
 
356
- dep = LibGems::Dependency.new(package_name, vers, kind)
550
+ dep = LibGems::Dependency.new(package_name, vers, type)
357
551
  cur_installed = LibGems.source_index.search(dep)
358
552
 
359
553
  begin
@@ -368,18 +562,24 @@ module BPM
368
562
  end
369
563
 
370
564
  installed.each do |i|
371
- puts "Fetched #{i.name} (#{i.version}) from remote" if verbose
565
+ puts "~ Fetched #{i.name} (#{i.version}) from remote" if verbose
372
566
  end
373
-
567
+
374
568
  end
375
569
 
376
- def build_local_deps(force=true)
377
- install_root = File.join root_path, '.bpm', 'packages'
378
- unless File.exists? install_root
379
- return nil if !force
380
- rebuild_dependencies
570
+
571
+ # Get list of local dep names from the .bpm directory
572
+ #
573
+ # Pass +false+ to prevent the list from being rebuilt
574
+
575
+ def build_local_dependency_list(force=true)
576
+ install_root = self.internal_package_root
577
+
578
+ unless File.exists?(install_root)
579
+ return nil unless force
580
+ rebuild_dependency_list
381
581
  end
382
-
582
+
383
583
  Dir[File.join(install_root, '*')].map do |package_name|
384
584
  pkg = BPM::Package.new package_name
385
585
  pkg.load_json
@@ -387,87 +587,212 @@ module BPM
387
587
  end
388
588
  end
389
589
 
590
+ # Tell if package is vendored
591
+
390
592
  def has_local_package?(package_name)
391
- package_root = File.join @root_path, 'packages', package_name
392
- File.exists? package_root
593
+ File.directory?(local_package_root(package_name))
393
594
  end
394
595
 
596
+
597
+ # Tell if given version is satisfied by the passed version
598
+
395
599
  def satisfied_by?(req_vers, new_vers)
396
- req = LibGems::Requirement.new req_vers
600
+ req = LibGems::Requirement.new(req_vers)
397
601
  req_vers.sub(/^= /,'') == new_vers.sub(/^= /,'') ||
398
- req.satisfied_by?(LibGems::Version.new(new_vers))
602
+ req.satisfied_by?(LibGems::Version.new(new_vers))
399
603
  end
400
604
 
401
- def clean_version(vers)
402
- if vers == '>= 0-pre'
403
- prerel = true
404
- vers = '>= 0'
405
- else
406
- prerel = vers =~ /[a-zA-Z]/
605
+
606
+ # Get list of dependencies, searching only the project and fetched
607
+ # packages. Does not query remote server. Raises if not found or
608
+ # conflicting.
609
+ def find_dependencies(deps=nil, verbose=false)
610
+
611
+ deps ||= all_dependencies
612
+
613
+ search_list = Array(deps)
614
+ found = []
615
+ ret = []
616
+
617
+ until search_list.empty?
618
+ name, version = search_list.shift
619
+
620
+ if dup = found.find{|p| p.name == name}
621
+ # already found, check for conflicts
622
+ next if satisfied_by?(version, dup.version)
623
+ raise PackageConflictError.new(name, dup.version, version)
624
+ end
625
+
626
+ pkg = locate_package(name, version, verbose)
627
+ raise PackageNotFoundError.new(name, version) unless pkg
628
+
629
+ found << pkg
630
+
631
+ # Look up dependencies of dependencies
632
+ search_list += Array(pkg.dependencies)
633
+ search_list += Array(pkg.dependencies_development)
634
+ search_list += Array(pkg.dependencies_build)
635
+
636
+ ret << pkg
407
637
  end
408
- [vers, prerel]
638
+
639
+ ret
409
640
  end
410
-
411
- def locate_dependencies(deps, verbose)
412
- todo = []
413
- seen = []
414
- ret = []
415
-
416
- deps.each { |package_name, vers| todo << [package_name, vers] }
417
-
418
- while todo.size > 0
419
- package_name, vers = todo.shift
420
-
421
- if seen.include? package_name
422
641
 
423
- # already seen - verify requirements are not in conflict
424
- pkg = ret.find { |p| p.name == package_name }
425
- unless satisfied_by? vers, pkg.version
426
- raise "Conflicting dependencies '#{package_name}' requires #{pkg.version} and #{vers}"
427
- end
428
-
429
- next
430
- end
431
642
 
432
- seen << package_name
643
+ # Find package locally or in global cache
644
+
645
+ def locate_package(package_name, vers, verbose)
646
+ local = has_local_package?(package_name)
647
+
648
+ # It's true that we don't have a prerelase check here, but the
649
+ # previous one we had didn't do anything, so it's better to have
650
+ # none than one that doesn't work
651
+ vers = ">= 0" if vers == ">= 0-pre"
652
+ src_path = local ?
653
+ local_package_root(package_name) :
654
+ BPM::Local.new.source_root(package_name, vers)
655
+
656
+ return nil unless src_path
657
+
658
+ pkg = BPM::Package.new(src_path)
659
+ pkg.load_json # throws exception if json invalid
660
+ pkg
661
+ end
433
662
 
434
- # Find locally installed or fetched package
435
- pkg = locate_package package_name, vers, verbose
663
+ # pass in a hash of dependencies and versions
664
+ def report_package_locations(deps=nil)
665
+ deps ||= local_deps
666
+ deps.each do |dep|
667
+ is_local = has_local_package?(dep.name) ? 'local' : 'fetched'
668
+ puts "~ Using #{is_local} package '#{dep.name}' (#{dep.version})"
669
+ end
670
+ end
671
+
672
+ # Method for help in sorting dependencies
436
673
 
437
- if pkg.nil?
438
- raise "Could not find eligable package for '#{package_name}' (#{vers})"
674
+ def add_sorted_dep(dep, deps, type, sorted, seen=[])
675
+ return if seen.include? dep
676
+ seen << dep # we want to do this first to avoid cylical refs
677
+
678
+ list = {}
679
+ list.merge!(dep.dependencies) if [:both, :runtime].include?(type)
680
+ list.merge!(dep.dependencies_development) if [:both, :development].include?(type)
681
+ list.each do |dep_name, dep_vers|
682
+ found_dep = deps.find { |cur| cur.name == dep_name }
683
+ add_sorted_dep(found_dep, deps, type, sorted, seen) if found_dep
684
+ end
685
+ sorted << dep unless sorted.include? dep
686
+ end
687
+
688
+ def has_mode(opts, mode)
689
+ return false if opts.nil?
690
+ modes = Array(opts['modes'])
691
+ modes.size==0 || modes.include?('*') || modes.include?(mode.to_s)
692
+ end
693
+
694
+
695
+ ## BUILD OPTIONS
696
+
697
+ def merge_build_opts(ret, dep_name, target_name, opts, mode)
698
+
699
+ ret[target_name] ||= {}
700
+
701
+ if opts['assets']
702
+ ret[target_name] = opts['assets']
703
+ return
704
+ end
705
+
706
+ if opts['directories'] && opts['directories'].size>0
707
+ ret[target_name][dep_name] = opts['directories']
708
+ end
709
+
710
+ if opts['minifier']
711
+ if opts['minifier'].is_a? String
712
+ ret[target_name]['bpm:minifier'] = {}
713
+ ret[target_name]['bpm:minifier'][opts['minifier']] = '>= 0'
714
+ else
715
+ ret[target_name]['bpm:minifier'] = opts['minifier']
439
716
  end
717
+ end
440
718
 
441
- # Add dependencies for found package to list
442
- pkg.dependencies.each do |dep_name, dep_vers|
443
- todo << [dep_name, dep_vers]
719
+ Array(opts['include']).each do |package_name|
720
+ dep = local_deps.find { |cur_dep| cur_dep.name == package_name }
721
+ raise PackageNotFoundError.new(package_name, '>= 0') if dep.nil?
722
+ tmp_settings = {}
723
+ merge_build_settings(tmp_settings, dep, mode, true, true)
724
+ if target_name =~ /\.css$/ && tmp_settings['bpm_styles.css']
725
+ ret[target_name].merge! tmp_settings['bpm_styles.css']
726
+ elsif target_name =~ /\.js$/ && tmp_settings['bpm_libs.js']
727
+ ret[target_name].merge! tmp_settings['bpm_libs.js']
444
728
  end
445
-
446
- ret << pkg
447
729
  end
448
730
 
449
- ret
450
731
  end
732
+
733
+ def project_settings_excludes(dep_name, target_name)
734
+ exclusions = bpm_build[target_name] && bpm_build[target_name]['exclude']
735
+ exclusions && exclusions.include?(dep_name)
736
+ end
737
+
738
+ DEFAULT_BUILD_OPTS = {
739
+ 'bpm_libs.js' => {
740
+ 'directories' => ['lib'],
741
+ 'modes' => ['*']
742
+ },
743
+
744
+ 'bpm_styles.css' => {
745
+ 'directories' => ['css'],
746
+ 'modes' => ['*']
747
+ }
748
+ }
451
749
 
452
- def locate_package(package_name, vers, verbose)
453
- if has_local_package? package_name
454
- src_path = File.join root_path, 'packages', package_name
455
- pkg = BPM::Package.new src_path
456
- pkg.load_json
457
- puts "~ Using local package '#{pkg.name}' (#{pkg.version})" if verbose
458
- else
459
- vers, prerel = clean_version vers
460
- src_path = BPM::Local.new.source_root package_name, vers, prerel
461
- if src_path
462
- pkg = BPM::Package.new src_path
463
- pkg.load_json
464
- puts "~ Using fetched package '#{pkg.name}' (#{pkg.version})" if verbose
750
+ def soft_merge(base, ext)
751
+ ret = base.dup
752
+ ext.each do |key, value|
753
+ if ret[key].is_a?(Hash) && value.is_a?(Hash)
754
+ ret[key] = soft_merge(ret[key], value)
755
+ else
756
+ ret[key] = value
465
757
  end
466
758
  end
467
-
468
- pkg
759
+ ret
469
760
  end
470
761
 
762
+ def default_build_opts(dep_name)
763
+ @default_build_opts ||= {}
764
+ ret = @default_build_opts[dep_name]
765
+ if ret.nil?
766
+ ret = DEFAULT_BUILD_OPTS.dup
767
+ ret[dep_name] = {
768
+ "assets" => %w(resources assets),
769
+ "modes" => ["*"]
770
+ }
771
+
772
+ ret["#{dep_name}/bpm_tests.js"] = {
773
+ 'directories' => ['tests'],
774
+ 'modes' => ['debug']
775
+ }
776
+
777
+ @default_build_opts[dep_name] = ret
778
+ end
779
+ ret
780
+ end
781
+
782
+ def merge_build_settings(ret, dep, mode, include_defaults=true, ignore_excludes=false)
783
+
784
+ bpm_opts = dep.bpm_build
785
+ if include_defaults
786
+ bpm_opts = soft_merge default_build_opts(dep.name), bpm_opts
787
+ end
788
+
789
+ bpm_opts.each do |target_name, opts|
790
+ next if !has_mode(opts, mode)
791
+ next if !ignore_excludes && project_settings_excludes(dep.name, target_name)
792
+ merge_build_opts ret, dep.name, target_name, opts, mode
793
+ end
794
+ end
795
+
471
796
  end
472
797
 
473
798
  end