app_stack 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzBjNDgxMTQyZGE2NDMzNTRiYWExNTdlYmY4ZTNmZjVkMjNlMmZiMw==
5
+ data.tar.gz: !binary |-
6
+ OGIwNDZiNzNlNGQzYTViNDRmYTJhYWJmNzM5NGI1MzMxZmVkYWRkNA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MWU3MzhiNmQ5NDgzOTJiODM5YTQ0MmQ1YmMzMjNkNzI5ZmNjMDlmMjYwZDVm
10
+ OTY1MjA3OWE0MDcyYWQ3ZTc5NTU0NGE4OTY0MTY3MDk5YjEwMWU4MWI0Mjky
11
+ NmIzMGZkOTRiMGIzZjIzNGM4NjdlZGNmZTQwOGY0YmU0OWFkZmQ=
12
+ data.tar.gz: !binary |-
13
+ YzUzZGY3MjBkODAxZDFiNjM3NGY2MDhlNzY2NWUxMWI2ODk0ZGFkYjI4ZTNj
14
+ NjRmM2U5MjU1NmNjNDE3ZTE1ZGU3YjJjOWQyNWFlNDJmNzU0NjUxYjk2YTAz
15
+ YzFlYmRiMmYyOTg5OTlkMmYyYWI1NTVlNzM2YzMzZWZlYjBiNjY=
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ % AppStack: Merge Source Code from A Stack of App Modules
2
+ % Huang Wei <huangw@7lime.com>
3
+ % 3013-08-26
4
+
5
+ ## Concept
6
+
7
+ A configuration file `.app-stack.yml` in you app-root, in format like:
8
+
9
+ stack: [base-module auth-module ...]
10
+ app_dir: '../stack-apps'
11
+ tpl_ext: '.sample.erb'
12
+ verbose: 1
13
+ attrs:
14
+ dababase_name: 'nameofdatabase'
15
+ files:
16
+ README.md << __self
17
+ app/controllers/home_controller.rb << base-module
18
+
19
+ And in `Rakefile` add:
20
+
21
+ require 'app_stack'
22
+
23
+ namespace :stack do
24
+ task :update do
25
+ AppStack.new('.app-stack.yml').run!
26
+ end
27
+ end
28
+
29
+ Run `rack stack:up` will copy files according to the setting from yaml file,
30
+ and any new files that in you app stack but not in the current directory.
31
+
32
+ ## Template and Addition
33
+
34
+ If you have a file end with `.sample.erb`, for example `config.sample.erb`
35
+ in your stack besides `config`, this file will be used as a erb template, and
36
+ the output with combines with `attrs` set in your local yaml file. Those value
37
+ will inherited follow the stacks (from v0.0.2).
38
+
39
+ If you have a file name end with `.line_addon`, like `Gemfile.line_addon`,
40
+ the contents of this file will add to local `Gemefile` line by line unless
41
+ the line is already exists (from v0.0.3).
data/app_stack.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
+ require 'app_stack/version'
3
+
4
+ Gem::Specification.new 'app_stack', AppStack::VERSION do |s|
5
+ s.description = 'Merge app source code in a stack to increase module reusability'
6
+ s.summary = 'Use as a rake task, define a stack of modules and app-stack will merge files from those stack-apps to the local application directory.'
7
+ s.authors = ['Huang Wei']
8
+ s.email = 'huangw@7lime.com'
9
+ s.homepage = 'https://github.com/7lime/app-stack-gem'
10
+ s.files = `git ls-files`.split("\n") - %w[.gitignore Rakefile]
11
+ s.license = 'MIT'
12
+ s.test_files = Dir.glob('{spec,test}/**/*.rb')
13
+
14
+ s.add_dependency 'tilt'
15
+ s.add_dependency 'term-ansicolor'
16
+ s.add_development_dependency 'rspec', '~> 2.5'
17
+ s.add_development_dependency 'simplecov', '~> 2.5'
18
+ end
19
+
@@ -0,0 +1,25 @@
1
+ ---
2
+ stack:
3
+ - base-app
4
+ - auth-app
5
+ stack_apps_dir: ../stack-apps
6
+ tpl_ext: .template.erb
7
+ addon_ext: .line_addon
8
+ verbose: 1
9
+ ignores:
10
+ - .+\.swap
11
+ - ~.+
12
+ - .+~
13
+ attrs:
14
+ application_name: My App
15
+ from_self: myapp
16
+ files:
17
+ README: __self
18
+ config: base-app
19
+ config/app.config.rb: base-app
20
+ config/configuration.yml: auth-app
21
+ config/configuration.yml.template.erb: auth-app
22
+ .app-stack.yml: __self
23
+ Gemfile: __self
24
+ Gemfile.line_addon: auth-app
25
+ Gemefile: auth-app
@@ -0,0 +1,5 @@
1
+ source 'http://ruby.taobao.org/'
2
+
3
+ gem 'fluentd'
4
+ gem 'cucumber'
5
+ gem 'devise'
@@ -0,0 +1 @@
1
+ readme in my app
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ base_config = 'in base_app'
4
+ base_config = 'base_app' if base_config
@@ -0,0 +1,4 @@
1
+ Application:
2
+ Name: My App
3
+ Super: base
4
+ Inherit: myapp
File without changes
@@ -0,0 +1 @@
1
+ gem 'devise'
@@ -0,0 +1 @@
1
+ readme in auth_app
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ auth_config = 'in auth_app'
4
+ auth_config = 'auth_app' if auth_config
@@ -0,0 +1,2 @@
1
+ This:
2
+ File: Not Set
@@ -0,0 +1,4 @@
1
+ Application:
2
+ Name: <%= application_name %>
3
+ Super: <%= from_super %>
4
+ Inherit: <%= from_self %>
@@ -0,0 +1,23 @@
1
+ ---
2
+ stack:
3
+ - base-app
4
+ - auth-app
5
+ stack_apps_dir: ../stack-apps
6
+ tpl_ext: .template.erb
7
+ verbose: 1
8
+ ignores:
9
+ - .+\.swap
10
+ - ~.+
11
+ - .+~
12
+ attrs:
13
+ application_name: My App
14
+ from_super: 'base'
15
+ from_self: 'base'
16
+ files:
17
+ .app-stack.yml: __self
18
+ README: __self
19
+ config: base-app
20
+ config/app.config.rb: base-app
21
+ config/.app.config.rb.swp: auth-app
22
+ config/configuration.yml: auth-app
23
+ config/configuration.yml.template.erb: auth-app
@@ -0,0 +1 @@
1
+ readme in base_app
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ base_config = 'in base_app'
4
+ base_config = 'base_app' if base_config
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ # AppStack module
4
+ module AppStack
5
+ VERSION = '0.0.3'
6
+ end
data/lib/app_stack.rb ADDED
@@ -0,0 +1,150 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+ require 'find'
5
+ require 'fileutils'
6
+ require 'term/ansicolor'
7
+ # mixin String class for term-color methods
8
+ class String; include Term::ANSIColor end
9
+ require 'tilt/erb'
10
+ require 'ostruct'
11
+
12
+ ## A namespace for app-stack based modules
13
+ module AppStack
14
+
15
+ CONF_FILE = '.app-stack.yml'
16
+
17
+ def run!(file = '.app-stack.yml')
18
+ # load configuration
19
+ @config = YAML.load(File.read(file))
20
+ @attr = {}
21
+ # assign default values:
22
+ @app_root = File.expand_path(File.dirname(file)) unless @config['app_root']
23
+ @stack_apps_dir = @config['stack_apps_dir']
24
+ @stack_apps_dir = @app_root + '/' +
25
+ @stack_apps_dir if @stack_apps_dir.match(/^\.\.?\//)
26
+
27
+ @files = @config['files'] || {}
28
+ register_own_files!
29
+ # loop over each stack application
30
+ @config['stack'].each { |stack_app| do_copy(stack_app) }
31
+ # rewrite configuration back to app-stack file
32
+ @config['files'] = @files
33
+ File.open(file, 'wb') { |fh| fh.puts YAML.dump(@config) }
34
+ end
35
+
36
+ def newer(f1, f2)
37
+ return false unless File.exists?(f1)
38
+ return true unless File.exists?(f2)
39
+ File.mtime(f1) > File.mtime(f2)
40
+ end
41
+
42
+ def do_addon!(f, basename)
43
+ target = File.expand_path(@app_root + '/' + basename)
44
+ # add on always applies
45
+ addon_file = f + @config['addon_ext']
46
+ if File.exists?(addon_file) # && newer(addon_file, target)
47
+ add_lines = File.read(addon_file).split("\n")
48
+ add_lines -= File.read(target).split("\n")
49
+ afh = File.open(target, 'a')
50
+ add_lines.each { |line| afh.puts line }
51
+ afh.close
52
+ done = 'add lines'.bold.green if add_lines.size > 0
53
+ end
54
+ end
55
+
56
+ # rubocop:disable MethodLength
57
+ def copy_file!(f, basename)
58
+ return 'ignored'.white if ignores(basename)
59
+
60
+ done = 'keeped'.green
61
+ target = File.expand_path(@app_root + '/' + basename)
62
+ # directory?
63
+ if File.directory?(f)
64
+ if File.directory?(target)
65
+ done = 'exists'.green
66
+ else
67
+ FileUtils.mkdir_p target
68
+ done = 'created'.bold.green
69
+ end
70
+ else
71
+ tpl_file = f + @config['tpl_ext']
72
+ if File.exists?(tpl_file) && newer(tpl_file, target)
73
+ @tilt = Tilt::ERBTemplate.new(tpl_file)
74
+ oh = File.open(target, 'wb')
75
+ oh.write @tilt.render(OpenStruct.new(@attr.merge(@config['attrs'])))
76
+ oh.close
77
+ done = 'rendered'.bold.green
78
+ elsif newer(f, target)
79
+ FileUtils.copy f, target
80
+ done = 'copied'.bold.green
81
+ end
82
+ end
83
+ done
84
+ end
85
+ # rubocop:able MethodLength
86
+
87
+ def ignores(f)
88
+ @config['ignores'] = [] unless @config['ignores']
89
+ return true if f == CONF_FILE
90
+ return true if /#{@config['tpl_ext']}$/.match(f)
91
+ return true if /#{@config['addon_ext']}$/.match(f)
92
+ @config['ignores'].each do |ptn|
93
+ return true if /#{ptn}/.match(f)
94
+ end
95
+ false
96
+ end
97
+
98
+ def do_copy(stack_app)
99
+ raise 'invalid app name "__self"' if stack_app == '__self'
100
+ stack_app_dir = File.expand_path(@stack_apps_dir + '/' + stack_app)
101
+
102
+ # merge attr setting
103
+ if File.exists?(stack_app_dir + '/' + CONF_FILE)
104
+ stack_conf = YAML.load(File.read(stack_app_dir + '/' + CONF_FILE))
105
+ @attr.merge! stack_conf['attrs'] if stack_conf['attrs'] &&
106
+ stack_conf['attrs'].is_a?(Hash)
107
+ end
108
+
109
+ Find.find(stack_app_dir).each do |f|
110
+ basename = f.sub(/^#{stack_app_dir}\//, '')
111
+ next if f == stack_app_dir
112
+ do_copy_it = @files[basename] ? false : true
113
+ do_copy_it = true if @files[basename] == stack_app
114
+ if do_copy_it
115
+ @files[basename] = stack_app unless @files[basename]
116
+ done = copy_file!(f, basename)
117
+ carp "From #{stack_app.blue.bold} #{basename.bold}", done
118
+ else
119
+ carp "From #{stack_app.blue.bold} #{basename.bold}",
120
+ 'skip, use '.white + @files[basename]
121
+ end
122
+ done = do_addon!(f, basename)
123
+ carp "From #{stack_app.blue.bold} addon #{basename.bold}", done if done
124
+ end
125
+ end
126
+
127
+ # for files already in the app root, register to no-copy list
128
+ def register_own_files!
129
+ Find.find(@app_root).each do |f|
130
+ next if f == @app_root
131
+ basename = f.sub(/^#{@app_root}\//, '')
132
+ unless @files[basename]
133
+ carp "From #{'self'.blue.bold} #{basename.bold}", 'registed'.green.bold
134
+ @files[basename] = '__self'
135
+ end
136
+
137
+ carp "From #{'self'.blue.bold} #{basename.bold} ",
138
+ 'keep'.green if @files[basename] == '__self'
139
+ end
140
+ end
141
+
142
+ def carp(job, state = 'done'.green)
143
+ return unless @config['verbose'] && @config['verbose'] > 0
144
+ dots = 70 - job.size
145
+ dots = 0 if dots < 0
146
+ puts job + ' ' + '.' * dots + ' ' + state
147
+ end
148
+
149
+ extend self
150
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: app_stack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Huang Wei
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tilt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: term-ansicolor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '2.5'
69
+ description: Merge app source code in a stack to increase module reusability
70
+ email: huangw@7lime.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - README.md
76
+ - app_stack.gemspec
77
+ - examples/my_app/.app-stack.yml
78
+ - examples/my_app/Gemfile
79
+ - examples/my_app/README
80
+ - examples/my_app/config/app.config.rb
81
+ - examples/my_app/config/configuration.yml
82
+ - examples/stack-apps/auth-app/Gemfile
83
+ - examples/stack-apps/auth-app/Gemfile.line_addon
84
+ - examples/stack-apps/auth-app/README
85
+ - examples/stack-apps/auth-app/config/app.config.rb
86
+ - examples/stack-apps/auth-app/config/configuration.yml
87
+ - examples/stack-apps/auth-app/config/configuration.yml.template.erb
88
+ - examples/stack-apps/base-app/.app-stack.yml
89
+ - examples/stack-apps/base-app/README
90
+ - examples/stack-apps/base-app/config/app.config.rb
91
+ - lib/app_stack.rb
92
+ - lib/app_stack/version.rb
93
+ homepage: https://github.com/7lime/app-stack-gem
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.0.6
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Use as a rake task, define a stack of modules and app-stack will merge files
117
+ from those stack-apps to the local application directory.
118
+ test_files: []