app_stack 1.2.1 → 1.3.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.
Files changed (61) hide show
  1. checksums.yaml +15 -0
  2. data/.app_stack.yml +14 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +2 -0
  5. data/README.md +14 -0
  6. data/app_stack.gemspec +1 -0
  7. data/bin/config_assets +3 -0
  8. data/bin/stackup +8 -0
  9. data/file.erb +0 -0
  10. data/lib/app_stack/cli_options.rb +52 -0
  11. data/lib/app_stack/copy_list_builder.rb +144 -0
  12. data/lib/app_stack/local_files_parser.rb +95 -0
  13. data/lib/app_stack/stack_app.rb +114 -0
  14. data/lib/app_stack/version.rb +1 -1
  15. data/lib/app_stack.rb +13 -22
  16. data/tags +45 -0
  17. metadata +16 -62
  18. data/doc/coverage/.last_run.json +0 -1
  19. data/doc/coverage/.resultset.json +0 -1
  20. data/doc/coverage/assets/0.7.1/application.css +0 -1110
  21. data/doc/coverage/assets/0.7.1/application.js +0 -626
  22. data/doc/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  23. data/doc/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  24. data/doc/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  25. data/doc/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  26. data/doc/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  27. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  28. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  29. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  30. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  31. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  32. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  33. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  34. data/doc/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  35. data/doc/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  36. data/doc/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  37. data/doc/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  38. data/doc/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  39. data/doc/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  40. data/doc/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  41. data/doc/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  42. data/doc/coverage/assets/0.7.1/favicon_green.png +0 -0
  43. data/doc/coverage/assets/0.7.1/favicon_red.png +0 -0
  44. data/doc/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  45. data/doc/coverage/assets/0.7.1/loading.gif +0 -0
  46. data/doc/coverage/assets/0.7.1/magnify.png +0 -0
  47. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  48. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  49. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  50. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  51. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  52. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  53. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  54. data/doc/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  55. data/doc/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  56. data/doc/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  57. data/doc/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  58. data/doc/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  59. data/doc/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  60. data/doc/coverage/index.html +0 -2480
  61. data/lib/app_stack/config.rb +0 -132
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZTJmNjU5OThhNjgwMjg5MzJjZGVmNjQ2MGU2ZTkzMDNkZGY0NGM5NQ==
5
+ data.tar.gz: !binary |-
6
+ ZTA1ODI2N2RlM2U3MTNiZmFkM2NjMmI5ZTdhNWU5NzRiNTE1NDhlMw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YzAzMmQ5YzEwNWIzZTI3MDk1MmE1MzMzOWZhOGQ5YWFkMWNkZTJhY2E5OGJl
10
+ ZjgwOTNiZGRhYjY2MWM3MDdmMGRjOWNmYTVhYjg5ZDE4NGIzMmI0NTNmMTA1
11
+ ZTUwMWFhZDNkMTg5MzAyYjdmYmMzOTI4ZGUyM2QxYWIyMDk1NTI=
12
+ data.tar.gz: !binary |-
13
+ MjVjNDgwNmE1OWQ2YTlhODZhZDgxNDYzZGM4ZGY3YzQ4MjdjMDE5NmNkNTdh
14
+ NWY2ZWNiYzViYmRmNDkzNTA4MGM2NmU1ZDM2N2RlMDk4OTM5ZWY2MTFkZTI4
15
+ OWNmNWJjNjk3NDYwYjYxYWUxZGNlNzk0ZDdjZjc0NmRmZTEwN2E=
data/.app_stack.yml ADDED
@@ -0,0 +1,14 @@
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/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source 'http://ruby.taobao.org'
2
2
 
3
+ gem 'diffy'
3
4
  gem 'tilt', '>= 1.4.1'
4
5
  gem 'term-ansicolor', '>= 1.2.2'
5
6
  gem 'activesupport', '>= 3.2.14'
data/Gemfile.lock CHANGED
@@ -9,6 +9,7 @@ GEM
9
9
  tzinfo (~> 0.3.37)
10
10
  atomic (1.1.13)
11
11
  diff-lcs (1.2.4)
12
+ diffy (3.0.1)
12
13
  i18n (0.6.5)
13
14
  minitest (4.7.5)
14
15
  multi_json (1.8.0)
@@ -37,6 +38,7 @@ PLATFORMS
37
38
 
38
39
  DEPENDENCIES
39
40
  activesupport (>= 3.2.14)
41
+ diffy
40
42
  rspec (>= 2.14.1)
41
43
  simplecov (>= 0.7.1)
42
44
  term-ansicolor (>= 1.2.2)
data/README.md CHANGED
@@ -62,6 +62,20 @@ Define directory where the source code of stack modules located. Default is `../
62
62
 
63
63
  Default as above (refer to document below).
64
64
 
65
+ Then run:
66
+
67
+ $ stackup [config_file]
68
+
69
+ Default configuration file is `.app_stack.yml`
70
+
71
+ Command line options:
72
+
73
+ - `-h, --help` show help message
74
+ - `--verbose` show more informations
75
+ - `-s, --simulate` only show the copy list, do not actually copy
76
+ - `-f, --force` force overwrite new files (only import new file and
77
+ ask for updated files by default)
78
+
65
79
  ## Copy Precedence
66
80
 
67
81
  For a module chain `a, b, c, ...`, files exported by `b` will over-write
data/app_stack.gemspec CHANGED
@@ -8,6 +8,7 @@ Gem::Specification.new 'app_stack', AppStack::VERSION do |s|
8
8
  s.email = 'huangw@7lime.com'
9
9
  s.homepage = 'https://github.com/7lime/app_stack-gem'
10
10
  s.files = `git ls-files`.split("\n") - %w[.gitignore .rspec Rakefile]
11
+ s.executables << 'stackup'
11
12
  s.license = 'MIT'
12
13
  s.test_files = Dir.glob('{spec,test}/**/*.rb')
13
14
 
data/bin/config_assets ADDED
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ Tse
data/bin/stackup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # vi: ft=ruby
4
+
5
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
6
+ require 'app_stack'
7
+
8
+ AppStack.stackup!
data/file.erb ADDED
File without changes
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ require 'optparse'
4
+
5
+ # parse command line options based
6
+ # rubocop:disable MethodLength
7
+ class CliOptions
8
+ attr_accessor :force, :simulate, :verbose, :conf_file
9
+
10
+ def initialize(argv = ARGV)
11
+ parse_opt!(argv)
12
+ case argv.size
13
+ when 1 then self.conf_file = argv.shift
14
+ when 0 then self.conf_file = AppStack::DEFAULT_CONF_FILE
15
+ else fail "too many configuration files (#{argv.join(', ')})."
16
+ end
17
+ end
18
+
19
+ # parse command line options
20
+ def parse_opt!(argv)
21
+ opt_parser = OptionParser.new do |opts|
22
+ opts.banner = 'Usage: appstack [options] [config_file]'
23
+
24
+ opts.separator ''
25
+ opts.separator 'Available options:'
26
+
27
+ opts.on('-f', '--force', 'force overwrite') do
28
+ self.force = true
29
+ end
30
+
31
+ opts.on('-s', '--simulate', 'simulate only, do not copy') do
32
+ self.simulate = true
33
+ end
34
+
35
+ opts.on('--verbose', 'show debug messages') do
36
+ self.verbose = true
37
+ end
38
+
39
+ opts.on_tail('-h', '--help', 'show this message') do
40
+ puts opts
41
+ exit
42
+ end
43
+
44
+ opts.on_tail('-v', '--version', 'show version number') do
45
+ puts AppStack::VERSION
46
+ exit
47
+ end
48
+ end
49
+
50
+ opt_parser.parse!(argv)
51
+ end
52
+ end
@@ -0,0 +1,144 @@
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
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
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
+ end
103
+
104
+ puts "use -f (--option) option to overwrite all files,"
105
+ puts "or 'touch' local file to disable warn for specific file."
106
+ end
107
+
108
+ def do_copy!
109
+ @copy_files.each { |to, fr| copy_file!(fr, to) }
110
+ end
111
+
112
+ def do_render!
113
+ @render_files.each { |to, fr| render_file!(fr, to) }
114
+ end
115
+
116
+ # if f1 newer than f2, or f2 not exits but f1 does.
117
+ def newer?(f1, f2)
118
+ return false unless File.exists?(f1)
119
+ return true unless File.exists?(f2)
120
+ File.mtime(f1) > File.mtime(f2)
121
+ end
122
+
123
+ def copy_file!(fr, to)
124
+ target_dir = File.dirname(to)
125
+ FileUtils.mkdir_p target_dir unless File.directory?(target_dir)
126
+ puts "copied #{fr.blue} \n to: " + to.green.bold
127
+ FileUtils.copy fr, to
128
+ end
129
+
130
+ def render_file!(fr, to)
131
+ oh = File.open(to, 'wb')
132
+ if fr.match(/\.liquid$/)
133
+ require 'liquid'
134
+ oh.write Liquid::Template.parse(File.open(fr,
135
+ 'r:utf-8').read).render(attrs)
136
+ else
137
+ tilt = Tilt.new(fr)
138
+ oh.write tilt.render(OpenStruct.new(attrs))
139
+ end
140
+ oh.close
141
+ puts "readered #{fr.blue}\n to: " + to.green.bold
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,95 @@
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
@@ -0,0 +1,114 @@
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
+ @copy_list['r:' + f] = f.gsub(/#{@config[:tpl_ext].join('|')}$/, '')
91
+ echo 'found local template file: ',
92
+ short_path(f) + ' -> ' + short_path(@copy_list['r:' + f])
93
+ end
94
+
95
+ merge!
96
+ end
97
+
98
+ # echo message only if verbose specified to be true
99
+ def echo(msg, var = nil)
100
+ return unless @options.verbose
101
+
102
+ msg = "[#{app_name || self.class.name}] ".green + msg
103
+ msg += "\n" if var && var.inspect.size > 30
104
+
105
+ print msg
106
+ if var
107
+ print Term::ANSIColor.bold
108
+ var.inspect.size > 30 ? PP.pp(var) : PP.singleline_pp(var)
109
+ print Term::ANSIColor.reset
110
+ end
111
+ puts unless var && var.inspect.size > 30
112
+ end
113
+ end
114
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # AppStack module
4
4
  module AppStack
5
- VERSION = '1.2.1'
5
+ VERSION = '1.3.0'
6
6
  end
data/lib/app_stack.rb CHANGED
@@ -1,34 +1,25 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'yaml'
4
- require 'find'
5
- require 'fileutils'
6
- require 'ostruct'
7
- require 'tilt'
8
- require 'pathname'
9
- require 'active_support/core_ext/hash/deep_merge'
10
-
11
3
  require 'term/ansicolor'
12
4
  # mixin String class for term-color methods
13
5
  class String; include Term::ANSIColor end
14
6
 
15
- require 'app_stack/config'
16
- # require 'app_stack/copier'
17
- require 'app_stack/merger'
18
-
19
- ## A namespace for app-stack based modules
20
- module AppStack
21
- CONF_FILE = './.app_stack.yml'
7
+ require 'active_support/core_ext/hash/deep_merge'
22
8
 
9
+ require 'app_stack/version'
10
+ require 'app_stack/cli_options'
11
+ require 'app_stack/local_files_parser'
12
+ require 'app_stack/copy_list_builder'
13
+ require 'app_stack/stack_app'
23
14
 
24
- # based on conf_file, merge up from stack of applications
25
- def stackup!(conf_file)
26
- # merge files from stacks
27
- conf_file ||= CONF_FILE
28
- mger = Merger.new(conf_file)
15
+ # module functions for handle stackup
16
+ module AppStack
17
+ DEFAULT_CONF_FILE = '.app_stack.yml'
29
18
 
30
- # not run, just prepare in vobose mode
31
- ENV['NR'] ? mger.prepare(true) : mger.merge!
19
+ # handle the execution to main class:
20
+ def stackup!(argv = ARGV)
21
+ @options = CliOptions.new(argv)
22
+ StackApp.new(@options.conf_file, @options).stackup!
32
23
  end
33
24
 
34
25
  module_function :stackup!
data/tags ADDED
@@ -0,0 +1,45 @@
1
+ !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
2
+ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
3
+ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
4
+ !_TAG_PROGRAM_NAME Exuberant Ctags //
5
+ !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
6
+ !_TAG_PROGRAM_VERSION 5.8 //
7
+ AppStack lib/app_stack.rb /^module AppStack$/;" m
8
+ AppStack lib/app_stack/copy_list_builder.rb /^module AppStack$/;" m
9
+ AppStack lib/app_stack/local_files_parser.rb /^module AppStack$/;" m
10
+ AppStack lib/app_stack/merger.rb /^module AppStack$/;" m
11
+ AppStack lib/app_stack/stack_app.rb /^module AppStack$/;" m
12
+ AppStack lib/app_stack/version.rb /^module AppStack$/;" m
13
+ CliOptions lib/app_stack/cli_options.rb /^class CliOptions$/;" c
14
+ CopyListBuilder lib/app_stack/copy_list_builder.rb /^ module CopyListBuilder$/;" m class:AppStack
15
+ CopyListItem lib/app_stack/stack_app.rb /^ class CopyListItem$/;" c class:AppStack
16
+ LocalFilesParser lib/app_stack/local_files_parser.rb /^ module LocalFilesParser$/;" m class:AppStack
17
+ Merger lib/app_stack/merger.rb /^ class Merger$/;" c class:AppStack
18
+ ParseError lib/app_stack/stack_app.rb /^ class ParseError < RuntimeError; end$/;" c class:AppStack
19
+ StackApp lib/app_stack/stack_app.rb /^ class StackApp$/;" c class:AppStack
20
+ String lib/app_stack.rb /^class String; include Term::ANSIColor end$/;" c
21
+ app_name lib/app_stack/local_files_parser.rb /^ def app_name$/;" f class:AppStack.LocalFilesParser
22
+ attr_mod? lib/app_stack/merger.rb /^ def attr_mod?(to)$/;" f class:AppStack.Merger
23
+ copy_file! lib/app_stack/merger.rb /^ def copy_file!(fr, to)$/;" f class:AppStack.Merger
24
+ directory lib/app_stack/local_files_parser.rb /^ def directory$/;" f class:AppStack.LocalFilesParser
25
+ echo lib/app_stack/stack_app.rb /^ def echo(msg, var = nil)$/;" f class:AppStack.StackApp
26
+ export_files lib/app_stack/local_files_parser.rb /^ def export_files(group = 'default')$/;" f class:AppStack.LocalFilesParser
27
+ find_files lib/app_stack/local_files_parser.rb /^ def find_files(plist)$/;" f class:AppStack.LocalFilesParser
28
+ full_path lib/app_stack/local_files_parser.rb /^ def full_path(file)$/;" f class:AppStack.LocalFilesParser
29
+ glob_files lib/app_stack/local_files_parser.rb /^ def glob_files(dir, allow_hash = false)$/;" f class:AppStack.LocalFilesParser
30
+ import_files lib/app_stack/copy_list_builder.rb /^ def import_files(import_conf)$/;" f class:AppStack.CopyListBuilder
31
+ initialize lib/app_stack/cli_options.rb /^ def initialize(argv = ARGV)$/;" f class:CliOptions
32
+ initialize lib/app_stack/merger.rb /^ def initialize(conf_file, verbose = false)$/;" f class:AppStack.Merger
33
+ initialize lib/app_stack/stack_app.rb /^ def initialize(filename, options)$/;" f class:AppStack.StackApp
34
+ load_stack lib/app_stack/merger.rb /^ def load_stack(stack_name, groups)$/;" f class:AppStack.Merger
35
+ load_stack lib/app_stack/stack_app.rb /^ def load_stack$/;" f class:AppStack.StackApp
36
+ merge! lib/app_stack/merger.rb /^ def merge!$/;" f class:AppStack.Merger
37
+ newer? lib/app_stack/merger.rb /^ def newer?(f1, f2)$/;" f class:AppStack.Merger
38
+ parse_export_files lib/app_stack/local_files_parser.rb /^ def parse_export_files$/;" f class:AppStack.LocalFilesParser
39
+ parse_opt! lib/app_stack/cli_options.rb /^ def parse_opt!(argv)$/;" f class:CliOptions
40
+ parse_stacks lib/app_stack/merger.rb /^ def parse_stacks$/;" f class:AppStack.Merger
41
+ prepare lib/app_stack/merger.rb /^ def prepare(verbose = false)$/;" f class:AppStack.Merger
42
+ render_file! lib/app_stack/merger.rb /^ def render_file!(fr, to)$/;" f class:AppStack.Merger
43
+ short_path lib/app_stack/local_files_parser.rb /^ def short_path(path)$/;" f class:AppStack.LocalFilesParser
44
+ stackup! lib/app_stack.rb /^ def stackup!(argv = ARGV)$/;" f class:AppStack
45
+ stackup! lib/app_stack/stack_app.rb /^ def stackup!$/;" f class:AppStack.StackApp