ghaki-namer 2011.11.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Gerald Kalafut
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,23 @@
1
+ = Ghaki Namer = Automatic file naming
2
+
3
+ Ghaki Namer is a series of helpers that allow file naming by a set pattern.
4
+
5
+ == Download
6
+
7
+ The latest version of Ghaki Namer can be found at
8
+
9
+ * git@github.com:ghaki/ghaki-namer.git
10
+
11
+ == Installation
12
+
13
+ The preferred method of installing Ghaki Namer is through its GEM file.
14
+
15
+ % [sudo] gem install ghaki-namer-1.0.0.gem
16
+
17
+ == License
18
+
19
+ Ghaki Namer is released under the MIT license.
20
+
21
+ == Support
22
+
23
+ Contact mailto:gerald@kalafut.org
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2011.11.30.1
@@ -0,0 +1,80 @@
1
+ ############################################################################
2
+ module Ghaki
3
+ module Namer
4
+ class Base
5
+
6
+ ######################################################################
7
+ TIME_STAMP_FMT = '%Y%m%d_%H%M%S'
8
+ RAND_STAMP_MAX = 65536 # FFFF+1
9
+ RAND_STAMP_FMT = '%04x'
10
+
11
+ ######################################################################
12
+ attr_accessor :time_stamp, :rand_stamp, :rand_stamp_max,
13
+ :ticket_generator
14
+
15
+ ######################################################################
16
+ def initialize opts={}
17
+ @time_stamp = opts[:time_stamp] || Time.now
18
+ @rand_stamp_max = opts[:rand_stamp_max] || RAND_STAMP_MAX
19
+ @rand_stamp = opts[:rand_stamp] || rand(@rand_stamp_max)
20
+ @ticket_generator = opts[:ticket_generator]
21
+ end
22
+
23
+ ######################################################################
24
+ def parse_names *get_pile
25
+ put_pile = []
26
+ get_pile.each do |item|
27
+ _parse_item put_pile, item
28
+ end
29
+ put_pile
30
+ end
31
+
32
+ ######################################################################
33
+ def ticket
34
+ @ticket ||= parse_names( *@ticket_generator).join('')
35
+ end
36
+
37
+ ######################################################################
38
+ def debug_dump out_file
39
+ out_file.box 'debug ' + self.class.to_s
40
+ out_file.reindent({
41
+ :time_stamp => self.time_stamp,
42
+ :rand_stamp => self.rand_stamp,
43
+ :rand_stamp_max => self.rand_stamp_max,
44
+ :ticket_generator => self.ticket_generator,
45
+ }.inspect)
46
+ end
47
+
48
+ ######################################################################
49
+ ######################################################################
50
+ private
51
+
52
+ ######################################################################
53
+ def _parse_item put_pile, item
54
+ case item
55
+ when String then put_pile.push(item)
56
+ when :time_stamp then put_pile.push( @time_stamp.strftime(TIME_STAMP_FMT) )
57
+ when :rand_stamp then put_pile.push( RAND_STAMP_FMT % @rand_stamp )
58
+ when Array then _parse_complex put_pile, *item
59
+ when Proc then put_pile.push( item.call() )
60
+ else
61
+ raise ArgumentError, "Invalid Path Generator: #{item.class}"
62
+ end
63
+ end
64
+
65
+ ######################################################################
66
+ def _parse_complex put_pile, item, *info
67
+ case item
68
+ when :time_stamp then put_pile.push( @time_stamp.strftime(info[0]) )
69
+ when :rand_stamp then put_pile.push( info[0] % @rand_stamp )
70
+ when :format then put_pile.push( info[0] % info[1] )
71
+ when Proc then put_pile.push( item.call( *info ) )
72
+ else
73
+ raise ArgumentError, "Invalid Path Generator: #{item.class}"
74
+ end
75
+ end
76
+
77
+ end # class
78
+ end # namespace
79
+ end # package
80
+ ############################################################################
@@ -0,0 +1,3 @@
1
+ module Ghaki
2
+ class NamerError < RuntimeError; end
3
+ end
@@ -0,0 +1,13 @@
1
+ require 'ghaki/app/plugin'
2
+ require 'ghaki/namer/files/base'
3
+
4
+ module Ghaki #:nodoc:
5
+ module Namer #:nodoc:
6
+ module Files #:nodoc:
7
+
8
+ class App < Ghaki::App::Plugin
9
+ app_plugin_make Base, :file_namer
10
+ app_plugin_link :file_namer
11
+ end
12
+
13
+ end end end
@@ -0,0 +1,142 @@
1
+ require 'fileutils'
2
+ require 'ghaki/namer/base'
3
+
4
+ module Ghaki #:nodoc:
5
+ module Namer #:nodoc:
6
+ module Files #:nodoc:
7
+
8
+ class Base < Namer::Base
9
+
10
+ ######################################################################
11
+ attr_accessor :path_generator, :base_generator,
12
+ :suffix_map, :filename_map
13
+
14
+ ######################################################################
15
+ def initialize opts={} ; super opts
16
+ @suffix_map = {}
17
+ @filename_map = {}
18
+ @path_generator = opts[:path_generator] || []
19
+ @base_generator = opts[:base_generator] || []
20
+ end
21
+
22
+ ######################################################################
23
+ def debug_dump out_file; super
24
+ out_file.puts( {
25
+ :suffix_map => self.suffix_map,
26
+ :path_generator => self.path_generator,
27
+ :base_generator => self.base_generator,
28
+ :filename_map => self.filename_map,
29
+ }.inspect )
30
+ end
31
+
32
+ ######################################################################
33
+ def generate_filename key
34
+ cur_path = parse_names( *@path_generator )
35
+ cur_base = parse_names( *@base_generator ).
36
+ push( @suffix_map[key] ).join('.')
37
+ File.join( cur_path, cur_base )
38
+ end
39
+
40
+ ######################################################################
41
+ def create_working_dirs opts={}
42
+ @filename_map.values.each do |fname|
43
+ ::FileUtils.mkdir_p( File.dirname(fname), opts )
44
+ end
45
+ self
46
+ end
47
+
48
+ ######################################################################
49
+ # RESERVE FILE NAMES
50
+ ######################################################################
51
+
52
+ #---------------------------------------------------------------------
53
+ def reserve_file token, new_suffix
54
+ old_suffix = @suffix_map[token]
55
+ if old_suffix.nil?
56
+ @suffix_map[token] = new_suffix
57
+ elsif old_suffix != new_suffix
58
+ raise NamerError, "Inconsistent File Extension: #{token.to_s} (#{old_suffix}/#{new_suffix})"
59
+ end
60
+ end
61
+
62
+ #---------------------------------------------------------------------
63
+ def reserve_files list
64
+ list.each do |key,val| reserve_file key, val end
65
+ self
66
+ end
67
+
68
+ ######################################################################
69
+ # PUT FILENAMES USING OPTS
70
+ ######################################################################
71
+
72
+ #---------------------------------------------------------------------
73
+ def opt_put_file opts, token
74
+ put_file token, opts[token] if opts.has_key?(token)
75
+ end
76
+
77
+ #---------------------------------------------------------------------
78
+ def opt_put_files opts, *tokens
79
+ tokens.each do |token| opt_put_file token, opts end
80
+ end
81
+
82
+ ######################################################################
83
+ # PUT FILENAMES DIRECTLY
84
+ ######################################################################
85
+
86
+ #---------------------------------------------------------------------
87
+ def put_file token, new_fname
88
+ old_fname = @filename_map[token]
89
+ if old_fname.nil?
90
+ @filename_map[token] = new_fname
91
+ elsif old_fname != new_fname
92
+ raise NamerError, "Inconsistent Filenaming: #{token.to_s}"
93
+ end
94
+ new_fname
95
+ end
96
+
97
+ #---------------------------------------------------------------------
98
+ def put_files list
99
+ list.each do |key,val| put_file key, val end
100
+ self
101
+ end
102
+
103
+ ######################################################################
104
+ # FREEZE FILENAMES
105
+ ######################################################################
106
+
107
+ #---------------------------------------------------------------------
108
+ def freeze_file token
109
+ @filename_map[token] || put_file( token, generate_filename( token ) )
110
+ end
111
+
112
+ #---------------------------------------------------------------------
113
+ def freeze_files tokens
114
+ tokens.each do |token| freeze_file token end
115
+ self
116
+ end
117
+
118
+ #####################################################################
119
+ alias_method :get_file, :freeze_file
120
+
121
+ ######################################################################
122
+ # ASSIGNING FILE NAMES
123
+ ######################################################################
124
+
125
+ def assign_file token, suffix
126
+ reserve_file token, suffix
127
+ freeze_file token
128
+ end
129
+
130
+ ######################################################################
131
+ def assign_files list
132
+ list.each do |key,val| assign_file key, val end
133
+ self
134
+ end
135
+
136
+ ######################################################################
137
+ def file_named? token
138
+ @filename_map[token].nil?
139
+ end
140
+
141
+ end
142
+ end end end
@@ -0,0 +1,13 @@
1
+ require 'ghaki/app/mixable'
2
+ require 'ghaki/namer/files/app'
3
+
4
+ module Ghaki #:nodoc:
5
+ module Namer #:nodoc:
6
+ module Files #:nodoc:
7
+
8
+ module Mixin
9
+ include Ghaki::App::Mixable
10
+ app_mixin_accessor App, :file_namer
11
+ end
12
+
13
+ end end end
@@ -0,0 +1,88 @@
1
+ ############################################################################
2
+ require 'ghaki/namer/base'
3
+
4
+ ############################################################################
5
+ module Ghaki module Namer module BaseTesting
6
+ describe Ghaki::Namer::Base do
7
+
8
+ ########################################################################
9
+ TIME_VAL = Time.at(1269258809) # "2010/03/22 04:53:29"
10
+ TIME_FMT = TIME_VAL.strftime(Ghaki::Namer::Base::TIME_STAMP_FMT)
11
+ RAND_VAL = 32456
12
+ RAND_FMT = Ghaki::Namer::Base::RAND_STAMP_FMT % RAND_VAL
13
+
14
+ ########################################################################
15
+ context 'object' do
16
+ subject {Ghaki::Namer::Base.new }
17
+ it { should respond_to :time_stamp }
18
+ it { should respond_to :rand_stamp }
19
+ it { should respond_to :rand_stamp_max }
20
+ it { should respond_to :parse_names }
21
+ it { should respond_to :ticket }
22
+ it { should respond_to :ticket_generator }
23
+ end
24
+
25
+ ########################################################################
26
+ describe '#new' do
27
+
28
+ context 'with specific options' do
29
+ MY_NOW = Time.now.to_i - 100
30
+ MY_NUM = 100
31
+ MY_MAX = 100
32
+ subject do
33
+ Ghaki::Namer::Base.new({
34
+ :time_stamp => MY_NOW,
35
+ :rand_stamp => MY_NUM,
36
+ :rand_stamp_max => MY_MAX,
37
+ })
38
+ end
39
+ specify { subject.time_stamp.should == MY_NOW }
40
+ specify { subject.rand_stamp.should == MY_NUM }
41
+ specify { subject.rand_stamp_max.should == MY_MAX }
42
+ end
43
+ end
44
+
45
+ ########################################################################
46
+ describe '#parse_names' do
47
+ subject do
48
+ Ghaki::Namer::Base.new({
49
+ :time_stamp => TIME_VAL,
50
+ :rand_stamp => RAND_VAL,
51
+ })
52
+ end
53
+ it 'should see time default' do
54
+ subject.parse_names(:time_stamp)[0].should == TIME_FMT
55
+ end
56
+ it 'should see rand default' do
57
+ subject.parse_names(:rand_stamp)[0].should == RAND_FMT
58
+ end
59
+ it 'should see time with format' do
60
+ subject.parse_names( [:time_stamp,'%Y/%m/%d'] )[0].should == '2010/03/22'
61
+ end
62
+ it 'should see rand with format' do
63
+ fmt = '%08d'
64
+ aft = fmt % RAND_VAL
65
+ subject.parse_names( [:rand_stamp,fmt] )[0].should == aft
66
+ end
67
+ it 'should see static values' do
68
+ out = subject.parse_names('ghaki','log')
69
+ out[0].should == 'ghaki'
70
+ out[1].should == 'log'
71
+ end
72
+ it 'should do complex formats' do
73
+ subject.parse_names( [:format,'%0.3s','phxlb13'] )[0].should == 'phx'
74
+ end
75
+ it 'should do simple lambdas' do
76
+ str = 'quack'
77
+ fun = lambda do 'quack' end
78
+ subject.parse_names(fun)[0].should == str
79
+ end
80
+ it 'should do complex lambdas' do
81
+ fun = lambda do |major,minor| major + '_' + minor end
82
+ subject.parse_names( [fun,'moo','12'] )[0].should == 'moo_12'
83
+ end
84
+ end
85
+
86
+ end
87
+ end end end
88
+ ############################################################################
@@ -0,0 +1,40 @@
1
+ ############################################################################
2
+ require 'ghaki/app/engine'
3
+ require 'ghaki/namer/files/app'
4
+
5
+ ############################################################################
6
+ module Ghaki module App module EngineTesting
7
+
8
+ SOURCE_MOD = Ghaki::Namer::Files::Base
9
+ TARGET_MOD = Ghaki::App::Engine
10
+
11
+ describe TARGET_MOD do
12
+
13
+ ######################################################################
14
+ context 'singleton' do
15
+ subject { TARGET_MOD.instance }
16
+ [ :file_namer, :file_namer_opts,
17
+ :file_namer=, :file_namer_opts=,
18
+ ].each do |token|
19
+ it { should respond_to token }
20
+ end
21
+ end
22
+
23
+ ######################################################################
24
+ context 'singleton method' do
25
+
26
+ describe '#file_namer' do
27
+ subject { TARGET_MOD.instance.file_namer }
28
+ it { should be_an_instance_of(SOURCE_MOD) }
29
+ end
30
+
31
+ describe '#file_namer_opts' do
32
+ subject { TARGET_MOD.instance.file_namer_opts }
33
+ it { should be_an_instance_of(::Hash) }
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end end end
40
+ ############################################################################
@@ -0,0 +1,36 @@
1
+ ############################################################################
2
+ require 'ghaki/namer/files/app'
3
+
4
+ ############################################################################
5
+ module Ghaki module Namer module Files module AppTesting
6
+
7
+ APP_MOD = Ghaki::Namer::Files::App
8
+ BASE_MOD = Ghaki::Namer::Files::Base
9
+
10
+ describe APP_MOD do
11
+ context 'singleton instance' do
12
+ subject { APP_MOD.instance }
13
+
14
+ it { should respond_to :file_namer }
15
+ it { should respond_to :file_namer= }
16
+ describe '#file_namer' do
17
+ subject { APP_MOD.instance.file_namer }
18
+ it { should be_an_instance_of(BASE_MOD) }
19
+ end
20
+
21
+ it { should respond_to :file_namer_opts }
22
+ it { should respond_to :file_namer_opts= }
23
+ describe '#file_namer_opts' do
24
+ subject { APP_MOD.instance.file_namer_opts }
25
+ it { should be_an_instance_of(::Hash) }
26
+ context 'defaults' do
27
+ # WORK GOES HERE
28
+ end
29
+ end
30
+
31
+ it { should respond_to :file_namer_defs }
32
+ it { should respond_to :file_namer_defs= }
33
+
34
+ end
35
+ end
36
+ end end end end
@@ -0,0 +1,75 @@
1
+ require 'ghaki/namer/files/base'
2
+
3
+ module Ghaki module Namer module Files module BaseTesting
4
+ BASE_MOD = Ghaki::Namer::Files::Base
5
+ describe BASE_MOD do
6
+
7
+ TIME_VAL = Time.at(1269258809).gmtime # "2010/03/22 11:53:29"
8
+ TIME_FMT = TIME_VAL.strftime(Ghaki::Namer::Base::TIME_STAMP_FMT)
9
+ RAND_VAL = 32456
10
+ RAND_FMT = Ghaki::Namer::Base::RAND_STAMP_FMT % RAND_VAL
11
+
12
+ ########################################################################
13
+ context 'object instance' do
14
+ subject { BASE_MOD.new }
15
+ it { should respond_to :create_working_dirs }
16
+ it { should respond_to :put_file }
17
+ it { should respond_to :put_files }
18
+ it { should respond_to :assign_file }
19
+ it { should respond_to :assign_files }
20
+ it { should respond_to :reserve_file }
21
+ it { should respond_to :reserve_files }
22
+ it { should respond_to :freeze_file }
23
+ it { should respond_to :freeze_files }
24
+ it { should respond_to :get_file }
25
+ end
26
+
27
+ ########################################################################
28
+ context 'name generation' do
29
+ subject do
30
+ BASE_MOD.new({
31
+ :time_stamp => TIME_VAL,
32
+ :rand_stamp => RAND_VAL,
33
+ :path_generator => [ '/ghaki/project', 'logs' ],
34
+ :base_generator => [:time_stamp]
35
+ })
36
+ end
37
+ describe '#reserve_file' do
38
+ it 'reserves file name' do
39
+ subject.reserve_file( :log_file, 'error.log' )
40
+ subject.get_file(:log_file).should == '/ghaki/project/logs/20100322_115329.error.log'
41
+ end
42
+ end
43
+ describe '#assign_file' do
44
+ it 'assign file name' do
45
+ subject.assign_file( :log_file, 'error.log' )
46
+ subject.get_file(:log_file).should == '/ghaki/project/logs/20100322_115329.error.log'
47
+ end
48
+ end
49
+ describe '#put_file' do
50
+ it 'stores file name' do
51
+ subject.put_file( :log_file, './error.txt' )
52
+ subject.get_file(:log_file).should == './error.txt'
53
+ end
54
+ end
55
+ end
56
+
57
+ ########################################################################
58
+ describe '#create_working_dirs' do
59
+ before(:all) do
60
+ @my_path = '/tmp/bogus'
61
+ @stor = BASE_MOD.new({
62
+ :path_generator => [@my_path],
63
+ }).assign_files({
64
+ :log_file => 'error.txt',
65
+ })
66
+ ::FileUtils.expects(:mkdir_p).with(@my_path,is_a(Hash)).once
67
+ end
68
+ it 'calls mkdir' do
69
+ @stor.create_working_dirs
70
+ end
71
+ end
72
+
73
+ end
74
+ end end end end
75
+ ############################################################################
@@ -0,0 +1,27 @@
1
+ ############################################################################
2
+ require 'ghaki/namer/files/mixin'
3
+
4
+ ############################################################################
5
+ module Ghaki module Namer module Files module MixinTesting
6
+ MIX_MOD = Ghaki::Namer::Files::Mixin
7
+ BAS_MOD = Ghaki::Namer::Files::Base
8
+ describe MIX_MOD do
9
+
10
+ class MyClass
11
+ include MIX_MOD
12
+ end
13
+
14
+ context 'including objects' do
15
+ subject { MyClass.new }
16
+ it { should respond_to :file_namer }
17
+ it { should respond_to :file_namer= }
18
+ end
19
+
20
+ describe '#file_namer' do
21
+ subject { MyClass.new.file_namer }
22
+ specify { subject.should be_an_instance_of(BAS_MOD) }
23
+ end
24
+
25
+ end
26
+ end end end end
27
+ ############################################################################
@@ -0,0 +1,6 @@
1
+ require 'mocha'
2
+
3
+ RSpec.configure do |cfg|
4
+ cfg.mock_with :mocha
5
+ cfg.color_enabled = true
6
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghaki-namer
3
+ version: !ruby/object:Gem::Version
4
+ version: 2011.11.30.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gerald Kalafut
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-30 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ghaki-app
16
+ requirement: &79714500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2011.11.29.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *79714500
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &79714280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 2.4.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *79714280
36
+ - !ruby/object:Gem::Dependency
37
+ name: mocha
38
+ requirement: &79714050 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.12
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *79714050
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &79713820 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.9.4
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *79713820
58
+ description: Series of helpers that allow file naming by a set pattern.
59
+ email: gerald@kalafut.org
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files:
63
+ - README
64
+ files:
65
+ - lib/ghaki/namer/error.rb
66
+ - lib/ghaki/namer/base.rb
67
+ - lib/ghaki/namer/files/mixin.rb
68
+ - lib/ghaki/namer/files/app.rb
69
+ - lib/ghaki/namer/files/base.rb
70
+ - README
71
+ - LICENSE
72
+ - VERSION
73
+ - spec/ghaki/namer/base_spec.rb
74
+ - spec/ghaki/namer/files/base_spec.rb
75
+ - spec/ghaki/namer/files/mixin_spec.rb
76
+ - spec/ghaki/namer/files/app_fnamer_spec.rb
77
+ - spec/ghaki/namer/files/app_engine_spec.rb
78
+ - spec/spec_helper.rb
79
+ homepage: http://ghaki.com/
80
+ licenses: []
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: 1.3.6
97
+ requirements: []
98
+ rubyforge_project: ghaki-namer
99
+ rubygems_version: 1.8.10
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Automatic file naming
103
+ test_files:
104
+ - spec/ghaki/namer/base_spec.rb
105
+ - spec/ghaki/namer/files/base_spec.rb
106
+ - spec/ghaki/namer/files/mixin_spec.rb
107
+ - spec/ghaki/namer/files/app_fnamer_spec.rb
108
+ - spec/ghaki/namer/files/app_engine_spec.rb
109
+ - spec/spec_helper.rb