app_stack 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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