app_stack 1.3.4 → 1.4.0
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.
- 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: ''
|