app_stack 1.3.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +6 -5
  3. data/Gemfile.lock +17 -5
  4. data/README.md +13 -1
  5. data/app_stack.gemspec +6 -5
  6. data/lib/app_stack/app.rb +86 -0
  7. data/lib/app_stack/cli_options.rb +42 -36
  8. data/lib/app_stack/compare_list.rb +195 -0
  9. data/lib/app_stack/configuration.rb +119 -0
  10. data/lib/app_stack/operator.rb +60 -0
  11. data/lib/app_stack/version.rb +1 -1
  12. data/lib/app_stack.rb +34 -6
  13. data/spec/app_stack_spec.rb +17 -0
  14. data/spec/cli_options_spec.rb +20 -0
  15. data/spec/compare_list_spec.rb +18 -0
  16. data/spec/configuration_spec.rb +95 -0
  17. data/spec/examples/la-assets-helper/app_stack.yml +14 -0
  18. data/spec/examples/la-assets-helper/lib/la_assets.rb +319 -0
  19. data/spec/examples/la-import_app/Trivia.erb +2 -0
  20. data/spec/examples/la-import_app/app_stack.yml +83 -0
  21. data/spec/examples/la-mongoid/app_stack.yml +49 -0
  22. data/spec/examples/la-mongoid/config/boot.rb +15 -0
  23. data/spec/examples/la-mongoid/config/database.rb +12 -0
  24. data/spec/examples/la-mongoid/config/mongoid.yml +22 -0
  25. data/spec/examples/la-mongoid/config/mongoid.yml.erb +22 -0
  26. data/spec/examples/la-sinatra/Gemfile.erb +11 -0
  27. data/spec/examples/la-sinatra/app_stack.yml +16 -0
  28. data/spec/examples/no-stacked/some_list.rb +4 -0
  29. data/spec/examples/sample_config/app_stack.yml +82 -0
  30. data/spec/examples/sample_config/hash_export.yml +4 -0
  31. data/spec/load_stack_spec.rb +13 -0
  32. data/spec/spec_helper.rb +7 -2
  33. data/tags +87 -34
  34. metadata +66 -87
  35. data/.app_stack.yml +0 -14
  36. data/bin/config_assets +0 -3
  37. data/lib/app_stack/copy_list_builder.rb +0 -147
  38. data/lib/app_stack/local_files_parser.rb +0 -95
  39. data/lib/app_stack/stack_app.rb +0 -119
  40. data/spec/config_spec.rb +0 -82
  41. data/spec/fixtures/config_sample/sample.yml +0 -19
  42. data/spec/fixtures/sample_files/module_1/Gemfile.erb +0 -1
  43. data/spec/fixtures/sample_files/module_1/app_stack.yml +0 -10
  44. data/spec/fixtures/sample_files/module_1/config/boot_sample.rb +0 -0
  45. data/spec/fixtures/sample_files/module_1/doc/excluding.txt +0 -1
  46. data/spec/fixtures/sample_files/module_1/doc/including.txt +0 -0
  47. data/spec/fixtures/sample_files/module_1/lib/mixins/b_lib.rb +0 -0
  48. data/spec/fixtures/sample_files/module_1/lib/mixins/s_lib.rb +0 -0
  49. data/spec/fixtures/sample_files/module_1/lib/samples/a_lib.rb +0 -0
  50. data/spec/fixtures/sample_files/module_1/spec/config_spec.rb +0 -0
  51. data/spec/fixtures/sample_files/module_2/Gemfile +0 -0
  52. data/spec/fixtures/sample_files/module_2/Gemfile.liquid +0 -1
  53. data/spec/fixtures/sample_files/module_2/app/lib/sequence.rb +0 -0
  54. data/spec/fixtures/sample_files/module_2/app_stack.yml +0 -3
  55. data/spec/fixtures/sample_files/module_3/app_stack.yml +0 -3
  56. data/spec/fixtures/sample_files/module_3/bin/del +0 -0
  57. data/spec/fixtures/sample_files/module_3/bin/rm +0 -0
  58. data/spec/fixtures/sample_files/module_3/config/application.yml +0 -0
  59. data/spec/fixtures/sample_files/module_3/config/database_development.yml +0 -0
  60. data/spec/fixtures/sample_files/module_3/config/database_production.yml +0 -0
  61. data/spec/fixtures/sample_files/module_3/lib/libfile_1.rb +0 -0
  62. data/spec/fixtures/sample_files/module_3/lib/libfile_2.rb +0 -0
  63. data/spec/fixtures/sample_files/my_app/app_stack.yml +0 -15
  64. data/spec/fixtures/sample_files/my_app/doc/excluding.txt +0 -1
  65. data/spec/fixtures/sample_files/my_app/local.conf +0 -0
  66. data/spec/fixtures/sample_files/my_app/local.conf.erb +0 -1
  67. data/spec/fixtures/sample_files/my_app/spec/config_spec.rb +0 -0
  68. data/spec/fixtures/sample_files/my_app_back/app_stack.yml +0 -15
  69. data/spec/fixtures/sample_files/my_app_back/doc/excluding.txt +0 -1
  70. data/spec/fixtures/sample_files/my_app_back/local.conf +0 -0
  71. data/spec/fixtures/sample_files/my_app_back/local.conf.erb +0 -1
  72. data/spec/fixtures/sample_files/my_app_back/spec/config_spec.rb +0 -0
  73. data/spec/merger_spec.rb +0 -43
  74. data/spec/stackup_spec.rb +0 -18
  75. /data/{file.erb → spec/examples/find_conf_file/both/.app_stack.yml} +0 -0
  76. /data/spec/{fixtures/sample_files/module_1/Gemfile → examples/find_conf_file/both/app_stack.yml} +0 -0
  77. /data/spec/{fixtures/sample_files/module_1/Rakefile → examples/find_conf_file/with_dot/.app_stack.yml} +0 -0
  78. /data/spec/{fixtures/config_sample → examples/sample_config}/wrong_key.yml +0 -0
  79. /data/spec/{fixtures/config_sample → examples/sample_config}/wrong_type.yml +0 -0
metadata CHANGED
@@ -1,68 +1,60 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
5
- prerelease:
4
+ version: 1.4.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Huang Wei
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-10-15 00:00:00.000000000 Z
11
+ date: 2013-11-13 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: tilt
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
21
- version: 1.4.1
19
+ version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
29
- version: 1.4.1
26
+ version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: term-ansicolor
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
37
- version: 1.2.2
33
+ version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
45
- version: 1.2.2
40
+ version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: activesupport
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
53
- version: 3.2.14
47
+ version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
61
- version: 3.2.14
54
+ version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: diffy
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,35 +69,45 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rspec
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
85
- version: 2.14.1
75
+ version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
93
- version: 2.14.1
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
94
97
  - !ruby/object:Gem::Dependency
95
98
  name: simplecov
96
99
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
100
  requirements:
99
101
  - - ! '>='
100
102
  - !ruby/object:Gem::Version
101
- version: 0.7.1
103
+ version: '0'
102
104
  type: :development
103
105
  prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
107
  requirements:
107
108
  - - ! '>='
108
109
  - !ruby/object:Gem::Version
109
- version: 0.7.1
110
+ version: '0'
110
111
  description: Merge app source code in a stack to increase module reusability
111
112
  email: huangw@7lime.com
112
113
  executables:
@@ -114,99 +115,77 @@ executables:
114
115
  extensions: []
115
116
  extra_rdoc_files: []
116
117
  files:
117
- - .app_stack.yml
118
118
  - Gemfile
119
119
  - Gemfile.lock
120
120
  - README.md
121
121
  - app_stack.gemspec
122
- - bin/config_assets
123
122
  - bin/stackup
124
- - file.erb
125
123
  - lib/app_stack.rb
124
+ - lib/app_stack/app.rb
126
125
  - lib/app_stack/cli_options.rb
127
- - lib/app_stack/copy_list_builder.rb
128
- - lib/app_stack/local_files_parser.rb
129
- - lib/app_stack/stack_app.rb
126
+ - lib/app_stack/compare_list.rb
127
+ - lib/app_stack/configuration.rb
128
+ - lib/app_stack/operator.rb
130
129
  - lib/app_stack/version.rb
131
- - spec/config_spec.rb
132
- - spec/fixtures/config_sample/sample.yml
133
- - spec/fixtures/config_sample/wrong_key.yml
134
- - spec/fixtures/config_sample/wrong_type.yml
135
- - spec/fixtures/sample_files/module_1/Gemfile
136
- - spec/fixtures/sample_files/module_1/Gemfile.erb
137
- - spec/fixtures/sample_files/module_1/Rakefile
138
- - spec/fixtures/sample_files/module_1/app_stack.yml
139
- - spec/fixtures/sample_files/module_1/config/boot_sample.rb
140
- - spec/fixtures/sample_files/module_1/doc/excluding.txt
141
- - spec/fixtures/sample_files/module_1/doc/including.txt
142
- - spec/fixtures/sample_files/module_1/lib/mixins/b_lib.rb
143
- - spec/fixtures/sample_files/module_1/lib/mixins/s_lib.rb
144
- - spec/fixtures/sample_files/module_1/lib/samples/a_lib.rb
145
- - spec/fixtures/sample_files/module_1/spec/config_spec.rb
146
- - spec/fixtures/sample_files/module_2/Gemfile
147
- - spec/fixtures/sample_files/module_2/Gemfile.liquid
148
- - spec/fixtures/sample_files/module_2/app/lib/sequence.rb
149
- - spec/fixtures/sample_files/module_2/app_stack.yml
150
- - spec/fixtures/sample_files/module_3/app_stack.yml
151
- - spec/fixtures/sample_files/module_3/bin/del
152
- - spec/fixtures/sample_files/module_3/bin/rm
153
- - spec/fixtures/sample_files/module_3/config/application.yml
154
- - spec/fixtures/sample_files/module_3/config/database_development.yml
155
- - spec/fixtures/sample_files/module_3/config/database_production.yml
156
- - spec/fixtures/sample_files/module_3/lib/libfile_1.rb
157
- - spec/fixtures/sample_files/module_3/lib/libfile_2.rb
158
- - spec/fixtures/sample_files/my_app/app_stack.yml
159
- - spec/fixtures/sample_files/my_app/doc/excluding.txt
160
- - spec/fixtures/sample_files/my_app/local.conf
161
- - spec/fixtures/sample_files/my_app/local.conf.erb
162
- - spec/fixtures/sample_files/my_app/spec/config_spec.rb
163
- - spec/fixtures/sample_files/my_app_back/app_stack.yml
164
- - spec/fixtures/sample_files/my_app_back/doc/excluding.txt
165
- - spec/fixtures/sample_files/my_app_back/local.conf
166
- - spec/fixtures/sample_files/my_app_back/local.conf.erb
167
- - spec/fixtures/sample_files/my_app_back/spec/config_spec.rb
168
- - spec/merger_spec.rb
130
+ - spec/app_stack_spec.rb
131
+ - spec/cli_options_spec.rb
132
+ - spec/compare_list_spec.rb
133
+ - spec/configuration_spec.rb
134
+ - spec/examples/find_conf_file/both/.app_stack.yml
135
+ - spec/examples/find_conf_file/both/app_stack.yml
136
+ - spec/examples/find_conf_file/with_dot/.app_stack.yml
137
+ - spec/examples/la-assets-helper/app_stack.yml
138
+ - spec/examples/la-assets-helper/lib/la_assets.rb
139
+ - spec/examples/la-import_app/Trivia.erb
140
+ - spec/examples/la-import_app/app_stack.yml
141
+ - spec/examples/la-mongoid/app_stack.yml
142
+ - spec/examples/la-mongoid/config/boot.rb
143
+ - spec/examples/la-mongoid/config/database.rb
144
+ - spec/examples/la-mongoid/config/mongoid.yml
145
+ - spec/examples/la-mongoid/config/mongoid.yml.erb
146
+ - spec/examples/la-sinatra/Gemfile.erb
147
+ - spec/examples/la-sinatra/app_stack.yml
148
+ - spec/examples/no-stacked/some_list.rb
149
+ - spec/examples/sample_config/app_stack.yml
150
+ - spec/examples/sample_config/hash_export.yml
151
+ - spec/examples/sample_config/wrong_key.yml
152
+ - spec/examples/sample_config/wrong_type.yml
153
+ - spec/load_stack_spec.rb
169
154
  - spec/spec_helper.rb
170
- - spec/stackup_spec.rb
171
155
  - tags
172
156
  homepage: https://github.com/7lime/app_stack-gem
173
157
  licenses:
174
158
  - MIT
159
+ metadata: {}
175
160
  post_install_message:
176
161
  rdoc_options: []
177
162
  require_paths:
178
163
  - lib
179
164
  required_ruby_version: !ruby/object:Gem::Requirement
180
- none: false
181
165
  requirements:
182
166
  - - ! '>='
183
167
  - !ruby/object:Gem::Version
184
168
  version: '0'
185
169
  required_rubygems_version: !ruby/object:Gem::Requirement
186
- none: false
187
170
  requirements:
188
171
  - - ! '>='
189
172
  - !ruby/object:Gem::Version
190
173
  version: '0'
191
174
  requirements: []
192
175
  rubyforge_project:
193
- rubygems_version: 1.8.23
176
+ rubygems_version: 2.0.6
194
177
  signing_key:
195
- specification_version: 3
178
+ specification_version: 4
196
179
  summary: Use as a rake task, define a stack of modules and app-stack will merge files
197
180
  from those stack-apps to the local application directory.
198
181
  test_files:
199
- - spec/config_spec.rb
200
- - spec/fixtures/sample_files/module_1/config/boot_sample.rb
201
- - spec/fixtures/sample_files/module_1/lib/mixins/b_lib.rb
202
- - spec/fixtures/sample_files/module_1/lib/mixins/s_lib.rb
203
- - spec/fixtures/sample_files/module_1/lib/samples/a_lib.rb
204
- - spec/fixtures/sample_files/module_1/spec/config_spec.rb
205
- - spec/fixtures/sample_files/module_2/app/lib/sequence.rb
206
- - spec/fixtures/sample_files/module_3/lib/libfile_1.rb
207
- - spec/fixtures/sample_files/module_3/lib/libfile_2.rb
208
- - spec/fixtures/sample_files/my_app/spec/config_spec.rb
209
- - spec/fixtures/sample_files/my_app_back/spec/config_spec.rb
210
- - spec/merger_spec.rb
182
+ - spec/app_stack_spec.rb
183
+ - spec/cli_options_spec.rb
184
+ - spec/compare_list_spec.rb
185
+ - spec/configuration_spec.rb
186
+ - spec/examples/la-assets-helper/lib/la_assets.rb
187
+ - spec/examples/la-mongoid/config/boot.rb
188
+ - spec/examples/la-mongoid/config/database.rb
189
+ - spec/examples/no-stacked/some_list.rb
190
+ - spec/load_stack_spec.rb
211
191
  - spec/spec_helper.rb
212
- - spec/stackup_spec.rb
data/.app_stack.yml DELETED
@@ -1,14 +0,0 @@
1
- stack:
2
- - la-sinatra: [default, { Gemfile: Gemfile, Procfile: Procfile.imp }]
3
- - la-mongoid: [default, mixins]
4
- - la-mancha-models-syobu-p1
5
- - la-assets-helper
6
- export: []
7
- exclude:
8
- - '*sample_files/**/*'
9
- attrs:
10
- application_code: ficus_syobu_p1
11
- application_name: Ficus Web Framework
12
- gems:
13
- default: {}
14
- development: {}
data/bin/config_assets DELETED
@@ -1,3 +0,0 @@
1
- # encoding: utf-8
2
-
3
- Tse
@@ -1,147 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'diffy'
4
- require 'tilt'
5
- require 'ostruct'
6
-
7
- module AppStack
8
- # import from outside apps
9
- module CopyListBuilder
10
- # get exported source file list from app, filtered by import_conf
11
- def import_files(import_conf)
12
- file_list = {}
13
- import_conf.each do |c|
14
- if c.is_a?(String) # group name
15
- echo "import from group #{c.bold.blue}"
16
- file_list.merge! export_files(c)
17
- elsif c.is_a?(Hash)
18
- echo "import form file: ", c
19
- file_list.merge! glob_files(c, true)
20
- else
21
- fail 'unknown import options: ' + c.inspect
22
- end
23
- end
24
- file_list
25
- end
26
-
27
- # render/copy file list
28
- def check_mtime
29
- @render_files, @copy_candidates = {}, {}
30
- @copy_list.each do |f, t|
31
- type, f = f.split ':', 2
32
-
33
- # exclude file in the exclude list
34
- excluded = false
35
- @config[:exclude].each do |patt|
36
- if File.fnmatch?(patt, t)
37
- echo "exclude #{short_path(t)} by patthern ", patt
38
- excluded = true
39
- break
40
- end
41
- end
42
- next if excluded
43
-
44
- # check modification time
45
- if type == 'c'
46
- if newer?(f, t)
47
- @copy_candidates[t] = f
48
- else
49
- echo "skip copy #{short_path(t).blue} (mtime or existence)."
50
- end
51
- elsif type == 'r'
52
- if newer?(f, t) or @attr_mtime > File.mtime(t)
53
- @render_files[t] = f
54
- else
55
- echo "skip render #{short_path(t).blue} (mtime or existence)."
56
- end
57
- else
58
- fail "unknown operation type #{type} for #{short_path(t)}"
59
- end
60
- end
61
- end
62
-
63
- def check_diff
64
- @copy_files, @diffs = {}, {}
65
- @copy_candidates.each do |t, f|
66
- if File.exists?(t)
67
- diff = Diffy::Diff.new(f, t, :source => 'files')
68
- if diff.to_s.chomp.size > 0
69
- @diffs[t] = diff
70
- @copy_files[t] = f
71
- else
72
- echo "Skip copy #{short_path(t).blue} (no diff)."
73
- end
74
- else
75
- @copy_files[t] = f
76
- end
77
- end
78
- end
79
-
80
- def merge!
81
- check_mtime
82
- check_diff
83
- echo 'final copy list: ', @copy_files
84
- echo 'final diff list: ', @diffs
85
- echo 'final render lists: ', @render_files
86
-
87
- if @diffs.keys.size > 0 and !@options.force
88
- ask_diffs # quit, copy and show diffs special files
89
- else
90
- do_copy!
91
- do_render!
92
- end
93
- end
94
-
95
- def ask_diffs
96
- puts "These files are changed remotely:"
97
- i = 1
98
- @diffs.each do |t, diff|
99
- puts "[#{i.to_s.bold}] " + short_path(t).blue
100
- puts "from: #{@copy_files[t].blue}"
101
- puts diff.to_s(:color)
102
- i += 1
103
- end
104
-
105
- puts "use -f (--force) option to overwrite all files,"
106
- puts "or 'touch' local file to disable warn for specific file."
107
- end
108
-
109
- def do_copy!
110
- @copy_files.each { |to, fr| copy_file!(fr, to) }
111
- end
112
-
113
- def do_render!
114
- @render_files.each { |to, fr| render_file!(fr, to) }
115
- end
116
-
117
- # if f1 newer than f2, or f2 not exits but f1 does.
118
- def newer?(f1, f2)
119
- return false unless File.exists?(f1)
120
- return true unless File.exists?(f2)
121
- File.mtime(f1) > File.mtime(f2)
122
- end
123
-
124
- def copy_file!(fr, to)
125
- target_dir = File.dirname(to)
126
- puts "copy #{fr.blue} \n to: " + to.green.bold
127
- return if @options.simulate
128
- FileUtils.mkdir_p target_dir unless File.directory?(target_dir)
129
- FileUtils.cp_r fr, to
130
- end
131
-
132
- def render_file!(fr, to)
133
- puts "reader #{fr.blue}\n to: " + to.green.bold
134
- return if @options.simulate
135
- oh = File.open(to, 'wb')
136
- if fr.match(/\.liquid$/)
137
- require 'liquid'
138
- oh.write Liquid::Template.parse(File.open(fr,
139
- 'r:utf-8').read).render(attrs)
140
- else
141
- tilt = Tilt.new(fr)
142
- oh.write tilt.render(OpenStruct.new(attrs))
143
- end
144
- oh.close
145
- end
146
- end
147
- end
@@ -1,95 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module AppStack
4
- # parse local files from a local app directory
5
- module LocalFilesParser
6
- def attrs
7
- @config[:attrs]
8
- end
9
-
10
- def directory
11
- File.expand_path('../', @file)
12
- end
13
-
14
- # use the direct name of the config file as app name
15
- def app_name
16
- File.basename(directory)
17
- end
18
-
19
- def full_path(file)
20
- File.expand_path(file, directory)
21
- end
22
-
23
- def short_path(path)
24
- lpath = path.sub(/^((c|r)\:)?#{directory}\/?/, '')
25
- lpath.sub(/^\//, '')
26
- end
27
-
28
- # get export files list (copy_from => copy_to hash) for a specific group
29
- def export_files(group = 'default')
30
- @export_files ||= parse_export_files
31
- group = 'default' if group.to_s == 'defaults' # back-compatibility
32
- @export_files[group.to_s]
33
- end
34
-
35
- # get all exported files in groups
36
- def parse_export_files
37
- # 'file_group_name' => { copy_from => copy_to_base_name }
38
- @export_files ||= {}
39
- @config[:export].each do |p_list| # pattern list
40
- if p_list.is_a?(Hash) # group, file list
41
- p_list.each do |n, p|
42
- @export_files[n] ||= {}
43
- @export_files[n].merge! find_files(p)
44
- end
45
- elsif p_list.is_a?(String)
46
- @export_files['default'] ||= {}
47
- @export_files['default'].merge! find_files([p_list])
48
- else
49
- fail 'invalid export option ' + p_list.inspect
50
- end
51
- end
52
- @export_files
53
- end
54
-
55
- def switch_to_tpl(file)
56
- f = full_path(file)
57
- tpl_file = nil
58
- @config[:tpl_ext].each { |ex| tpl_file = f + ex if File.exists?(f + ex) }
59
- tpl_file ? 'r:' + tpl_file : 'c:' + f
60
- end
61
-
62
- # from file pattern to copy_from => copy_to (remove directory header) hash
63
- def glob_files(dir, allow_hash = false)
64
- fhsh = {}
65
- if dir.is_a?(Hash)
66
- raise 'Can not use hash here for ' + dir.keys.join.to_s + ' in file ' +
67
- filename unless allow_hash
68
- dir.each do |f, t|
69
- t = '/' + t.gsub(/^\//, '')
70
- fhsh[switch_to_tpl(f)] = t
71
- echo "found: #{short_path(switch_to_tpl(f)).blue} to: ",
72
- short_path(t)
73
- end
74
- else
75
- Dir[File.expand_path(dir, directory)].each do |f|
76
- fhsh[switch_to_tpl(f)] = f.gsub(/^#{directory}/, '')
77
- echo "found: #{short_path(switch_to_tpl(f)).blue} to: ",
78
- short_path(short_path(f.gsub(/^#{directory}/, '')))
79
- end
80
- end
81
-
82
- fhsh
83
- end
84
-
85
- # from array (or string) of file patterns, glob files and build a
86
- # large array
87
- def find_files(plist)
88
- fhsh = {}
89
- plist.each do |file_pattern|
90
- fhsh.merge! glob_files(file_pattern)
91
- end
92
- fhsh
93
- end
94
- end
95
- end
@@ -1,119 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'yaml'
4
- require 'pp'
5
-
6
- module AppStack
7
- # content parse error
8
- class ParseError < RuntimeError; end
9
-
10
- # represent a single stacked application
11
- class StackApp
12
- attr_reader :file_mtime
13
-
14
- include LocalFilesParser
15
- include CopyListBuilder
16
-
17
- def initialize(filename, options)
18
- @filename, @options = filename, options
19
- @file = File.expand_path(filename)
20
- @file_mtime = File.mtime(@file)
21
-
22
- # default configuration, also restrict known keys and data type
23
- @config = {
24
- stack: [],
25
- export: [],
26
- exclude: [],
27
- attrs: {},
28
- stack_dir: '..',
29
- tpl_ext: %w[.erb .haml .liquid]
30
- }
31
-
32
- echo "load app #{app_name.bold} from file:", @file
33
- # use yaml file to set configuration
34
- YAML.load(File.open(@file, 'r:utf-8').read).each do |k, v|
35
- fail ParseError,
36
- "unkown option `#{k}` in #{@filename}" unless @config[k.to_sym]
37
- fail ParseError,
38
- "'#{k}' must be a #{@config[k.to_sym].class.to_s}" unless
39
- v.is_a?(@config[k.to_sym].class)
40
- echo "set #{k.blue} to: ", v
41
- @config[k.to_sym] = v
42
- end
43
- end
44
-
45
- # load definitions from all apps in the stack config
46
- def load_stack
47
- unless @stack
48
- @stack = { } # stack_app => import list
49
- @config[:stack].each do |app_conf|
50
- if app_conf.is_a?(String)
51
- app_name, groups = app_conf, ['default']
52
- elsif app_conf.is_a?(Hash)
53
- fail 'invalid app: ' + app_conf.inspect if app_conf.keys.size > 1
54
- app_conf.each { |an, ac| app_name, groups = an, ac }
55
- else
56
- fail 'invalid stack app: ' + app_conf.inspect
57
- end
58
-
59
- conf_file = @config[:stack_dir].sub(/\/?$/, '/') + app_name
60
- conf_file += '/' + File.basename(@file)
61
- app = StackApp.new(conf_file, @options)
62
- @stack[app] = groups
63
- end
64
- end
65
- @stack
66
- end
67
-
68
- # entry point: copy or simulate copy
69
- def stackup!
70
- @copy_list = {} # from_file_full_path => copy item
71
- new_attrs, @attr_mtime = {}, file_mtime
72
- load_stack.each do |app, import_conf|
73
- echo 'load files from ' + app.app_name.bold.blue
74
-
75
- # get file list from app
76
- app.import_files(import_conf).each do |f, t|
77
- @copy_list[f] = full_path(short_path(t))
78
- end
79
-
80
- # update global attrs
81
- new_attrs.deep_merge! app.attrs
82
- @attr_mtime = app.file_mtime if app.file_mtime > @attr_mtime
83
- end
84
-
85
- @config[:attrs] = new_attrs.deep_merge attrs
86
- echo 'the merged attributes', attrs
87
-
88
- # add local template files the copy list
89
- Dir[directory + "/**/*{#{@config[:tpl_ext].join(',')}}"].each do |f|
90
- of = f.gsub(/#{@config[:tpl_ext].join('|')}$/, '')
91
- if File.exists?(of)
92
- @copy_list['r:' + f] = of
93
- echo 'found local template file: ',
94
- short_path(f) + ' -> ' + short_path(of)
95
- else
96
- echo 'skip template file: ', f
97
- end
98
- end
99
-
100
- merge!
101
- end
102
-
103
- # echo message only if verbose specified to be true
104
- def echo(msg, var = nil)
105
- return unless @options.verbose
106
-
107
- msg = "[#{app_name || self.class.name}] ".green + msg
108
- msg += "\n" if var && var.inspect.size > 30
109
-
110
- print msg
111
- if var
112
- print Term::ANSIColor.bold
113
- var.inspect.size > 30 ? PP.pp(var) : PP.singleline_pp(var)
114
- print Term::ANSIColor.reset
115
- end
116
- puts unless var && var.inspect.size > 30
117
- end
118
- end
119
- end