Class: Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/capistrano/recipes/deploy/strategy/filter.rb

Overview

A filter knows how to copy files from one directory to another, applying mappings to the contents of these files.

You can specify the mapping using a Hash, and it will map $key fields found in each source file into the appropriate value in the target file. For example:

filter.using 'version'=>'1.2', 'build'=>Time.now

will replace all occurrences of ${version} with 1.2, and ${build} with the current date/time.

You can also specify the mapping by passing a proc or a method, that will be called for each source file, with the file name and content, returning the modified content.

Without any mapping, the filter simply copies files from the source directory into the target directory.

A filter has one target directory, but you can specify any number of source directories, either when creating the filter or calling #from. Include/exclude patterns are specified relative to the source directories, so:

filter.include '*.png'

will only include PNG files from any of the source directories. In the same way, you can use regular expressions, so:

filter.include /picture_.*\.png/

will only include PNG files starting with picture_ from any of the sources directories.

See Buildr#filter.

Defined Under Namespace

Classes: Mapper

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFilter

:nodoc:



49
50
51
52
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 49

def initialize #:nodoc:
  clear
  @force = true
end

Instance Attribute Details

#sourcesObject (readonly)

Returns the list of source directories (each being a file task).



55
56
57
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 55

def sources
  @sources
end

Instance Method Details

#clearObject

:call-seq:

clear => self

Clear filter sources and include/exclude patterns



61
62
63
64
65
66
67
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 61

def clear
  @include = []
  @exclude = []
  @sources = Rake::FileList[]
  @mapper = Mapper.new
  self
end

#exclude(*files) ⇒ Object

:call-seq:

exclude(*files) => self

Specifies files to exclude and returns self. See FileList#exclude.



133
134
135
136
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 133

def exclude(*files)
  @exclude += files.flatten
  self
end

#forceObject



69
70
71
72
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 69

def force
    @force = true
    self
end

#from(*sources) ⇒ Object

:call-seq:

from(*sources) => self

Adds additional directories from which to copy resources.

For example:

filter.from('src').into('target').using('build'=>Time.now)


86
87
88
89
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 86

def from(*sources)
  @sources |= sources.flatten.map { |dir| file(File.expand_path(dir.to_s)) }
  self
end

#include(*files) ⇒ Object Also known as: add

:call-seq:

include(*files) => self

Specifies files to include and returns self. See FileList#include.

By default all files are included. You can use this method to only include specific files from the source directory.



123
124
125
126
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 123

def include(*files)
  @include += files.flatten
  self
end

#into(dir) ⇒ Object

:call-seq:

into(dir) => self

Sets the target directory into which files are copied and returns self.

For example:

filter.from('src').into('target').using('build'=>Time.now)


110
111
112
113
114
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 110

def into(dir)
  @target_dir = dir.to_s
  @target = nil
  self
end

#mapperObject

The mapper to use. See #using.



144
145
146
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 144

def mapper #:nodoc:
  @mapper.mapper_type
end

#mappingObject

The mapping. See #using.



139
140
141
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 139

def mapping #:nodoc:
  @mapper.config
end

#noforceObject



74
75
76
77
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 74

def noforce
    @force = false
    self
end

#recursive_with_dot_files(*dirs) ⇒ Object



179
180
181
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 179

def recursive_with_dot_files(*dirs)
  FileList[dirs.map { |dir| File.join(dir, '/**/{*,.*}') }].reject { |file| File.basename(file) =~ /^[.]{1,2}$/ }
end

#relative_path(to, from = '.') ⇒ Object



183
184
185
186
187
188
189
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 183

def relative_path(to, from = '.')
  to = Pathname.new(to).cleanpath
  return to.to_s if from.nil?
  to_path = Pathname.new(File.expand_path(to.to_s, "/"))
  from_path = Pathname.new(File.expand_path(from.to_s, "/"))
  to_path.relative_path_from(from_path).to_s
end

#runObject

:call-seq:

run => boolean

Runs the filter.



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 195

def run
  copy_map = copy_map()

  mkpath target.to_s
  return false if copy_map.empty?

  copy_map.each do |path, source|
    dest = File.expand_path(path, target.to_s)
    if File.directory?(source)
      mkpath dest
    else
      mkpath File.dirname(dest)
      if @mapper.mapper_type
        mapped = @mapper.transform(File.open(source, 'rb') { |file| file.read }, path)
        File.open(dest, 'wb') { |file| file.write mapped }
      else # no mapping
        cp source, dest
      end
    end
    File.chmod(File.stat(source).mode | 0200, dest)
  end
  touch target.to_s
  true
end

#targetObject

The target directory as a file task.



92
93
94
95
96
97
98
99
100
101
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 92

def target
  return nil unless @target_dir
  unless @target
    @target = file(File.expand_path(@target_dir)) { |task| run if @target == task }
    @target.enhance @include.select {|f| f.is_a?(Rake::FileTask)}
    @target.enhance @exclude.select {|f| f.is_a?(Rake::FileTask)}
    @target.enhance copy_map.values
  end
  @target
end

#to_sObject

Returns the target directory.



221
222
223
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 221

def to_s
  target.to_s
end

#using(*args, &block) ⇒ Object

:call-seq:

using(mapping) => self
using { |file_name, contents| ... } => self

Specifies the mapping to use and returns self.

The most typical mapping uses a Hash, and the default mapping uses the Maven style, so ${key} are mapped to the values. You can change that by passing a different format as the first argument. Currently supports:

  • :ant – Map @key@.

  • :maven – Map ${key} (default).

  • :ruby – Map #{key}.

  • :erb – Map <%= key %>.

  • Regexp – Maps the matched data (e.g. /=(.*?)=/

For example:

filter.using 'version'=>'1.2'

Is the same as:

filter.using :maven, 'version'=>'1.2'

You can also pass a proc or method. It will be called with the file name and content, to return the mapped content.

Without any mapping, all files are copied as is.

To register new mapping type see the Mapper class.



174
175
176
177
# File 'lib/capistrano/recipes/deploy/strategy/filter.rb', line 174

def using(*args, &block)
  @mapper.using(*args, &block)
  self
end