filter theme_assets using globbing patterns (feature #14)

did committed Jan 04, 2016
commit 99e45965497441975cbf24c6ad81fafb9d63cd8b
Showing 6 changed files with 132 additions and 2 deletions
locomotive/wagon/cli.rb b/lib/locomotive/wagon/cli.rb +1 -0
@@ @@ -302,6 +302,7 @@ module Locomotive
desc 'deploy ENV [PATH]', 'Deploy a site to a remote Locomotive Engine'
option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only push the resource(s) passed in argument'
+ option :filter, aliases: '-f', type: 'array', default: nil, desc: 'Push specific resource entries'
option :data, aliases: '-d', type: 'boolean', default: false, desc: 'Push the content entries and the editable elements (by default, they are not)'
option :shell, type: 'boolean', default: true, desc: 'Use shell to ask for missing connection information like the site handle (in this case, take a random one)'
option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
locomotive/wagon/commands/push_command.rb b/lib/locomotive/wagon/commands/push_command.rb +2 -0
@@ @@ -5,6 +5,7 @@ require_relative 'loggers/push_logger'
require_relative_all 'concerns'
require_relative_all '../decorators/concerns'
require_relative_all '../decorators'
+ require_relative '../tools/glob'
require_relative 'push_sub_commands/push_base_command'
require_relative_all 'push_sub_commands'
@@ @@ -53,6 +54,7 @@ module Locomotive::Wagon
each_resource do |klass|
klass.push(api_client, steam_services, content_assets_pusher, remote_site) do |pusher|
pusher.with_data if options[:data]
+ pusher.only(options[:filter]) unless options[:filter].blank?
end
end
locomotive/wagon/commands/push_sub_commands/push_base_command.rb b/lib/locomotive/wagon/commands/push_sub_commands/push_base_command.rb +7 -1
@@ @@ -1,6 +1,6 @@
module Locomotive::Wagon
- class PushBaseCommand < Struct.new(:api_client, :steam_services, :content_assets_pusher, :remote_site)
+ class PushBaseCommand < Struct.new(:api_client, :steam_services, :content_assets_pusher, :remote_site, :filter)
extend Forwardable
@@ @@ -71,6 +71,12 @@ module Locomotive::Wagon
!!@with_data
end
+ def only(entities)
+ @only_entities = entities.map do |entity_or_filter|
+ Locomotive::Wagon::Glob.new(entity_or_filter.gsub(/\A\//, '')).to_regexp
+ end
+ end
+
class SkipPersistingException < Exception
end
locomotive/wagon/commands/push_sub_commands/push_theme_assets_command.rb b/lib/locomotive/wagon/commands/push_sub_commands/push_theme_assets_command.rb +10 -1
@@ @@ -6,8 +6,9 @@ module Locomotive::Wagon
def entities
repositories.theme_asset.all.map do |entity|
+ next if skip?(entity)
decorated = ThemeAssetDecorator.new(entity)
- end.sort { |a, b| a.priority <=> b.priority }
+ end.compact.sort { |a, b| a.priority <=> b.priority }
end
def decorate(entity)
@@ @@ -88,6 +89,14 @@ module Locomotive::Wagon
@sprockets_env ||= Locomotive::Steam::SprocketsEnvironment.new(File.join(path, 'public'), minify: true)
end
+ def skip?(entity)
+ return false if @only_entities.blank?
+
+ _source = entity.source.gsub('./public/', '')
+
+ !@only_entities.any? { |regexp| regexp.match(_source) }
+ end
+
end
end
locomotive/wagon/tools/glob.rb b/lib/locomotive/wagon/tools/glob.rb +86 -0
@@ @@ -0,0 +1,86 @@
+ # Original source code: https://raw.githubusercontent.com/alexch/rerun/master/lib/rerun/glob.rb
+ # License here: https://github.com/alexch/rerun/blob/master/LICENSE
+ #
+ # based on http://cpan.uwinnipeg.ca/htdocs/Text-Glob/Text/Glob.pm.html#glob_to_regex_string-
+ #
+ module Locomotive
+ module Wagon
+ class Glob
+
+ NO_LEADING_DOT = '(?=[^\.])' # todo
+ START_OF_FILENAME = '(\A|\/)' # beginning of string or a slash
+ END_OF_STRING = '\z'
+
+ def initialize(glob_string)
+ @glob_string = glob_string
+ end
+
+ def to_regexp_string
+ chars = @glob_string.split('')
+ chars = smoosh(chars)
+
+ START_OF_FILENAME + parse(chars) + END_OF_STRING
+ end
+
+ def to_regexp
+ Regexp.new(to_regexp_string)
+ end
+
+ def smoosh(chars)
+ [].tap do |out|
+ until chars.empty?
+ char = chars.shift
+ if char == "*" and chars.first == "*"
+ chars.shift
+ chars.shift if chars.first == "/"
+ out.push("**")
+ else
+ out.push(char)
+ end
+ end
+ end
+ end
+
+ protected
+
+ def parse(chars)
+ curlies, escaping = 0, false
+ chars.map do |char|
+ if escaping
+ escaping = false
+ char
+ else
+ case char
+ when '**' then "([^/]+/)*"
+ when '*' then ".*"
+ when "?" then "."
+ when "." then "\\."
+ when "{"
+ curlies += 1
+ "("
+ when "}"
+ if curlies > 0
+ curlies -= 1
+ ")"
+ else
+ char
+ end
+ when ","
+ if curlies > 0
+ "|"
+ else
+ char
+ end
+ when "\\"
+ escaping = true
+ "\\"
+ else
+ char
+ end
+ end
+ end.join
+ end
+
+ end
+ end
+ end
spec/unit/tools/glob_spec.rb +26 -0
@@ @@ -0,0 +1,26 @@
+ # encoding: utf-8
+
+ require 'spec_helper'
+
+ require_relative '../../../lib/locomotive/wagon/tools/glob.rb'
+
+ describe Locomotive::Wagon::Glob do
+
+ let(:string) { '' }
+ let(:instance) { described_class.new(string) }
+
+ describe "#to_regexp" do
+
+ subject { instance.to_regexp }
+
+ describe '**/*.css' do
+
+ let(:string) { '**/*.css' }
+
+ it { expect(subject.match('foo/bar/test.css')).not_to eq nil }
+
+ end
+
+ end
+
+ end