app_stack 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzE2OTk2NTU4ZWJkMTc2ZDA2NmE4OWE4NGUwMjljY2RiNGQ4NTk1Mw==
4
+ MDM3Mzk3NGEzZjlkMzFmYmUxZTgyZWQ4YzkwMTA3YjFiOTM5ZDY0ZA==
5
5
  data.tar.gz: !binary |-
6
- MTUwYjA2OTYxYjk2NWEyNzk2YWExZmRiYTA0YTU0ZjViYTI0MTEzYw==
6
+ YWU5NDA4ZWFkYTk1ZGIzYjRmZTM2ZTQ4ZjM1NDM1NmY2NmYyMGU0Mw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YzFmOThkNzg5YmFiMTdlNzJhODU1ZTczM2JkN2U3NDlkYzQzYmFhMTZiNjdi
10
- YTFmZTVjYzM3MjMzZmVmYjJjNGZjMGQ4YzQwODQwYzE1MDk0M2FjYWZlNTgw
11
- YThjM2QxYzhhZTcyNTY5MTMyMTVmZjA0NWI1ZTY3MTEwODEzOTU=
9
+ Mjc3NTIxOWEwMDc3NDkyMWQ2NDUyMjVlMDA4YzQ5MzAxM2ZjN2MxNzNlMDEw
10
+ NjdmMjRiYmU0ZGEyZWVhNjAzYzI2MTYwNzI5Njc4YTkxYjgyNmI3ODEyNDRh
11
+ NmI0MGI3OGY3MmQ4ZjgxNTBmYjFlYTkyOGQ3MzIxY2FlZmY3NDg=
12
12
  data.tar.gz: !binary |-
13
- ZWE1OWMzNDZiZTk3ZjdhYzBhMDU5MmFmZGYwYTNjM2Q2ZWYzZDVjOGVlZWQ5
14
- ODM0YzVhNWQ3ODMzMzU4NzhjZWRhZThkMDhkMWI3NDQzYWQ2NjAyM2RjYWQ5
15
- YTI3YWZiMjBjYTc4ODE4NTEwOTQ2ZGVmOWFhZWI3ZDg1YWUwZTc=
13
+ NDBlNDk4MjM0ODExODc5NGFhOTA0YWUyMzMwZjE2Y2QwZWFhMzkxYTFlMzg5
14
+ MTVlYWFiM2MwNTYxYTI5MDI5NTExYzNlZjJiMjE0NjMwZGQ3Zjc0OTE1MWFl
15
+ ODMwNjA4MmI1ZDkwOTQ0Y2M0ZmEzMTkwZDVmMDllMjNmNjI2MTg=
data/README.html ADDED
@@ -0,0 +1,172 @@
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta charset='utf-8'>
5
+ <title>Preview</title>
6
+ <!--this style include the test_md/css screen.css(first) and base.css -->
7
+ <style type="text/css">
8
+ pre code{display:block;background:#fff;color:#4d4d4c;font-family:Menlo, Monaco, Consolas, monospace;font-size:12px;line-height:1.5;border:1px solid #ccc;padding:10px}html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,code,del,dfn,em,img,q,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline}table{border-collapse:separate;border-spacing:0}caption,th,td{text-align:left;font-weight:normal}table,td,th{vertical-align:middle}blockquote:before,blockquote:after,q:before,q:after{content:""}blockquote,q{quotes:"" ""}a img{border:none}body{margin:10px}html{height:100%}body{padding:0;margin:0;font:14px/22px "adelle", Georgia, sans-serif;font-size-adjust:none;font-style:normal;font-variant:normal;font-weight:normal;background:#f4f6ec}a{color:#369}#markdown-toc{float:left;width:230px;margin-right:30px;margin-top:40px}#markdown-toc a{display:block;font-weight:bold;text-decoration:none}#markdown-toc #sections{list-style-type:none;border-bottom:3px solid rgba(0,0,0,0.1);padding-bottom:10px;margin-bottom:10px}#markdown-toc #sections>li>a{padding:5px 0;color:#444;font-size:16px}#markdown-toc #sections ul{margin-bottom:15px}#markdown-toc #sections ul li{list-style-type:none}#markdown-toc #sections ul li a{padding:1px 15px;font-size:13px;font-weight:normal}#markdown-toc .extra{padding:5px 0;min-height:1.4em}#markdown-toc .extra a{color:#555;font-size:14px}#markdown-toc #travis img{margin-top:10px;display:block}#markdown-toc>*:last-child{margin-bottom:20px}#content{padding:30px 30px 20px 30px;min-height:100px;width:600px;background:#fff;float:left;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;margin-top:15px}#content #loader{color:#888;width:300px;height:24px;line-height:24px;position:absolute;top:30px;left:30px;background:url("data:image/gif;base64,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") no-repeat center left;padding-left:32px;font-size:18px}#content>p{zoom:1}#content>p:before,#content>p:after{content:"";display:table}#content>p:after{clear:both}#content p{padding:0 0 0.8125em 0;color:#444}#content p img{float:left;margin:0.5em 0.8125em 0.8125em 0;padding:0}#content img{max-width:100%}#content h1,#content h2,#content h3,#content h4,#content h5,#content h6{font-weight:bold;line-height:1.2em}#content h1{font-size:2.125em;margin-bottom:0.4em}#content h2{font-size:1.7em;margin:0.855em 0 0.4em;color:#cc333f}#content h3{font-size:1.3em;margin:0.956em 0 0.4em}#content h4{font-size:1.1em;margin:1.161em 0 0.4em}#content h5,#content h6{font-size:1em;font-weight:bold;margin:1.238em 0 0.4em}#content>h1,#content>h2{margin-top:0}#content ul{list-style-position:outside}#content li ul,#content li ol{margin:0 1.625em}#content ul,#content ol{margin:0 0 1.625em 1.25em}#content dl{margin:0 0 1.625em 0}#content dl dt{font-weight:bold}#content dl dd{margin-left:1.625em}#content a{text-decoration:none}#content a:hover{text-decoration:underline}#content table{margin-bottom:1.625em;border-collapse:collapse}#content th{font-weight:bold}#content tr,#content th,#content td{margin:0;padding:0 1.625em 0 1em;height:26px}#content tfoot{font-style:italic}#content caption{text-align:center;font-family:Georgia, serif}#content abbr,#content acronym{border-bottom:1px dotted #000}#content address{margin-top:1.625em;font-style:italic}#content del{color:#000}#content blockquote{padding:1em 1em 1.625em 1em;font-family:georgia, serif;font-style:italic}#content blockquote:before{content:"\201C";font-size:3em;margin-left:-0.625em;font-family:georgia, serif;color:#aaa;line-height:0}#content blockquote>p{padding:0;margin:0}#content strong{font-weight:bold}#content em,#content dfn{font-style:italic}#content dfn{font-weight:bold}#content pre,#content code{margin:0 0 1.625em;white-space:pre}#content pre,#content code,#content tt{font-size:1em;font-family:Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace;line-height:1.5}#content code{background:#f7f8f1;padding:1px 2px;border:1px solid #ccc}#content pre code{padding:10px 12px;word-wrap:normal;overflow-y:auto}#content tt{display:block;margin:1.625em 0}#content hr{margin-bottom:1.625em}#content table{font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;width:100%}#content th,#content td{padding:5px 10px;border:1px solid #ccc}#content th{background:#eee;padding:7px 10px}#content td{font-size:0.9em;border-color:#ddd}#content tbody tr:nth-child(2n){background:#f5f5f5}@media only screen and (max-width: 480px){#container{width:100%}#markdown-toc{width:100%;margin-top:10px;float:none}#markdown-toc #sections,#markdown-toc #header,#markdown-toc .extra{padding-left:30px;padding-right:30px}#content{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border-width:1px;float:none;margin:0;width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}}@media only screen and (min-device-pixel-ratio: 1.5), only screen and (min-resolution: 1.5dppx){#github-ribbon img{width:100px}}*{margin:0;padding:0}body{margin-left:40px}#markdown-toc{float:right !important;position:fixed;left:745px;height:90%;overflow:auto}#content{float:left !important;filter:progid:DXImageTransform.Microsoft.Shadow(color=#909090,direction=120,strength=4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:2px 2px 10px #909090}#markdown-toc{width:auto;max-width:300px !important;top:40px}#markdown-toc>li>ul>li>a{color:#cc333f;margin-top:10px}#markdown-toc>li>ul>li>ul>li>a,h3{color:#009999}#markdown-toc>li>ul>li>ul>li>ul>li>a,h4{color:#669999}#markdown-toc>li>a{margin-bottom:20px;padding-bottom:20px;border-bottom:3px solid rgba(0,0,0,0.1);font-size:20px;color:#000000}#content code{border-radius:3px}#content>h1{font-size:2.0em}.title{font-size: 2.4em;color: #ff5456 !important}#markdown-toc>li{margin-bottom: 30px}#markdown-toc>li>a{padding-bottom:10px;}#markdown-toc>li>a{font-size: 18px;}#markdown-toc{white-space: nowrap}h1,h2,h3,h4,h5,h6{margin-bottom:1em !important;}#markdown-toc>li>ul>li>ul>li>ul>li>ul>li>a,h5{color:#7bb8b8 !important}#markdown-toc>li>ul>li>ul>li>ul>li>a,h4{color:#6c9e00 !important}#markdown-toc>li>ul>li>ul>li>a, h3{color:#3C6E6E !important}#markdown-toc>li>ul>li>a, h2{color:#4E6EA0 !important}#markdown-toc>li>a, h1{color:#134da5 !important}body{background:#ffffff}.code pre{border:1px solid rgb(204, 204, 204);overflow:auto;border-radius:3px}.code pre{background: none repeat scroll 0% 0% rgb(247, 248, 241)}#content sup{background: #c8deff}#content sup a{color: #273650}#content .footnotes{background: rgba(0,0,0,0.1);padding: 10px 0 0px 10px;border-radius: 5px}.reversefootnote{color: #000000;}
9
+ </style>
10
+
11
+ </head>
12
+
13
+ <body>
14
+ <div id="content">
15
+
16
+ <ul id="markdown-toc">
17
+ <li><a href="#merge-source-files-from-directories-in-chain">Merge Source Files from Directories in Chain</a> <ul>
18
+ <li><a href="#concept">Concept</a></li>
19
+ <li><a href="#synposis">Synposis</a> <ul>
20
+ <li><a href="#syncimport-from-other-modules">Sync/Import from other modules</a></li>
21
+ <li><a href="#export-groups">Export groups</a></li>
22
+ <li><a href="#render-a-template-file">Render a template file</a></li>
23
+ </ul>
24
+ </li>
25
+ <li><a href="#parking-list-for-new-version-14">Parking list for new version (1.4)</a></li>
26
+ </ul>
27
+ </li>
28
+ </ul>
29
+
30
+ <h1 id="merge-source-files-from-directories-in-chain">Merge Source Files from Directories in Chain</h1>
31
+
32
+ <h2 id="concept">Concept</h2>
33
+
34
+ <p>Import source files from a chain of application modules.</p>
35
+
36
+ <h2 id="synposis">Synposis</h2>
37
+
38
+ <h3 id="syncimport-from-other-modules">Sync/Import from other modules</h3>
39
+
40
+ <p>Suppose your local application is <code>dulcinea</code> and you want a file <code>lab.lua</code> from
41
+ directory <code>separate_module</code>, suppose directory <code>dulcinea</code> and <code>separate_module</code> are
42
+ located in the same location, then create a file <code>dulcinea/.app_stack.yml</code> like:</p>
43
+
44
+ <pre><code>sync:
45
+ - separate_module: { lab.lua: '' }
46
+ </code></pre>
47
+
48
+ <p>and run</p>
49
+
50
+ <pre><code>$ stackup
51
+ </code></pre>
52
+
53
+ <p>under the <code>dulcinea</code> directory, <code>lab.lua</code> will copied from <code>separate_module</code>.</p>
54
+
55
+ <p>If the file <code>lab.lua</code> in <code>separate_module</code> changed, run <code>stackup</code> again in
56
+ <code>dulcinea</code> will get a warning with colored diff message (you need <code>diff</code> command
57
+ installed in your system). If you want to over-writtern <code>dulcinea/lab.lua</code>, run</p>
58
+
59
+ <pre><code>$ stackup -f
60
+ </code></pre>
61
+
62
+ <p>If you want copy outside file only if local file not exists, use</p>
63
+
64
+ <pre><code>sync:
65
+ - separate_module: { lab.lua: '' }
66
+ - other_module: { copymeto.inc: 'copymeto.php' }
67
+ import:
68
+ - separate_module: { copyme: '' }
69
+ </code></pre>
70
+
71
+ <p>Note <code>other_module/copymeto.inc</code> will be copied as <code>dulcinea/copymeto.php</code>,
72
+ as explicitly defined in the above example.</p>
73
+
74
+ <h3 id="export-groups">Export groups</h3>
75
+
76
+ <p>If the <em>remote</em> module, like <code>separate_module</code> in the last example also <em>appstack aware</em>,
77
+ it may have a file <code>.app_stack.yml</code> or <code>app_stack.yml</code> in their root folder like:</p>
78
+
79
+ <pre><code>export:
80
+ - some.lua
81
+ - lib/**/*.lua
82
+ - config:
83
+ - config/*.lua
84
+ </code></pre>
85
+
86
+ <p>In this example setting, <code>separate_module</code> defined two <strong>export groups</strong>: <code>default</code>
87
+ and <code>config</code>, default group contains <code>some.lua</code> and all lua files under <code>lib/</code> folder
88
+ and all it&#8217;s sub-folders. <code>config</code> group (which defined as a Hash with an Array value, in YAML format)
89
+ conains all lua files under <code>config/</code> folder. You can <strong>import</strong> config files while <strong>sync</strong> default files from
90
+ <code>separate_module</code> by setting in <code>dulcinea/.app_stack.yml</code> like:</p>
91
+
92
+ <pre><code>import:
93
+ - separate_module
94
+ sync:
95
+ - separate_module: [ config ]
96
+ </code></pre>
97
+
98
+ <p>Or you want to sync both:</p>
99
+
100
+ <pre><code>sync:
101
+ - separate_module: [ config, default ]
102
+ </code></pre>
103
+
104
+ <p>You can still request for files that not explicitly exported by the remote configuration:</p>
105
+
106
+ <pre><code>sync:
107
+ - separate_module: [ config, default, { config.lua: config.sample.lua } ]
108
+ </code></pre>
109
+
110
+ <p>will sync <code>separate_module/config.lua</code> as <code>dulcinea/config.sample.lua</code>, as expected.</p>
111
+
112
+ <h3 id="render-a-template-file">Render a template file</h3>
113
+
114
+ <p>Suppose you have a template file <code>separate_module/main.lua.erb</code> like:</p>
115
+
116
+ <pre><code>...
117
+
118
+ local app_name = '&lt;%= app_name %&gt;'
119
+ local version = &lt;%= version_code %&gt;
120
+
121
+ ...
122
+ </code></pre>
123
+
124
+ <p>And in <code>separate_module/.app_stack.yml</code>:</p>
125
+
126
+ <pre><code>...
127
+ attrs:
128
+ app_name: Separated Module
129
+ version_code: 1.0
130
+ </code></pre>
131
+
132
+ <p>And in <code>dulcinea/.app_stack.yml</code>:</p>
133
+
134
+ <pre><code>render:
135
+ - separate_module: { main.lua.erb: '' }
136
+ attrs:
137
+ app_name: Main App
138
+ version_code: 1.0
139
+ </code></pre>
140
+
141
+ <p>You will get a file <code>dulcinea/main.lua</code> with contents</p>
142
+
143
+ <pre><code>...
144
+
145
+ local app_name = 'Main App'
146
+ local version = 1.0
147
+
148
+ ...
149
+ </code></pre>
150
+
151
+ <p>i.e., <code>attrs</code> are merged up from <strong>ALL</strong> stacked modules.</p>
152
+
153
+ <h2 id="parking-list-for-new-version-14">Parking list for new version (1.4)</h2>
154
+
155
+ <ul>
156
+ <li>[OK] Optional <code>.app_stack.yml</code> for stacked modules</li>
157
+ <li>[OK] Better detection for yaml file error</li>
158
+ <li>[OK] Better message with short file name</li>
159
+ <li>[OK] Render files only if contents really changed</li>
160
+ <li><del datetime="2013-11-11T10:05:01 +0800"><em>new file only</em> mode</del></li>
161
+ <li><del datetime="2013-11-11T10:05:15 +0800">Better simulate, new file only, force mode</del></li>
162
+ <li>Recursive stackup (?)</li>
163
+ <li>[OK] Separate sync/import group instead of one single <code>stackapps</code></li>
164
+ </ul>
165
+
166
+ </div>
167
+
168
+
169
+
170
+
171
+ </body>
172
+ </html>
data/README.md CHANGED
@@ -4,110 +4,140 @@
4
4
 
5
5
  Import source files from a chain of application modules.
6
6
 
7
- ## Parking list for new version (1.4)
7
+ ## Synposis
8
8
 
9
- - Optional `.app_stack.yml` for stacked modules
10
- - Better detection for yaml file error
11
- - Better message with short file name
12
- - Render files only if contents really changed
13
- - <del datetime="2013-11-11T10:05:01 +0800">*new file only* mode</del>
14
- - <del datetime="2013-11-11T10:05:15 +0800">Better simulate, new file only, force mode</del>
15
- - Recursive stackup (?)
16
- - Separate sync/import group instead of one single `stackapps`
9
+ ### Sync/Import from other modules
17
10
 
18
- ## Synposis
11
+ Suppose your local application is `dulcinea` and you want a file `lab.lua` from
12
+ directory `separate_module`, suppose directory `dulcinea` and `separate_module` are
13
+ located in the same location, then create a file `dulcinea/.app_stack.yml` like:
14
+
15
+ ~~~~~~~~~~~~~~~~~~~
16
+ sync:
17
+ - separate_module: { lab.lua: '' }
18
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
19
+
20
+ and run
21
+
22
+ $ stackup
19
23
 
20
- Put a configuration file `.app_stack.yml` in your application
21
- directory, in format like:
24
+ under the `dulcinea` directory, `lab.lua` will copied from `separate_module`.
22
25
 
23
- stack_dir: '../'
26
+ If the file `lab.lua` in `separate_module` changed, run `stackup` again in
27
+ `dulcinea` will get a warning with colored diff message (you need `diff` command
28
+ installed in your system). If you want to over-writtern `dulcinea/lab.lua`, run
24
29
 
25
- The directory contains other modules to import.
30
+ $ stackup -f
26
31
 
27
- import:
28
- - module-1
29
- sync:
30
- - module-2: [defaults, tests]
31
- - module-3:
32
- - defaults
33
- - file_a.html: file_a.htm
34
- - file_b.txt: ''
32
+ If you want copy outside file only if local file not exists, use
33
+
34
+ ~~~~~~~~~~~~~~~~~~~
35
+ sync:
36
+ - separate_module: { lab.lua: '' }
37
+ - other_module: { copymeto.inc: 'copymeto.php' }
38
+ import:
39
+ - separate_module: { copyme: '' }
40
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
35
41
 
36
- Define three modules to import (in directory `../module-1`, ...). Accord to the
37
- above setting, stack_app will copy `default` set of files exported by `module-1`,
38
- the `default` and `tests` set of files from `module-2` (file sets defined as string
39
- in array), and `defaults` set of files from `module-3`, plus `file_a.html` copied
40
- as `file_a.htm` and `file_b.txt` copied as it is (single files defined as a hash).
42
+ Note `other_module/copymeto.inc` will be copied as `dulcinea/copymeto.php`,
43
+ as explicitly defined in the above example.
41
44
 
42
- exclude:
43
- - config/*
44
- - filename_2
45
+ ### Export groups
45
46
 
46
- Do not copy `config/*` and single file `filename_2` from the stack.
47
+ If the _remote_ module, like `separate_module` in the last example also _appstack aware_,
48
+ it may have a file `.app_stack.yml` or `app_stack.yml` in their root folder like:
47
49
 
48
- export:
49
- - lib/**/*.rb
50
- - app/**/*.rb
51
- - tests:
52
- - spec/**/*.rb
50
+ ~~~~~~~~~~~~~~~~~~~~
51
+ export:
52
+ - some.lua
53
+ - lib/**/*.lua
54
+ - config:
55
+ - config/*.lua
56
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
53
57
 
54
- When used as a stack module, export the above files where ruby files under `lib/`
55
- and `app` are in the `defaults` set, besides with the `tests` set.
58
+ In this example setting, `separate_module` defined two **export groups**: `default`
59
+ and `config`, default group contains `some.lua` and all lua files under `lib/` folder
60
+ and all it's sub-folders. `config` group (which defined as a Hash with an Array value, in YAML format)
61
+ conains all lua files under `config/` folder. You can **import** config files while **sync** default files from
62
+ `separate_module` by setting in `dulcinea/.app_stack.yml` like:
56
63
 
57
- attrs:
58
- application_name: App Name
59
- application_code: app_code
60
- database_password: the very secret
61
- gems:
62
- default:
63
- - rspec: '~> 2.0.0'
64
- - ...
65
- development:
64
+ ~~~~~~~~~~~~~~~~~~~~
65
+ import:
66
+ - separate_module
67
+ sync:
68
+ - separate_module: [ config ]
69
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
66
70
 
67
- `attrs` can be inserted into `.erb` files.
71
+ Or you want to sync both:
68
72
 
69
- stack_dir: '../'
73
+ ~~~~~~~~~~~~~~~~~~~~
74
+ sync:
75
+ - separate_module: [ config, default ]
76
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
70
77
 
71
- Define directory where the source code of stack modules located. Default is `../`
78
+ You can still request for files that not explicitly exported by the remote configuration:
72
79
 
73
- tpl_ext: ['.erb', '.haml', '.liquid']
80
+ ~~~~~~~~~~~~~~~~~~~~
81
+ sync:
82
+ - separate_module: [ config, default, { config.lua: config.sample.lua } ]
83
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
74
84
 
75
- Default as above (refer to document below).
85
+ will sync `separate_module/config.lua` as `dulcinea/config.sample.lua`, as expected.
76
86
 
77
- Then run:
87
+ ### Render a template file
78
88
 
79
- $ stackup [config_file]
89
+ Suppose you have a template file `separate_module/main.lua.erb` like:
80
90
 
81
- Default configuration file is `.app_stack.yml`
91
+ ~~~~~~~~~~~~~~~~~~~~
92
+ ...
82
93
 
83
- Command line options:
94
+ local app_name = '<%= app_name %>'
95
+ local version = <%= version_code %>
84
96
 
85
- - `-h, --help` show help message
86
- - `--verbose` show more informations
87
- - `-s, --simulate` only show the copy list, do not actually copy
88
- - `-f, --force` force overwrite new files (only import new file and
89
- ask for updated files by default)
97
+ ...
98
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
90
99
 
91
- ## Copy Precedence
100
+ And in `separate_module/.app_stack.yml`:
92
101
 
93
- For a module chain `a, b, c, ...`, files exported by `b` will over-write
94
- the same files exported by `a` and so on.
102
+ ~~~~~~~~~~~~~~~~~~~~
103
+ ...
104
+ attrs:
105
+ app_name: Separated Module
106
+ version_code: 1.0
107
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
95
108
 
96
- If you want the files defined in `a`, manually copy it to the local directory
97
- and set it to `exclude` list.
109
+ And in `dulcinea/.app_stack.yml`:
98
110
 
99
- Note: `exclude` means 'use local file if exists, otherwise copy it', not
100
- 'do not copy it'.
111
+ ~~~~~~~~~~~~~~~~~~~~
112
+ render:
113
+ - separate_module: { main.lua.erb: '' }
114
+ attrs:
115
+ app_name: Main App
116
+ version_code: 1.0
117
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
101
118
 
102
- ## Template
119
+ You will get a file `dulcinea/main.lua` with contents
103
120
 
104
- If defined to export, for example `Gemfile`, and also defined a `Gemfile.erb`,
105
- the later will be used as a template to render `Gemefile`.
106
121
 
107
- For a module chain `a, b, c, ...`, `attrs` defined in `c` will merged into
108
- `attrs` defined in `b` ... and then assigned into the `erb` template.
122
+ ~~~~~~~~~~~~~~~~~~~~
123
+ ...
109
124
 
110
- App_stack use tilt to support `.erb`, `.haml` and `.liquid`, if a file have
111
- more than one template defined, the later will silently over-write the former.
112
- You can change the order in `tpl_ext` setting.
125
+ local app_name = 'Main App'
126
+ local version = 1.0
127
+
128
+ ...
129
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
130
+
131
+ i.e., `attrs` are merged up from **ALL** stacked modules.
132
+
133
+ ## Parking list for new version (1.4)
134
+
135
+ - [OK] Optional `.app_stack.yml` for stacked modules
136
+ - [OK] Better detection for yaml file error
137
+ - [OK] Better message with short file name
138
+ - [OK] Render files only if contents really changed
139
+ - <del datetime="2013-11-11T10:05:01 +0800">*new file only* mode</del>
140
+ - <del datetime="2013-11-11T10:05:15 +0800">Better simulate, new file only, force mode</del>
141
+ - Recursive stackup (?)
142
+ - [OK] Separate sync/import group instead of one single `stackapps`
113
143
 
data/lib/app_stack/app.rb CHANGED
@@ -34,13 +34,13 @@ module AppStack
34
34
  @app_stacks[app] = App.new(AppStack.find_conf_file(app_dir), app_dir)
35
35
  @app_stacks[app].rel_path = File.join(directory, config.stack_dir, app)
36
36
  @app_stacks[app].parse_export_groups!
37
- @attrs.merge! @app_stacks[app].config.attrs
37
+ @attrs.deep_merge! @app_stacks[app].config.attrs
38
38
 
39
39
  # info "load app #{app.bold} as", @app_stacks[app]
40
40
  info "load app #{app.bold}"
41
41
  end
42
42
 
43
- @attrs.merge! config.attrs
43
+ @attrs.deep_merge! config.attrs
44
44
  info 'merged attrs', attrs
45
45
  @app_stacks
46
46
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # AppStack module
4
4
  module AppStack
5
- VERSION = '1.4.0'
5
+ VERSION = '1.4.1'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Huang Wei
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-13 00:00:00.000000000 Z
11
+ date: 2013-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tilt
@@ -117,6 +117,7 @@ extra_rdoc_files: []
117
117
  files:
118
118
  - Gemfile
119
119
  - Gemfile.lock
120
+ - README.html
120
121
  - README.md
121
122
  - app_stack.gemspec
122
123
  - bin/stackup