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.
- checksums.yaml +15 -0
- data/Gemfile +6 -5
- data/Gemfile.lock +17 -5
- data/README.md +13 -1
- data/app_stack.gemspec +6 -5
- data/lib/app_stack/app.rb +86 -0
- data/lib/app_stack/cli_options.rb +42 -36
- data/lib/app_stack/compare_list.rb +195 -0
- data/lib/app_stack/configuration.rb +119 -0
- data/lib/app_stack/operator.rb +60 -0
- data/lib/app_stack/version.rb +1 -1
- data/lib/app_stack.rb +34 -6
- data/spec/app_stack_spec.rb +17 -0
- data/spec/cli_options_spec.rb +20 -0
- data/spec/compare_list_spec.rb +18 -0
- data/spec/configuration_spec.rb +95 -0
- data/spec/examples/la-assets-helper/app_stack.yml +14 -0
- data/spec/examples/la-assets-helper/lib/la_assets.rb +319 -0
- data/spec/examples/la-import_app/Trivia.erb +2 -0
- data/spec/examples/la-import_app/app_stack.yml +83 -0
- data/spec/examples/la-mongoid/app_stack.yml +49 -0
- data/spec/examples/la-mongoid/config/boot.rb +15 -0
- data/spec/examples/la-mongoid/config/database.rb +12 -0
- data/spec/examples/la-mongoid/config/mongoid.yml +22 -0
- data/spec/examples/la-mongoid/config/mongoid.yml.erb +22 -0
- data/spec/examples/la-sinatra/Gemfile.erb +11 -0
- data/spec/examples/la-sinatra/app_stack.yml +16 -0
- data/spec/examples/no-stacked/some_list.rb +4 -0
- data/spec/examples/sample_config/app_stack.yml +82 -0
- data/spec/examples/sample_config/hash_export.yml +4 -0
- data/spec/load_stack_spec.rb +13 -0
- data/spec/spec_helper.rb +7 -2
- data/tags +87 -34
- metadata +66 -87
- data/.app_stack.yml +0 -14
- data/bin/config_assets +0 -3
- data/lib/app_stack/copy_list_builder.rb +0 -147
- data/lib/app_stack/local_files_parser.rb +0 -95
- data/lib/app_stack/stack_app.rb +0 -119
- data/spec/config_spec.rb +0 -82
- data/spec/fixtures/config_sample/sample.yml +0 -19
- data/spec/fixtures/sample_files/module_1/Gemfile.erb +0 -1
- data/spec/fixtures/sample_files/module_1/app_stack.yml +0 -10
- data/spec/fixtures/sample_files/module_1/config/boot_sample.rb +0 -0
- data/spec/fixtures/sample_files/module_1/doc/excluding.txt +0 -1
- data/spec/fixtures/sample_files/module_1/doc/including.txt +0 -0
- data/spec/fixtures/sample_files/module_1/lib/mixins/b_lib.rb +0 -0
- data/spec/fixtures/sample_files/module_1/lib/mixins/s_lib.rb +0 -0
- data/spec/fixtures/sample_files/module_1/lib/samples/a_lib.rb +0 -0
- data/spec/fixtures/sample_files/module_1/spec/config_spec.rb +0 -0
- data/spec/fixtures/sample_files/module_2/Gemfile +0 -0
- data/spec/fixtures/sample_files/module_2/Gemfile.liquid +0 -1
- data/spec/fixtures/sample_files/module_2/app/lib/sequence.rb +0 -0
- data/spec/fixtures/sample_files/module_2/app_stack.yml +0 -3
- data/spec/fixtures/sample_files/module_3/app_stack.yml +0 -3
- data/spec/fixtures/sample_files/module_3/bin/del +0 -0
- data/spec/fixtures/sample_files/module_3/bin/rm +0 -0
- data/spec/fixtures/sample_files/module_3/config/application.yml +0 -0
- data/spec/fixtures/sample_files/module_3/config/database_development.yml +0 -0
- data/spec/fixtures/sample_files/module_3/config/database_production.yml +0 -0
- data/spec/fixtures/sample_files/module_3/lib/libfile_1.rb +0 -0
- data/spec/fixtures/sample_files/module_3/lib/libfile_2.rb +0 -0
- data/spec/fixtures/sample_files/my_app/app_stack.yml +0 -15
- data/spec/fixtures/sample_files/my_app/doc/excluding.txt +0 -1
- data/spec/fixtures/sample_files/my_app/local.conf +0 -0
- data/spec/fixtures/sample_files/my_app/local.conf.erb +0 -1
- data/spec/fixtures/sample_files/my_app/spec/config_spec.rb +0 -0
- data/spec/fixtures/sample_files/my_app_back/app_stack.yml +0 -15
- data/spec/fixtures/sample_files/my_app_back/doc/excluding.txt +0 -1
- data/spec/fixtures/sample_files/my_app_back/local.conf +0 -0
- data/spec/fixtures/sample_files/my_app_back/local.conf.erb +0 -1
- data/spec/fixtures/sample_files/my_app_back/spec/config_spec.rb +0 -0
- data/spec/merger_spec.rb +0 -43
- data/spec/stackup_spec.rb +0 -18
- /data/{file.erb → spec/examples/find_conf_file/both/.app_stack.yml} +0 -0
- /data/spec/{fixtures/sample_files/module_1/Gemfile → examples/find_conf_file/both/app_stack.yml} +0 -0
- /data/spec/{fixtures/sample_files/module_1/Rakefile → examples/find_conf_file/with_dot/.app_stack.yml} +0 -0
- /data/spec/{fixtures/config_sample → examples/sample_config}/wrong_key.yml +0 -0
- /data/spec/{fixtures/config_sample → examples/sample_config}/wrong_type.yml +0 -0
data/lib/app_stack/version.rb
CHANGED
data/lib/app_stack.rb
CHANGED
@@ -4,23 +4,51 @@ require 'term/ansicolor'
|
|
4
4
|
# mixin String class for term-color methods
|
5
5
|
class String; include Term::ANSIColor end
|
6
6
|
|
7
|
+
require 'yaml'
|
8
|
+
require 'pp'
|
7
9
|
require 'active_support/core_ext/hash/deep_merge'
|
10
|
+
require 'tempfile'
|
11
|
+
require 'diffy'
|
12
|
+
require 'tilt'
|
13
|
+
require 'ostruct'
|
8
14
|
|
9
15
|
require 'app_stack/version'
|
10
16
|
require 'app_stack/cli_options'
|
11
|
-
require 'app_stack/
|
12
|
-
require 'app_stack/
|
13
|
-
require 'app_stack/
|
17
|
+
require 'app_stack/configuration'
|
18
|
+
require 'app_stack/app'
|
19
|
+
require 'app_stack/compare_list'
|
20
|
+
require 'app_stack/operator'
|
14
21
|
|
15
22
|
# module functions for handle stackup
|
16
23
|
module AppStack
|
17
|
-
|
24
|
+
attr_reader :options
|
25
|
+
|
26
|
+
DEFAULT_CONF_FILE = %w[app_stack.yml .app_stack.yml]
|
18
27
|
|
19
28
|
# handle the execution to main class:
|
20
29
|
def stackup!(argv = ARGV)
|
21
30
|
@options = CliOptions.new(argv)
|
22
|
-
|
31
|
+
conf_file = options.conf_file || find_conf_file('.')
|
32
|
+
App.new(conf_file).stackup!
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# find configuration file (stackup.yml ...) in order
|
38
|
+
# prefer the base name of conf-file used for stackup
|
39
|
+
def find_conf_file(directory)
|
40
|
+
conf_files = DEFAULT_CONF_FILE
|
41
|
+
if options && options.conf_file
|
42
|
+
base_name = File.basename(options.conf_file)
|
43
|
+
conf_files.delete(base_name)
|
44
|
+
conf_files.unshift(base_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
conf_files.each do |f|
|
48
|
+
return File.join(directory, f) if File.exists?(File.join(directory, f))
|
49
|
+
end
|
50
|
+
nil
|
23
51
|
end
|
24
52
|
|
25
|
-
module_function :stackup
|
53
|
+
module_function :stackup!, :options, :find_conf_file
|
26
54
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AppStack do
|
6
|
+
describe '.find_conf_file' do
|
7
|
+
it 'find .app_stack.yml' do
|
8
|
+
AppStack.find_conf_file(examples('find_conf_file/with_dot'))
|
9
|
+
.should eq(examples('find_conf_file/with_dot/.app_stack.yml'))
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'prefer app_stack.yml' do
|
13
|
+
AppStack.find_conf_file(examples('find_conf_file/both'))
|
14
|
+
.should eq(examples('find_conf_file/both/app_stack.yml'))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AppStack::CliOptions do
|
6
|
+
it 'parse argv with config file given' do
|
7
|
+
opt = AppStack::CliOptions.new(%w[-f opt_file.yml])
|
8
|
+
opt.force.should be_true
|
9
|
+
opt.conf_file.should eq('opt_file.yml')
|
10
|
+
opt.verbose.should be_false
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'parse argv without config file given' do
|
14
|
+
opt = AppStack::CliOptions.new(%w[-s --verbose])
|
15
|
+
opt.force.should be_false
|
16
|
+
opt.simulate.should be_true
|
17
|
+
opt.verbose.should be_true
|
18
|
+
opt.conf_file.should be_nil
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AppStack::App do
|
6
|
+
describe '#load_compare_list!' do
|
7
|
+
subject(:list) do
|
8
|
+
app = AppStack::App.new(examples('la-import_app/app_stack.yml'))
|
9
|
+
app.load_stack!
|
10
|
+
app.load_compare_list!
|
11
|
+
app.compare_list.map(&:label)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has proper sync list' do
|
15
|
+
subject.each { |f| puts f }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AppStack do
|
6
|
+
describe '#load_config' do
|
7
|
+
subject { AppStack::App.new(examples('sample_config/app_stack.yml')) }
|
8
|
+
it 'parses any yaml file' do
|
9
|
+
subject.load_config
|
10
|
+
subject.config.should be_instance_of(AppStack::Configuration)
|
11
|
+
subject.config.export.should be_instance_of(Array)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe AppStack::Configuration do
|
17
|
+
describe '#initialize' do
|
18
|
+
it 'raise error for non-exists keys' do
|
19
|
+
expect do
|
20
|
+
AppStack::Configuration.new(examples('sample_config/wrong_key.yml'))
|
21
|
+
end.to raise_error(AppStack::ParseError)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'raise error for keys with wrong data type' do
|
25
|
+
expect do
|
26
|
+
AppStack::Configuration.new(examples('sample_config/wrong_type.yml'))
|
27
|
+
end.to raise_error(AppStack::ParseError)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'return default config for directory without config file' do
|
31
|
+
conf = AppStack::Configuration.new
|
32
|
+
conf.export.should be_instance_of(Array)
|
33
|
+
conf.export.size.should be(0)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#parse_export_files' do
|
38
|
+
subject(:app) do
|
39
|
+
app = AppStack::App.new(examples('sample_config/app_stack.yml'))
|
40
|
+
app.validate_config!
|
41
|
+
app
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raise error for wrong export definition' do
|
45
|
+
expect do
|
46
|
+
AppStack::App.new(examples('sample_config/hash_export.yml'))
|
47
|
+
.validate_config!
|
48
|
+
end.to raise_error(AppStack::ParseError)
|
49
|
+
end
|
50
|
+
|
51
|
+
its(:export_groups) { should be_instance_of(Hash) }
|
52
|
+
|
53
|
+
it 'catch default export group files' do
|
54
|
+
app.export_groups['default']
|
55
|
+
.should include('app/lib/bases/web_application.rb')
|
56
|
+
app.export_groups['default']
|
57
|
+
.should include('features/step_definitions/web_steps.rb')
|
58
|
+
app.export_groups['default']
|
59
|
+
.should include('public/assets/definition.yml')
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'catch explicit named export group files' do
|
64
|
+
app.export_groups['gemfile']
|
65
|
+
.should include('Gemfile')
|
66
|
+
app.export_groups['cucumber'].should include('lib/task/cucumber.rake')
|
67
|
+
app.export_groups['cucumber'] .should include('features/support/*')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#sync_list' do
|
72
|
+
subject(:app) do
|
73
|
+
app = AppStack::App.new(examples('sample_config/app_stack.yml'))
|
74
|
+
app.validate_config!
|
75
|
+
app.sync_list
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'include default group for string setting' do
|
79
|
+
subject['la-mongoid'].should include('default')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'include groups for array settings' do
|
83
|
+
subject['la-assets-helper'].should include('default')
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'include single file hash settings' do
|
87
|
+
subject['la-assets-helper'][1]['Rakefile'].should eq('Rakefile')
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'include multi group settings' do
|
91
|
+
subject['la-sinatra'].size.should eq(2)
|
92
|
+
subject['la-sinatra'].should include('tests')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
export:
|
2
|
+
- lib/la_assets.rb
|
3
|
+
- app/lib/helpers/assets_helper.rb
|
4
|
+
- lib/tasks/assets.rake
|
5
|
+
- example:
|
6
|
+
- public/assets/definition.yml
|
7
|
+
attrs:
|
8
|
+
gems:
|
9
|
+
default:
|
10
|
+
sass: ''
|
11
|
+
closure-compiler: ''
|
12
|
+
term-ansicolor: ''
|
13
|
+
development: {}
|
14
|
+
services: {}
|
@@ -0,0 +1,319 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Compile and minimizing assets (Javascript/CSS) files
|
4
|
+
|
5
|
+
require 'pp'
|
6
|
+
require 'term/ansicolor'
|
7
|
+
# mixin String class for term-color methods
|
8
|
+
class String; include Term::ANSIColor end
|
9
|
+
|
10
|
+
require 'yaml'
|
11
|
+
require 'fileutils'
|
12
|
+
|
13
|
+
require 'sass'
|
14
|
+
require 'closure-compiler'
|
15
|
+
|
16
|
+
# configure / compile java script and css assets files
|
17
|
+
# rubocop:disable MethodLength, ClassLength
|
18
|
+
class LaAssets
|
19
|
+
|
20
|
+
# initialize compiler and setup options
|
21
|
+
def initialize(def_file, verbose = false, cleanup = false)
|
22
|
+
# default configuration (directory relative to current directory):
|
23
|
+
@settings = {
|
24
|
+
'public_dir' => 'public',
|
25
|
+
'assets_dir' => 'public/assets',
|
26
|
+
'js_output_dir' => 'public/javastripts',
|
27
|
+
'css_output_dir' => 'public/stylesheets',
|
28
|
+
'output_file' => 'config/assets.yml',
|
29
|
+
'js_url_prefix' => '/javastripts/',
|
30
|
+
'css_url_prefix' => '/stylesheets/',
|
31
|
+
'development_prefix' => '/'
|
32
|
+
}
|
33
|
+
|
34
|
+
@verbose = verbose # control echo on/off
|
35
|
+
@cleanup = cleanup && cleanup.to_i
|
36
|
+
@assets_definition = {} # load assets configuration
|
37
|
+
|
38
|
+
# find the asset definition file:
|
39
|
+
@definition_file = def_file || 'public/assets/definition.yml'
|
40
|
+
echo 'use definition file: ', @definition_file
|
41
|
+
|
42
|
+
parse_definitions
|
43
|
+
set_setting_methods
|
44
|
+
load_current_config
|
45
|
+
end
|
46
|
+
|
47
|
+
# clean previous config and update to new setting
|
48
|
+
def update_config!
|
49
|
+
@assets_config, @asset_file_list = nil, nil
|
50
|
+
dir = File.dirname(output_file)
|
51
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
52
|
+
echo 'write development mapping as: ', development_mapping
|
53
|
+
echo 'write production mapping as: ', production_mapping
|
54
|
+
File.open(output_file, 'wb') do |fh|
|
55
|
+
fh.write YAML.dump(
|
56
|
+
'production' => production_mapping,
|
57
|
+
'development' => development_mapping
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def compile!
|
63
|
+
@version = Time.now.gmtime.strftime('v%y%m%d%H%M')
|
64
|
+
echo 'get current timestamp (utc) version number: ', @version
|
65
|
+
|
66
|
+
# compile each asset definition based on asset config
|
67
|
+
assets_config.each do |target, file_list|
|
68
|
+
map_ary, compile_list = [], []
|
69
|
+
|
70
|
+
# get the file name with version number
|
71
|
+
new_file = production_path(target)
|
72
|
+
|
73
|
+
# delete separate hosted assets from file list
|
74
|
+
file_list.each { |f| url?(f) ? map_ary << f : compile_list << f }
|
75
|
+
|
76
|
+
echo 'build compile list:', compile_list
|
77
|
+
|
78
|
+
map_ary << compile_file!(new_file, compile_list) if compile_list.size > 0
|
79
|
+
@production_mapping ||= {}
|
80
|
+
@production_mapping[target] = map_ary
|
81
|
+
end
|
82
|
+
|
83
|
+
update_config!
|
84
|
+
cleanup!
|
85
|
+
end
|
86
|
+
|
87
|
+
def cleanup!
|
88
|
+
return unless @cleanup
|
89
|
+
|
90
|
+
echo "cleanup asset files older than #{@cleanup} minutes"
|
91
|
+
Dir[js_output_dir + '/*.js'].each do |f|
|
92
|
+
next if used_filelist.include?(File.basename(f))
|
93
|
+
if file_old?(f)
|
94
|
+
echo 'delete old file: ', f
|
95
|
+
FileUtils.rm f
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
Dir[css_output_dir + '/*.css'].each do |f|
|
100
|
+
next if used_filelist.include?(File.basename(f))
|
101
|
+
if file_old?(f)
|
102
|
+
echo 'delete old file: ', f
|
103
|
+
FileUtils.rm f
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def used_filelist
|
109
|
+
used_filelist = []
|
110
|
+
production_mapping.each do |t, flist|
|
111
|
+
flist = [flist] unless flist.is_a?(Array)
|
112
|
+
flist.each { |f| used_filelist << File.basename(f) unless url?(f) }
|
113
|
+
end
|
114
|
+
used_filelist
|
115
|
+
end
|
116
|
+
|
117
|
+
def file_old?(file)
|
118
|
+
filestamp = file.match(/v(\d{10})/)[1]
|
119
|
+
timeline = Time.now - 60 * @cleanup
|
120
|
+
|
121
|
+
echo "compare #{filestamp} to #{timeline.gmtime.strftime('%y%m%d%H%M')}",
|
122
|
+
file
|
123
|
+
|
124
|
+
filestamp && timeline.gmtime.strftime('%y%m%d%H%M').to_i > filestamp.to_i
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def compile_file!(new_file, file_list)
|
130
|
+
echo "compile #{new_file} from: ", file_list
|
131
|
+
FileUtils.mkdir_p File.dirname(new_file)
|
132
|
+
wh = File.open(new_file, 'wb')
|
133
|
+
if get_type(new_file) == :css
|
134
|
+
wh.write Sass::Engine.new(file_list.map { |f| File.read(f) }.join,
|
135
|
+
syntax: :scss, style: :compressed).render
|
136
|
+
else
|
137
|
+
echo 'perform closure compiler on file list: ', file_list
|
138
|
+
wh.write Closure::Compiler.new.compile_files(file_list)
|
139
|
+
end
|
140
|
+
wh.close
|
141
|
+
|
142
|
+
use_file = check_version(new_file)
|
143
|
+
if use_file == new_file
|
144
|
+
echo 'file updated ', use_file
|
145
|
+
else
|
146
|
+
echo 'file actually used for production: ', use_file
|
147
|
+
FileUtils.rm new_file
|
148
|
+
end
|
149
|
+
|
150
|
+
production_file_url(use_file)
|
151
|
+
end
|
152
|
+
|
153
|
+
# map file to url (in development environment) for a single file
|
154
|
+
def development_file_url(file)
|
155
|
+
return file if url?(file)
|
156
|
+
@settings['development_prefix'] + file.gsub(/^#{public_dir}\/?/, '')
|
157
|
+
end
|
158
|
+
|
159
|
+
def production_file_url(file)
|
160
|
+
return file if url?(file)
|
161
|
+
key = get_type(file) == :css ? 'css_url_prefix' : 'js_url_prefix'
|
162
|
+
@settings[key] + File.basename(file)
|
163
|
+
end
|
164
|
+
|
165
|
+
# the resulted output mappings for development
|
166
|
+
def development_mapping
|
167
|
+
unless @development_mapping
|
168
|
+
@development_mapping = {}
|
169
|
+
assets_config.each do |target, files|
|
170
|
+
@development_mapping[target] = files.map { |f| development_file_url f }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
@development_mapping
|
174
|
+
end
|
175
|
+
|
176
|
+
# the resulted output mappings for production
|
177
|
+
def production_mapping
|
178
|
+
@production_mapping || @current_config['production']
|
179
|
+
end
|
180
|
+
|
181
|
+
def parse_definitions
|
182
|
+
YAML.load(File.read(@definition_file)).each do |target, file_list|
|
183
|
+
if target == 'settings'
|
184
|
+
update_settings(file_list)
|
185
|
+
else
|
186
|
+
fail "wrong file type #{target}" unless target.match(/\.(js|css)$/)
|
187
|
+
fail "wrong file list for #{target}" unless file_list.is_a?(Array)
|
188
|
+
@assets_definition[target] = file_list
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
echo 'updated settings: ', @settings
|
193
|
+
echo 'loaded definitions: ', @assets_definition
|
194
|
+
self
|
195
|
+
end
|
196
|
+
|
197
|
+
# define directory full paths as accessors methods
|
198
|
+
def set_setting_methods
|
199
|
+
@settings.each do |k, v|
|
200
|
+
next unless k.match(/_(dir|file)$/)
|
201
|
+
echo 'defined method: ', k.to_s
|
202
|
+
self.class.class_eval do
|
203
|
+
var = v.size > 0 ? File.expand_path(v) : nil
|
204
|
+
define_method(k.to_sym) { var }
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def load_current_config
|
210
|
+
if File.exists?(output_file)
|
211
|
+
@current_config = YAML.load(File.read(output_file))
|
212
|
+
echo 'loaded current config as: ', @current_config
|
213
|
+
else
|
214
|
+
@current_config = { production: {}, development: {} }
|
215
|
+
echo 'not existing assets config file found'
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# file lists for all definitions
|
220
|
+
def assets_config
|
221
|
+
unless @assets_config
|
222
|
+
@assets_config = {}
|
223
|
+
@assets_definition.each do |target, file_list|
|
224
|
+
type = get_type(target)
|
225
|
+
@assets_config[target] = file_list.map do |file|
|
226
|
+
url?(file) ? file : find_assets(file, type)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
echo 'find assets config from file definition: ', @assets_config
|
231
|
+
end
|
232
|
+
@assets_config
|
233
|
+
end
|
234
|
+
|
235
|
+
# # get all assets (with .css or .js extension) file under assets directory
|
236
|
+
def asset_file_list
|
237
|
+
unless @asset_file_list
|
238
|
+
@asset_file_list = Dir[assets_dir + '/**/*.{css,js}'].to_a
|
239
|
+
echo 'refreshed assets file list as: ', @asset_file_list
|
240
|
+
end
|
241
|
+
@asset_file_list
|
242
|
+
end
|
243
|
+
|
244
|
+
# map asset identifier to real file path,
|
245
|
+
# type should be :js or :css
|
246
|
+
def find_assets(ident, type)
|
247
|
+
filefound, file_to_use = [], nil
|
248
|
+
ident.gsub!(/\.#{type.to_s}$/, '')
|
249
|
+
asset_file_list.each do |file|
|
250
|
+
next unless file.match(/#{ident}/)
|
251
|
+
next unless get_type(file) == type.to_sym
|
252
|
+
filefound << file.gsub(assets_dir, '')
|
253
|
+
file_to_use = file if !file_to_use || file.size < file_to_use.size
|
254
|
+
end
|
255
|
+
|
256
|
+
if filefound.size > 1
|
257
|
+
echo "found more than one files for #{ident.blue} (#{type.to_s}):",
|
258
|
+
filefound, true
|
259
|
+
echo 'use: ', file_to_use.gsub(assets_dir, ''), true
|
260
|
+
end
|
261
|
+
fail "file for #{ident} (#{type.to_s}) not found" unless file_to_use
|
262
|
+
file_to_use
|
263
|
+
end
|
264
|
+
|
265
|
+
# update settings from yaml config file, check setting value data type
|
266
|
+
def update_settings(sets)
|
267
|
+
sets.each do |k, v|
|
268
|
+
fail "unknown setting '#{k}'" unless @settings.keys.include?(k)
|
269
|
+
fail "setting '#{k}' must be a #{@settings[k].class.to_s}" unless
|
270
|
+
v.is_a?(@settings[k].class)
|
271
|
+
@settings[k] = v
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# check file with older versions, determine which file to use
|
276
|
+
def check_version(file)
|
277
|
+
filepattern = file.gsub(/\.v\d+\.(css|js)$/, "*.#{get_type(file).to_s}")
|
278
|
+
Dir[filepattern].each do |f|
|
279
|
+
next if f == file # skip the same file
|
280
|
+
return f if File.read(f) == File.read(file)
|
281
|
+
end
|
282
|
+
file
|
283
|
+
end
|
284
|
+
|
285
|
+
def url?(file)
|
286
|
+
file.match(%r!^(http:|https:)?//!)
|
287
|
+
end
|
288
|
+
|
289
|
+
# production file path for target file
|
290
|
+
def production_path(target)
|
291
|
+
type = get_type(target)
|
292
|
+
dir = type == :css ? css_output_dir : js_output_dir
|
293
|
+
dir + '/' + target.gsub(/\.(js|css)$/, ".#{@version}.#{type}")
|
294
|
+
end
|
295
|
+
|
296
|
+
def get_type(file)
|
297
|
+
case
|
298
|
+
when file.match(/.+\.css$/) then :css
|
299
|
+
when file.match(/.+\.js$/) then :js
|
300
|
+
else
|
301
|
+
fail 'unsupported file type for ' + file
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# echo message only if verbose specified to be true
|
306
|
+
def echo(msg, var = nil, force = false)
|
307
|
+
return unless @verbose || force
|
308
|
+
msg += "\n" if var && var.inspect.size > 30
|
309
|
+
|
310
|
+
print "[#{caller[0][/`.*'/][1..-2]}] ".green + msg
|
311
|
+
|
312
|
+
if var
|
313
|
+
print Term::ANSIColor.bold
|
314
|
+
var.inspect.size > 30 ? PP.pp(var) : PP.singleline_pp(var)
|
315
|
+
print Term::ANSIColor.reset
|
316
|
+
end
|
317
|
+
puts unless var && var.inspect.size > 30
|
318
|
+
end
|
319
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import:
|
2
|
+
- la-mongoid
|
3
|
+
- la-sinatra:
|
4
|
+
- tests
|
5
|
+
sync:
|
6
|
+
- la-assets-helper:
|
7
|
+
- default
|
8
|
+
- Rakefile: Rakefile
|
9
|
+
- la-sinatra:
|
10
|
+
- settings
|
11
|
+
- tests
|
12
|
+
- no-stacked:
|
13
|
+
- {some_list.rb: ''}
|
14
|
+
render:
|
15
|
+
- la-sinatra: { Gemfile.erb: Gemfile, Procfile.erb: Procfile }
|
16
|
+
- la-mongoid: { config/mongoid.yml.erb: '' }
|
17
|
+
render_local: { Trivia.erb: Trivia }
|
18
|
+
export:
|
19
|
+
- app/lib/bases/web_application.rb
|
20
|
+
- lib/la_assets.rb
|
21
|
+
- lib/tasks/assets.rake
|
22
|
+
- app/lib/helpers/assets_helper.rb
|
23
|
+
- app/lib/helpers/slim_helper.rb
|
24
|
+
- app/lib/helpers/flash_i18n_errors_helper.rb
|
25
|
+
- app/lib/helpers/form_helper.rb
|
26
|
+
- features/support/*
|
27
|
+
- features/step_definitions/web_steps.rb
|
28
|
+
- lib/tasks/cucumber.rake
|
29
|
+
- lib/tasks/generator.rake
|
30
|
+
- public/assets/definition.yml
|
31
|
+
- gemfile:
|
32
|
+
- Gemfile
|
33
|
+
- rakefile:
|
34
|
+
- Rakefile
|
35
|
+
- foreman:
|
36
|
+
- Procfile
|
37
|
+
- cucumber:
|
38
|
+
- features/support/*
|
39
|
+
- features/step_definitions/web_steps.rb
|
40
|
+
- lib/task/cucumber.rake
|
41
|
+
- setup:
|
42
|
+
- .gitignore
|
43
|
+
- config.ru
|
44
|
+
- config/boot.rb
|
45
|
+
- config/exceptions.rb
|
46
|
+
- config/environment.rb
|
47
|
+
- config/application.rb
|
48
|
+
- config/route.rb
|
49
|
+
- app/lib/sinatra/mount.rb
|
50
|
+
- auth:
|
51
|
+
- app/lib/helpers/auth_helper.rb
|
52
|
+
attrs:
|
53
|
+
application_code: la_import_app
|
54
|
+
application_name: La Import Application
|
55
|
+
gems:
|
56
|
+
default:
|
57
|
+
activesupport: ''
|
58
|
+
rack-session-mongo: ''
|
59
|
+
sinatra: ''
|
60
|
+
sinatra-contrib: ''
|
61
|
+
sinatra-r18n: ''
|
62
|
+
sinatra-flash: ''
|
63
|
+
slim: ''
|
64
|
+
puma: ''
|
65
|
+
gibberish: ''
|
66
|
+
bcrypt-ruby: ''
|
67
|
+
will_paginate_mongoid: ''
|
68
|
+
development:
|
69
|
+
rspec: ''
|
70
|
+
cucumber: ''
|
71
|
+
capybara: ''
|
72
|
+
poltergeist: ''
|
73
|
+
html2slim: ''
|
74
|
+
foreman: ''
|
75
|
+
simplecov: ''
|
76
|
+
rake: ''
|
77
|
+
rubocop: ''
|
78
|
+
sass: ''
|
79
|
+
closure-compiler: ''
|
80
|
+
term-ansicolor: ''
|
81
|
+
rspec_api_documentation: ''
|
82
|
+
services:
|
83
|
+
puma: 'bundle exec puma -p 8080 --pidfile /tmp/puma.pid'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
---
|
2
|
+
export:
|
3
|
+
- config/database.rb
|
4
|
+
- config/mongoid.yml
|
5
|
+
- lib/mongoid/**/*
|
6
|
+
- setup:
|
7
|
+
- config/database.rb
|
8
|
+
- config/mongoid.yml
|
9
|
+
- created_at:
|
10
|
+
- lib/mongoid/created_at.rb
|
11
|
+
- presenter:
|
12
|
+
- lib/mongoid/presenter.rb
|
13
|
+
- tags:
|
14
|
+
- lib/mongoid/tags.rb
|
15
|
+
- sequence:
|
16
|
+
- lib/mongoid/sequence.rb
|
17
|
+
- index_task:
|
18
|
+
- lib/tasks/mongoid_index.rake
|
19
|
+
- spec_helper:
|
20
|
+
- spec/spec_helper.rb
|
21
|
+
- rakefile:
|
22
|
+
- Rakefile
|
23
|
+
- gemfile:
|
24
|
+
- Gemfile
|
25
|
+
- tests:
|
26
|
+
- spec/sequence_spec.rb
|
27
|
+
- spec/support/mocks/post.rb
|
28
|
+
- spec/support/mocks/u_present.rb
|
29
|
+
- spec/support/mixins/monoid_indexes.rb
|
30
|
+
- spec/factories/post_factory.rb
|
31
|
+
- spec/mongoid_mixin_spec.rb
|
32
|
+
- spec/mongoid_tags_spec.rb
|
33
|
+
attrs:
|
34
|
+
mongodb_host: localhost:27017
|
35
|
+
application_name: La Mongoid (Stacked App)
|
36
|
+
application_code: la_mongoid
|
37
|
+
gems:
|
38
|
+
default:
|
39
|
+
mongoid: '>= 3.1.4'
|
40
|
+
activesupport: ''
|
41
|
+
yajl-ruby: ''
|
42
|
+
multi_json: ''
|
43
|
+
development:
|
44
|
+
rake: ''
|
45
|
+
rubocop: ''
|
46
|
+
rspec: ''
|
47
|
+
simplecov: ''
|
48
|
+
forgery: ''
|
49
|
+
factory_girl: ''
|