From ba068a90ec7dd07c8a687b28481f5b83d15d78e8 Mon Sep 17 00:00:00 2001 From: Paul B Date: Tue, 22 Oct 2013 12:05:23 +0200 Subject: [PATCH 1/3] Add a build functionality to build YUI module using Shifter --- jammit.gemspec | 2 +- lib/jammit.rb | 49 ++++++++++++++++++++++++++--- lib/jammit/builder.rb | 36 +++++++++++++++++++++ lib/jammit/dependencies.rb | 2 ++ lib/jammit/packager.rb | 16 ++++++++-- lib/jammit/shifter_builder.rb | 24 ++++++++++++++ test/config/assets-build.yml | 12 +++++++ test/fixtures/src/test3/build.json | 10 ++++++ test/fixtures/src/test3/js/test3.js | 5 +++ test/unit/test_builder.rb | 20 ++++++++++++ 10 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 lib/jammit/builder.rb create mode 100644 lib/jammit/shifter_builder.rb create mode 100644 test/config/assets-build.yml create mode 100644 test/fixtures/src/test3/build.json create mode 100644 test/fixtures/src/test3/js/test3.js create mode 100644 test/unit/test_builder.rb diff --git a/jammit.gemspec b/jammit.gemspec index 1618ec74..011a6022 100644 --- a/jammit.gemspec +++ b/jammit.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'jammit' - s.version = '0.6.6' # Keep version in sync with jammit.rb + s.version = '0.6.6clic' # Keep version in sync with jammit.rb s.date = '2013-03-20' s.homepage = "http://documentcloud.github.com/jammit/" diff --git a/lib/jammit.rb b/lib/jammit.rb index c9d6d08e..ee22e26f 100644 --- a/lib/jammit.rb +++ b/lib/jammit.rb @@ -4,7 +4,7 @@ # to all of the configuration options. module Jammit - VERSION = "0.6.6" + VERSION = "0.6.6clic" ROOT = File.expand_path(File.dirname(__FILE__) + '/..') @@ -26,6 +26,10 @@ module Jammit DEFAULT_JAVASCRIPT_COMPRESSOR = :jsmin + JAVASCRIPT_BUILDERS = [:shifter] + + DEFAULT_JAVASCRIPT_BUILDER = :shifter + CSS_COMPRESSORS = [:cssmin, :yui, :sass] DEFAULT_CSS_COMPRESSOR = :cssmin @@ -52,13 +56,13 @@ class DeprecationError < StandardError; end class << self attr_reader :configuration, :template_function, :template_namespace, - :embed_assets, :package_assets, :compress_assets, :gzip_assets, - :package_path, :mhtml_enabled, :include_jst_script, :config_path, - :javascript_compressor, :compressor_options, :css_compressor, + :embed_assets, :package_assets, :compress_assets, :build_assets, :gzip_assets, + :files_changed, :package_path, :mhtml_enabled, :include_jst_script, :config_path, + :javascript_compressor, :javascript_builder, :compressor_options, :css_compressor, :css_compressor_options, :template_extension, :template_extension_matcher, :allow_debugging, :rewrite_relative_paths, :public_root - attr_accessor :javascript_compressors, :css_compressors + attr_accessor :javascript_compressors, :javascript_builders, :css_compressors end # The minimal required configuration. @@ -67,6 +71,7 @@ class << self @package_path = DEFAULT_PACKAGE_PATH @javascript_compressors = JAVASCRIPT_COMPRESSORS + @javascript_builders = JAVASCRIPT_BUILDERS @css_compressors = CSS_COMPRESSORS # Load the complete asset configuration from the specified @config_path@. @@ -86,13 +91,16 @@ def self.load_configuration(config_path, soft=false) @package_path = conf[:package_path] || DEFAULT_PACKAGE_PATH @embed_assets = conf[:embed_assets] || conf[:embed_images] @compress_assets = !(conf[:compress_assets] == false) + @build_assets = !(conf[:build_assets] == false) @rewrite_relative_paths = !(conf[:rewrite_relative_paths] == false) @gzip_assets = !(conf[:gzip_assets] == false) @allow_debugging = !(conf[:allow_debugging] == false) @mhtml_enabled = @embed_assets && @embed_assets != "datauri" @compressor_options = symbolize_keys(conf[:compressor_options] || {}) @css_compressor_options = symbolize_keys(conf[:css_compressor_options] || {}) + @files_changed = list_git_changes set_javascript_compressor(conf[:javascript_compressor]) + set_javascript_builder(conf[:javascript_builder]) set_css_compressor(conf[:css_compressor]) set_package_assets(conf[:package_assets]) set_template_function(conf[:template_function]) @@ -146,6 +154,17 @@ def self.package!(options={}) packager.precache_all(options[:output_folder], options[:base_url]) end + # Lists the files that were changed + def self.list_git_changes + list = [] + if `git --version` =~ /[\d\.]+/ + list = `git ls-files -m`.split(/\r?\n/) + else + Jammit.warn('Please check that Git is installed and available in your PATH') + end + list + end + private # Allows command-line definition of `PUBLIC_ROOT`, for those using Jammit @@ -160,6 +179,12 @@ def self.set_javascript_compressor(value) @javascript_compressor = javascript_compressors.include?(value) ? value : DEFAULT_JAVASCRIPT_COMPRESSOR end + # Ensure that the JavaScript builder is a valid choice. + def self.set_javascript_builder(value) + value = value && value.to_sym + @javascript_builder = javascript_builders.include?(value) ? value : DEFAULT_JAVASCRIPT_BUILDER + end + # Ensure that the CSS compressor is a valid choice. def self.set_css_compressor(value) value = value && value.to_sym @@ -203,6 +228,13 @@ def self.check_java_version @checked_java_version = true end + def self.check_shifter + return true if @checked_shifter_version + version = (`shifter -v 2>&1`) + disable_build if !version + @checked_shifter_version = true + end + # If we don't have a working Java VM, then disable asset compression and # complain loudly. def self.disable_compression @@ -210,6 +242,13 @@ def self.disable_compression warn("Asset compression disabled -- Java unavailable.") end + # If we don't have a working Shifter, then disable YUI module build and + # complain loudly. + def self.disable_build + @build_assets = false + warn("Asset build disabled -- Shifter unavailable.") + end + # Jammit 0.5+ no longer supports separate template packages. def self.check_for_deprecations if @configuration[:templates] diff --git a/lib/jammit/builder.rb b/lib/jammit/builder.rb new file mode 100644 index 00000000..40d538ae --- /dev/null +++ b/lib/jammit/builder.rb @@ -0,0 +1,36 @@ + +module Jammit + # A builder needs + # - to expose a 'do_it' method to build the given files + # - to expose a 'build_file_2_src_dir' method to get the src folder form the build file + class Builder + + JAVASCRIPT_BUILDERS = { + :shifter => Jammit.javascript_builders.include?(:shifter) ? Jammit::ShifterBuilder : nil + } + + def initialize + if Jammit.javascript_builders.include?(:shifter) + Jammit.check_shifter + end + js_flavor = Jammit.javascript_builder || Jammit::DEFAULT_JAVASCRIPT_BUILDER + @js_builder = JAVASCRIPT_BUILDERS[js_flavor].new + end + + # YUI Shifter to build JS modules + def build_js(paths) + paths = [paths] unless paths.is_a? Array + if Jammit.build_assets + @js_builder.do_it(paths) + end + end + + # Check if src file has changed + def changed?(glob) + src_dir = @js_builder.build_file_2_src_dir glob + Jammit.files_changed.any? { |js| js.include? src_dir } + end + + end + +end diff --git a/lib/jammit/dependencies.rb b/lib/jammit/dependencies.rb index 9714bd8a..ba84dc9b 100644 --- a/lib/jammit/dependencies.rb +++ b/lib/jammit/dependencies.rb @@ -46,6 +46,8 @@ require 'cssmin' require 'jammit/jsmin_compressor' require 'jammit/cssmin_compressor' +require 'jammit/shifter_builder' +require 'jammit/builder' require 'jammit/compressor' require 'jammit/packager' diff --git a/lib/jammit/packager.rb b/lib/jammit/packager.rb index 26cc7313..8d654c7e 100644 --- a/lib/jammit/packager.rb +++ b/lib/jammit/packager.rb @@ -74,6 +74,10 @@ def compressor @compressor ||= Compressor.new end + def builder + @builder ||= Builder.new + end + # Return the compressed contents of a stylesheet package. def pack_stylesheets(package, variant=nil, asset_url=nil) compressor.compress_css(package_for(package, :css)[:paths], variant, asset_url) @@ -103,8 +107,16 @@ def package_for(package, extension) # Print a warning if no files were found that match the glob. def glob_files(glob) absolute = Pathname.new(glob).absolute? - paths = Dir[absolute ? glob : File.join(ASSET_ROOT, glob)].sort - Jammit.warn("No assets match '#{glob}'") if paths.empty? + glob_f = absolute ? glob : File.join(ASSET_ROOT, glob) + paths = Dir[glob_f].sort + # For a javascript asset which doesnt contain a '*' wildcard + if glob =~ /\/[^*^\/]+\.js$/ and (paths.empty? or builder.changed?(glob_f)) + Jammit.warn("File '#{glob_f}' missing") if paths.empty? + Jammit.warn("File '#{glob_f}' changed") if builder.changed?(glob_f) + builder.build_js(glob_f) + else + Jammit.warn("No assets match '#{glob}'") if paths.empty? + end paths end diff --git a/lib/jammit/shifter_builder.rb b/lib/jammit/shifter_builder.rb new file mode 100644 index 00000000..1d105943 --- /dev/null +++ b/lib/jammit/shifter_builder.rb @@ -0,0 +1,24 @@ +class Jammit::ShifterBuilder + + def do_it(js) + js.map { |p| build_file_2_src_dir p}.each { |j| shift(j) } + end + + # Replace the build/ dir name to src/ and remove filename from the path + def build_file_2_src_dir(glob) + src_glob = glob.gsub(/build/,"src") + src_dir = src_glob.gsub(/\/[^\/]*\.js$/, "") + src_dir + end + + private + + def shift(glob) + # Try to shift it + src_dir = glob + Jammit.warn("Trying to shift #{src_dir}") + FileUtils.cd(src_dir) do + `shifter` + end + end +end \ No newline at end of file diff --git a/test/config/assets-build.yml b/test/config/assets-build.yml new file mode 100644 index 00000000..80d803b5 --- /dev/null +++ b/test/config/assets-build.yml @@ -0,0 +1,12 @@ +javascript_compressor: yui +css_compressor: yui +embed_assets: on +compress_assets: true +build_assets: true +javascript_builder: shifter + +javascripts: + workspace: + - fixtures/src/test1.js + - fixtures/src/test2.js + - fixtures/build/test3/test3.js # Missing asset to try to build diff --git a/test/fixtures/src/test3/build.json b/test/fixtures/src/test3/build.json new file mode 100644 index 00000000..53e54fc7 --- /dev/null +++ b/test/fixtures/src/test3/build.json @@ -0,0 +1,10 @@ +{ + "name": "test3", + "builds": { + "test3": { + "jsfiles": [ + "test3.js" + ] + } + } +} diff --git a/test/fixtures/src/test3/js/test3.js b/test/fixtures/src/test3/js/test3.js new file mode 100644 index 00000000..ffb58525 --- /dev/null +++ b/test/fixtures/src/test3/js/test3.js @@ -0,0 +1,5 @@ +var mandelay = { + name : function() { return this.constructor.prototype; } +}; + +myself.sayHi(mandelay.name()); \ No newline at end of file diff --git a/test/unit/test_builder.rb b/test/unit/test_builder.rb new file mode 100644 index 00000000..dfa7eb13 --- /dev/null +++ b/test/unit/test_builder.rb @@ -0,0 +1,20 @@ +require 'test_helper' + +class BuilderTest < Test::Unit::TestCase + + def setup + Jammit.load_configuration('test/config/assets-build.yml') + @packager = Jammit.packager + @builder = Builder.new + end + + def teardown + FileUtils.rm_rf 'test/fixtures/build/' + end + + def test_javascript_build + build_file = 'test/fixtures/build/test3/test3.js' + assert File.exists?(build_file), "Expected #{build_file} to be generated" + end + +end From 8ef8fcb1da960c04492d794080f11c5853e480c4 Mon Sep 17 00:00:00 2001 From: Paul B Date: Tue, 22 Oct 2013 14:52:13 +0200 Subject: [PATCH 2/3] Check files changes with absolute path to be sure --- lib/jammit.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/jammit.rb b/lib/jammit.rb index ee22e26f..438367ac 100644 --- a/lib/jammit.rb +++ b/lib/jammit.rb @@ -159,6 +159,7 @@ def self.list_git_changes list = [] if `git --version` =~ /[\d\.]+/ list = `git ls-files -m`.split(/\r?\n/) + list = list.map{ |f| Pathname.new(f).absolute? ? f : File.join(ASSET_ROOT, f) } else Jammit.warn('Please check that Git is installed and available in your PATH') end From 3e457d04a3feb8d308d0e1939292c0360da257fd Mon Sep 17 00:00:00 2001 From: Paul B Date: Wed, 23 Oct 2013 17:49:51 +0200 Subject: [PATCH 3/3] Can't determine all modules with its build name. This commit builds then all modules of same hierarchie --- lib/jammit/shifter_builder.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/jammit/shifter_builder.rb b/lib/jammit/shifter_builder.rb index 1d105943..bcbee7f3 100644 --- a/lib/jammit/shifter_builder.rb +++ b/lib/jammit/shifter_builder.rb @@ -4,11 +4,10 @@ def do_it(js) js.map { |p| build_file_2_src_dir p}.each { |j| shift(j) } end - # Replace the build/ dir name to src/ and remove filename from the path + # Get the dir name to src/ def build_file_2_src_dir(glob) - src_glob = glob.gsub(/build/,"src") - src_dir = src_glob.gsub(/\/[^\/]*\.js$/, "") - src_dir + build_root = glob[/(.*)\/build\/(.*)/,1] + build_root+'/src/' if build_root end private @@ -18,7 +17,11 @@ def shift(glob) src_dir = glob Jammit.warn("Trying to shift #{src_dir}") FileUtils.cd(src_dir) do - `shifter` + Dir.glob('*').select {|f| File.directory? f}.each do |mod| + FileUtils.cd(mod) do + `shifter` + end + end end end end \ No newline at end of file