app_stack 0.0.3
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/README.md +41 -0
- data/app_stack.gemspec +19 -0
- data/examples/my_app/.app-stack.yml +25 -0
- data/examples/my_app/Gemfile +5 -0
- data/examples/my_app/README +1 -0
- data/examples/my_app/config/app.config.rb +4 -0
- data/examples/my_app/config/configuration.yml +4 -0
- data/examples/stack-apps/auth-app/Gemfile +0 -0
- data/examples/stack-apps/auth-app/Gemfile.line_addon +1 -0
- data/examples/stack-apps/auth-app/README +1 -0
- data/examples/stack-apps/auth-app/config/app.config.rb +4 -0
- data/examples/stack-apps/auth-app/config/configuration.yml +2 -0
- data/examples/stack-apps/auth-app/config/configuration.yml.template.erb +4 -0
- data/examples/stack-apps/base-app/.app-stack.yml +23 -0
- data/examples/stack-apps/base-app/README +1 -0
- data/examples/stack-apps/base-app/config/app.config.rb +4 -0
- data/lib/app_stack/version.rb +6 -0
- data/lib/app_stack.rb +150 -0
- metadata +118 -0
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 @@
|
|
1
|
+
readme in my app
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
gem 'devise'
|
@@ -0,0 +1 @@
|
|
1
|
+
readme in auth_app
|
@@ -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
|
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: []
|