new 0.0.1 → 0.0.2
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 +4 -4
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +79 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +121 -0
- data/bin/new +6 -0
- data/lib/new/cli.rb +94 -0
- data/lib/new/core.rb +6 -0
- data/lib/new/dsl.rb +42 -0
- data/lib/new/interpolate.rb +100 -0
- data/lib/new/project.rb +34 -0
- data/lib/new/task.rb +41 -0
- data/lib/new/template.rb +64 -0
- data/lib/new/version.rb +41 -0
- data/lib/new.rb +72 -0
- data/new-0.0.0.gem +0 -0
- data/new-0.0.1.gem +0 -0
- data/spec/fixtures/custom/tasks/custom_bar_task/custom_bar_task.rb +3 -0
- data/spec/fixtures/custom/templates/custom_bar_template/custom_bar.txt +0 -0
- data/spec/fixtures/tasks/custom_bar_task/custom_bar_task.rb +1 -0
- data/spec/fixtures/tasks/foo_task/foo_task.rb +7 -0
- data/spec/fixtures/templates/foo_template/[FOO.BAR].txt.erb +1 -0
- data/spec/fixtures/templates/foo_template/nested_[FOO.BAR]/foo.txt.erb +1 -0
- data/spec/lib/new/cli_spec.rb +104 -0
- data/spec/lib/new/interpolate_spec.rb +41 -0
- data/spec/lib/new/project_spec.rb +30 -0
- data/spec/lib/new/task_spec.rb +39 -0
- data/spec/lib/new/template_spec.rb +59 -0
- data/spec/lib/new/version_spec.rb +28 -0
- data/spec/lib/new_spec.rb +19 -0
- data/spec/spec_helper.rb +26 -0
- data/tasks/gem/README.md +36 -0
- data/tasks/gem/gem.rb +122 -0
- data/templates/js/Gemfile +30 -0
- data/templates/js/Guardfile +7 -0
- data/templates/js/LICENSE-MIT.erb +22 -0
- data/templates/js/README.md.erb +61 -0
- data/templates/js/demo/index.html.erb +7 -0
- data/templates/js/lib/README.md +2 -0
- data/templates/js/spec/[PROJECT_NAME].spec.js.coffee.erb +1 -0
- data/templates/js/spec/index.html.erb +29 -0
- data/templates/js/spec/spec_helper.js.coffee +0 -0
- data/templates/js/spec/vendor/chai.js +3765 -0
- data/templates/js/spec/vendor/sinon-chai.js +106 -0
- data/templates/js/spec/vendor/sinon.js +4246 -0
- data/templates/js/src/README.md +3 -0
- data/templates/js/src/[PROJECT_NAME].js.coffee.erb +10 -0
- data/templates/js/testem.yml +12 -0
- metadata +70 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bc7ceccb527c6c45b6d98046b396a55890aa2bc
|
4
|
+
data.tar.gz: 688b33a0980e1ab5413d2e2d92fbc1b187d93c72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3896cfd37150e57dba854c0da96a35880e537434a2e9b5348e43884acc7b8445c22f8b27ebff21b887a711f8797b5d143b135b9c0388e3f5c072b0f12cc24fed
|
7
|
+
data.tar.gz: 3ad4cb4fbf8b15e15316a7d12bd74f9af061f9583164ef142f95c5f21a6b5c218ca55aaf83f809767f0923f78f2f35dffc1f16c29a28b9fe29e5ddad689f7e4c
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activesupport'
|
4
|
+
gem 'colorize'
|
5
|
+
gem 'rake'
|
6
|
+
gem 'recursive-open-struct'
|
7
|
+
gem 'semantic'
|
8
|
+
gem 'thor'
|
9
|
+
|
10
|
+
group :development do
|
11
|
+
gem 'guard'
|
12
|
+
gem 'guard-bundler'
|
13
|
+
gem 'guard-rspec'
|
14
|
+
gem 'rspec'
|
15
|
+
gem 'terminal-notifier-guard'
|
16
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (4.0.2)
|
5
|
+
i18n (~> 0.6, >= 0.6.4)
|
6
|
+
minitest (~> 4.2)
|
7
|
+
multi_json (~> 1.3)
|
8
|
+
thread_safe (~> 0.1)
|
9
|
+
tzinfo (~> 0.3.37)
|
10
|
+
atomic (1.1.14)
|
11
|
+
celluloid (0.15.2)
|
12
|
+
timers (~> 1.1.0)
|
13
|
+
coderay (1.1.0)
|
14
|
+
colorize (0.6.0)
|
15
|
+
diff-lcs (1.2.5)
|
16
|
+
ffi (1.9.3)
|
17
|
+
formatador (0.2.4)
|
18
|
+
guard (2.3.0)
|
19
|
+
formatador (>= 0.2.4)
|
20
|
+
listen (~> 2.1)
|
21
|
+
lumberjack (~> 1.0)
|
22
|
+
pry (>= 0.9.12)
|
23
|
+
thor (>= 0.18.1)
|
24
|
+
guard-bundler (2.0.0)
|
25
|
+
bundler (~> 1.0)
|
26
|
+
guard (~> 2.2)
|
27
|
+
guard-rspec (4.2.5)
|
28
|
+
guard (~> 2.1)
|
29
|
+
rspec (>= 2.14, < 4.0)
|
30
|
+
i18n (0.6.9)
|
31
|
+
listen (2.4.0)
|
32
|
+
celluloid (>= 0.15.2)
|
33
|
+
rb-fsevent (>= 0.9.3)
|
34
|
+
rb-inotify (>= 0.9)
|
35
|
+
lumberjack (1.0.4)
|
36
|
+
method_source (0.8.2)
|
37
|
+
minitest (4.7.5)
|
38
|
+
multi_json (1.8.4)
|
39
|
+
pry (0.9.12.4)
|
40
|
+
coderay (~> 1.0)
|
41
|
+
method_source (~> 0.8)
|
42
|
+
slop (~> 3.4)
|
43
|
+
rake (10.1.0)
|
44
|
+
rb-fsevent (0.9.4)
|
45
|
+
rb-inotify (0.9.3)
|
46
|
+
ffi (>= 0.5.0)
|
47
|
+
recursive-open-struct (0.4.5)
|
48
|
+
rspec (2.14.1)
|
49
|
+
rspec-core (~> 2.14.0)
|
50
|
+
rspec-expectations (~> 2.14.0)
|
51
|
+
rspec-mocks (~> 2.14.0)
|
52
|
+
rspec-core (2.14.7)
|
53
|
+
rspec-expectations (2.14.4)
|
54
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
55
|
+
rspec-mocks (2.14.4)
|
56
|
+
semantic (1.3.0)
|
57
|
+
slop (3.4.7)
|
58
|
+
terminal-notifier-guard (1.5.3)
|
59
|
+
thor (0.18.1)
|
60
|
+
thread_safe (0.1.3)
|
61
|
+
atomic
|
62
|
+
timers (1.1.0)
|
63
|
+
tzinfo (0.3.38)
|
64
|
+
|
65
|
+
PLATFORMS
|
66
|
+
ruby
|
67
|
+
|
68
|
+
DEPENDENCIES
|
69
|
+
activesupport
|
70
|
+
colorize
|
71
|
+
guard
|
72
|
+
guard-bundler
|
73
|
+
guard-rspec
|
74
|
+
rake
|
75
|
+
recursive-open-struct
|
76
|
+
rspec
|
77
|
+
semantic
|
78
|
+
terminal-notifier-guard
|
79
|
+
thor
|
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# More info at https://github.com/guard/guard#readme
|
2
|
+
|
3
|
+
notification :terminal_notifier, subtitle: 'ruby.gems.new'
|
4
|
+
|
5
|
+
guard :bundler do
|
6
|
+
watch('Gemfile')
|
7
|
+
end
|
8
|
+
|
9
|
+
guard :rspec, all_after_pass: true, all_on_start: true, cmd: 'bundle exec rspec' do
|
10
|
+
watch(%r{^spec/.+_spec\.rb$})
|
11
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
12
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
13
|
+
watch('.rspec') { 'spec' }
|
14
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ryan Brewster
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# new
|
2
|
+
###### install
|
3
|
+
```shell
|
4
|
+
gem install new
|
5
|
+
new init
|
6
|
+
```
|
7
|
+
|
8
|
+
###### Create a new project
|
9
|
+
```shell
|
10
|
+
new [TEMPLATE] [NAME]
|
11
|
+
```
|
12
|
+
|
13
|
+
###### Release a new version
|
14
|
+
```shell
|
15
|
+
new release
|
16
|
+
```
|
17
|
+
|
18
|
+
#### Templates
|
19
|
+
Templates represent a boilerplate directory & file structure preconfigured for a given project type. _(eg js, ruby, gem, rails, etc.)_
|
20
|
+
|
21
|
+
#### Tasks
|
22
|
+
Tasks represent a process associated with releasing new code. Tasks are run in order they are listed in the project `.new` configuration file. _(eg github, gem, etc.)_
|
23
|
+
|
24
|
+
#### Local Config/Templates/Tasks
|
25
|
+
After running `new init`, you will have `.new` folder in your home directory. This directory contains:
|
26
|
+
|
27
|
+
* `.new` local configuration file
|
28
|
+
* `tasks` directory for custom tasks
|
29
|
+
* `templates` directory for custom templates
|
30
|
+
|
31
|
+
Copy or create custom templates & tasks in these folders. They will take precendence over the default templates included with the gem.
|
32
|
+
|
33
|
+
**Make sure to edit your local configuration file!**
|
34
|
+
|
35
|
+
```yaml
|
36
|
+
# ~/.new/.new
|
37
|
+
|
38
|
+
license: MIT
|
39
|
+
developer:
|
40
|
+
name: Foo Bar
|
41
|
+
email: foo@bar.com
|
42
|
+
templates:
|
43
|
+
foo_template:
|
44
|
+
custom: option
|
45
|
+
tasks:
|
46
|
+
github:
|
47
|
+
username: foouser
|
48
|
+
```
|
49
|
+
|
50
|
+
|
51
|
+
#### Custom Templates
|
52
|
+
* The directory name will be used for the template name.
|
53
|
+
* Templates can have a `.new` file in the root of the folder. These values can be accessed through interpolation.
|
54
|
+
|
55
|
+
```yaml
|
56
|
+
# ~/.new/templates/foo_template/.new
|
57
|
+
|
58
|
+
foo: bar
|
59
|
+
tasks:
|
60
|
+
foo_task:
|
61
|
+
bar_task:
|
62
|
+
baz: 'baz'
|
63
|
+
```
|
64
|
+
|
65
|
+
_Note: the tasks are followed by a colon `:` whether they have options or not._
|
66
|
+
|
67
|
+
###### Interpolation
|
68
|
+
Use ERB template syntax in your files to interpolate template options. Make sure to add `.erb` to the end of the filename.
|
69
|
+
|
70
|
+
You can also access any custom values set in your local configuration file.
|
71
|
+
|
72
|
+
```erb
|
73
|
+
<%# ~/.new/templates/foo_template/foo.txt.erb %>
|
74
|
+
|
75
|
+
<%= license %>
|
76
|
+
<%= developer.name %>
|
77
|
+
<%= developer.email %>
|
78
|
+
<%= type %>
|
79
|
+
<%= project_name %>
|
80
|
+
<%= foo %>
|
81
|
+
<%= tasks.bar_task.baz %>
|
82
|
+
```
|
83
|
+
|
84
|
+
You can also interpolate directory and filenames using the syntax `foo_[DEVELOPER.NAME].txt`
|
85
|
+
|
86
|
+
_Note using the dot notation to access nested attributes._
|
87
|
+
|
88
|
+
#### Custom Tasks
|
89
|
+
* The directory name will be used for the task name
|
90
|
+
* A `.rb` file must be included in the directory with the same name
|
91
|
+
* The `.rb` file must contain a class of `New::Task::FooTask` and inherit from `New::Task`
|
92
|
+
* The `.rb` file must have a standard ruby `run` method that will run when a project is released.
|
93
|
+
* A Task can have an `OPTIONS` constant with default options needed for the task to run. These can be further customized in the project or local configuration `.new` file
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# ~/.new/tasks/foo_task/foo_task.rb
|
97
|
+
|
98
|
+
class New::Task::FooTask < New::Test
|
99
|
+
OPTION = {
|
100
|
+
foo: 'bar'
|
101
|
+
}
|
102
|
+
|
103
|
+
def run
|
104
|
+
# do stuff here
|
105
|
+
# access task options from the `options` object
|
106
|
+
# access all project options from the `project_options` object
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
#### TODO
|
112
|
+
* optional scripts when creating a template
|
113
|
+
* write templates
|
114
|
+
* write tasks
|
115
|
+
|
116
|
+
#### Contributing
|
117
|
+
1. Fork it ( http://github.com/brewster1134/new/fork )
|
118
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
119
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
120
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
121
|
+
5. Create new Pull Request
|
data/bin/new
ADDED
data/lib/new/cli.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class New::Cli < Thor
|
5
|
+
desc '[TEMPLATE] [NAME]', "Create a new project with a given template (#{New.templates.join(' ')})"
|
6
|
+
# option :name, required: true
|
7
|
+
def method_missing method, *args
|
8
|
+
if New.templates.include? method.to_sym
|
9
|
+
# Split args that look like options (i.e start with - or --) into a separate array
|
10
|
+
positional_args, opts = Thor::Options.split args
|
11
|
+
|
12
|
+
# extract name from args
|
13
|
+
name = positional_args[0]
|
14
|
+
raise Thor::RequiredArgumentMissingError unless name
|
15
|
+
|
16
|
+
# Add all options here
|
17
|
+
# Make sure to include required options up above as well so they show in the help menu
|
18
|
+
parser = Thor::Options.new(
|
19
|
+
# name: Thor::Option.new(:name, required: true, type: :string)
|
20
|
+
)
|
21
|
+
|
22
|
+
# The options hash is frozen in #initialize so you need to merge and re-assign
|
23
|
+
self.options = options.merge(parser.parse(opts)).freeze
|
24
|
+
|
25
|
+
# Dispatch the command
|
26
|
+
project method, name
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'init', 'Set up your home directory folder for storing custom templates and default configuration'
|
33
|
+
def init
|
34
|
+
if Dir.exists? New::CUSTOM_DIR
|
35
|
+
New.say 'Home folder already exists.', type: :warn
|
36
|
+
else
|
37
|
+
# create folder
|
38
|
+
New.say 'Creating home folder.', type: :success
|
39
|
+
FileUtils.mkdir_p New::CUSTOM_DIR
|
40
|
+
FileUtils.mkdir_p File.join(New::CUSTOM_DIR, New::TASKS_DIR_NAME)
|
41
|
+
FileUtils.mkdir_p File.join(New::CUSTOM_DIR, New::TEMPLATES_DIR_NAME)
|
42
|
+
|
43
|
+
# create config file
|
44
|
+
New.say 'Creating default configuration file.', type: :success
|
45
|
+
File.open File.join(New::CUSTOM_DIR, New::CONFIG_FILE), 'w' do |f|
|
46
|
+
f.write New::Template::CUSTOM_CONFIG_TEMPLATE.to_yaml
|
47
|
+
end
|
48
|
+
|
49
|
+
New.say "Edit #{File.join(New::CUSTOM_DIR, New::CONFIG_FILE)} with your custom configuration details.", type: :warn
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'release', 'Release your new code (Run from within a project directory!)'
|
54
|
+
def release
|
55
|
+
project_config_file = File.join(Dir.pwd, New::CONFIG_FILE)
|
56
|
+
raise unless File.exists? project_config_file
|
57
|
+
|
58
|
+
# get project config file
|
59
|
+
project_config = YAML.load(File.open(project_config_file)).deep_symbolize_keys!
|
60
|
+
|
61
|
+
# extract tasks from configuration
|
62
|
+
tasks = (project_config[:tasks] || {}).keys.map(&:to_sym)
|
63
|
+
|
64
|
+
tasks.each do |task|
|
65
|
+
# require custom task and initialize it
|
66
|
+
begin
|
67
|
+
if New.custom_tasks.include? task
|
68
|
+
require "#{New::CUSTOM_DIR}/#{New::TASKS_DIR_NAME}/#{task}/#{task}"
|
69
|
+
else
|
70
|
+
require "#{New::DEFAULT_DIR}/#{New::TASKS_DIR_NAME}/#{task}/#{task}"
|
71
|
+
end
|
72
|
+
rescue LoadError
|
73
|
+
New.say "No task '#{task}' found!", type: :fail
|
74
|
+
next
|
75
|
+
end
|
76
|
+
"New::Task::#{task.to_s.classify}".constantize.new project_config
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def project template, name
|
83
|
+
if Dir.exists? File.join(Dir.pwd, name)
|
84
|
+
New.say "A project named #{name} already exists...", type: :warn
|
85
|
+
New.say " Overwrite it? [Yn]", type: :warn
|
86
|
+
exit if STDIN.gets.chomp! != 'Y'
|
87
|
+
|
88
|
+
# Delete existing project
|
89
|
+
FileUtils.rm_rf File.join(Dir.pwd, name)
|
90
|
+
end
|
91
|
+
|
92
|
+
New::Project.new template, name
|
93
|
+
end
|
94
|
+
end
|
data/lib/new/core.rb
ADDED
data/lib/new/dsl.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module New::Dsl
|
2
|
+
# Replacement for `puts` that accepts various stylistic arguments
|
3
|
+
# https://github.com/fazibear/colorize/blob/master/lib/colorize.rb
|
4
|
+
#
|
5
|
+
# justify: => [center|ljust|rjust] The type of justification to use
|
6
|
+
# padding: => [integer] The maximum string size to justify text in
|
7
|
+
# color: => [integer] See link above for supported colors
|
8
|
+
# bgcolor: => [integer] See link above for supported colors
|
9
|
+
# type: => [symbol] Preset colors for [:fail, :success, :warn]
|
10
|
+
#
|
11
|
+
def say text = '', args = {}
|
12
|
+
# Justify options
|
13
|
+
if args[:justify] && args[:padding]
|
14
|
+
text = text.send args[:justify], args[:padding]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Color text
|
18
|
+
text = text.colorize(color: args[:color]) if args[:color]
|
19
|
+
|
20
|
+
# Color background
|
21
|
+
text = text.colorize(background: args[:bgcolor]) if args[:bgcolor]
|
22
|
+
|
23
|
+
# Type options
|
24
|
+
# process last due to the addition of special color codes
|
25
|
+
text = case args[:type]
|
26
|
+
when :fail
|
27
|
+
text.red
|
28
|
+
when :success
|
29
|
+
text.green
|
30
|
+
when :warn
|
31
|
+
text.yellow
|
32
|
+
else
|
33
|
+
text
|
34
|
+
end
|
35
|
+
|
36
|
+
if args[:indent]
|
37
|
+
text = (' ' * args[:indent]) + text
|
38
|
+
end
|
39
|
+
|
40
|
+
puts text
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'recursive-open-struct'
|
3
|
+
|
4
|
+
module New::Interpolate
|
5
|
+
# regex to match capital underscored template options names ie [PROJECT_NAME]
|
6
|
+
FILENAME_RENAME_MATCH = /\[([A-Z_.]+)\]/
|
7
|
+
|
8
|
+
# Convienance method for processing everything
|
9
|
+
#
|
10
|
+
def interpolate src_path, options
|
11
|
+
@src_path = src_path
|
12
|
+
@options = options
|
13
|
+
|
14
|
+
copy_to_tmp
|
15
|
+
process_paths
|
16
|
+
process_files
|
17
|
+
end
|
18
|
+
|
19
|
+
def dir; @dest_path; end
|
20
|
+
|
21
|
+
# Convert options to OpenStruct so we can use dot notation in the templates
|
22
|
+
#
|
23
|
+
def dot_options
|
24
|
+
@dot_options ||= RecursiveOpenStruct.new(@options)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Allow templates to call option values directly
|
30
|
+
#
|
31
|
+
def method_missing method
|
32
|
+
dot_options.send(method.to_sym) || super
|
33
|
+
end
|
34
|
+
|
35
|
+
def copy_to_tmp
|
36
|
+
# Create a unique temporary path to store the processed files
|
37
|
+
@dest_path = File.join(New::TEMP_DIR, Time.now.to_i.to_s)
|
38
|
+
|
39
|
+
# Create a directory if an individual file is being processed
|
40
|
+
FileUtils.mkdir_p @dest_path if File.file? @src_path
|
41
|
+
|
42
|
+
# Copy to tmp
|
43
|
+
FileUtils.cp_r @src_path, @dest_path
|
44
|
+
end
|
45
|
+
|
46
|
+
# Collect files with a matching value to interpolate
|
47
|
+
#
|
48
|
+
def process_paths
|
49
|
+
get_path = -> type do
|
50
|
+
Dir.glob(File.join(@dest_path, '**/*')).select do |e|
|
51
|
+
File.send("#{type}?".to_sym, e) && e =~ FILENAME_RENAME_MATCH
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# rename directories first
|
56
|
+
get_path[:directory].each{ |dir| process_path dir }
|
57
|
+
get_path[:file].each{ |file| process_path file }
|
58
|
+
end
|
59
|
+
|
60
|
+
# Interpolate filenames with template options
|
61
|
+
#
|
62
|
+
def process_path path
|
63
|
+
new_path = path.gsub FILENAME_RENAME_MATCH do
|
64
|
+
# Extract interpolated values into symbols
|
65
|
+
methods = $1.downcase.split('.').map(&:to_sym)
|
66
|
+
|
67
|
+
# Call each method on options
|
68
|
+
methods.inject(dot_options){ |options, method| options.send(method.to_sym) }
|
69
|
+
end
|
70
|
+
|
71
|
+
if File.file? path
|
72
|
+
File.rename path, new_path
|
73
|
+
else
|
74
|
+
FileUtils.mv path, new_path
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Collect files with an .erb extension to interpolate
|
79
|
+
#
|
80
|
+
def process_files
|
81
|
+
Dir.glob(File.join(@dest_path, '**/*.erb'), File::FNM_DOTMATCH).each do |file|
|
82
|
+
process_file file
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Interpolate erb template data
|
87
|
+
#
|
88
|
+
def process_file file
|
89
|
+
# Process the erb file
|
90
|
+
processed_file = ERB.new(File.read(file)).result(binding)
|
91
|
+
|
92
|
+
# Overwrite the original file with the processed file
|
93
|
+
File.open file, 'w' do |f|
|
94
|
+
f.write processed_file
|
95
|
+
end
|
96
|
+
|
97
|
+
# Remove the .erb from the file name
|
98
|
+
File.rename file, file.chomp('.erb')
|
99
|
+
end
|
100
|
+
end
|
data/lib/new/project.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
class New::Project
|
2
|
+
include New::Version
|
3
|
+
|
4
|
+
# Create all variables and run new project creation methods
|
5
|
+
#
|
6
|
+
def initialize template, name
|
7
|
+
@project_dir = File.join(Dir.pwd, name.to_s) # the newly created project directory
|
8
|
+
@template = New::Template.new template, name
|
9
|
+
|
10
|
+
copy_template
|
11
|
+
create_config_file
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Create the new project by copying the template directory
|
17
|
+
#
|
18
|
+
def copy_template
|
19
|
+
FileUtils.cp_r @template.dir, @project_dir
|
20
|
+
|
21
|
+
# cleanup tmp
|
22
|
+
FileUtils.rm_rf @template.dir
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create the .new configuration file in the new project
|
26
|
+
#
|
27
|
+
def create_config_file
|
28
|
+
new_config = File.join(@project_dir, New::CONFIG_FILE)
|
29
|
+
File.open new_config, 'w' do |f|
|
30
|
+
yaml_options = @template.options.deep_dup.deep_stringify_keys!.to_yaml
|
31
|
+
f.write(yaml_options)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/new/task.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class New::Task
|
4
|
+
def self.inherited task_class
|
5
|
+
task_class.name = caller.first[/[a-z_]+?(?=\.rb)/].to_sym
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize project_config
|
9
|
+
@project_config = project_config
|
10
|
+
run
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.name= name
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
def self.name; @name; end
|
17
|
+
def name; self.class.name.to_sym; end
|
18
|
+
|
19
|
+
# Return ALL available options
|
20
|
+
#
|
21
|
+
def project_options
|
22
|
+
custom_options = New.custom_config
|
23
|
+
project_options = @project_config
|
24
|
+
|
25
|
+
all_options = custom_options.deep_merge(project_options)
|
26
|
+
|
27
|
+
# Groom tasks (prevent tasks from the custom config from polluting the project config)
|
28
|
+
all_options[:tasks].each_key do |task|
|
29
|
+
all_options[:tasks].delete(task) unless project_options[:tasks].has_key?(task)
|
30
|
+
end
|
31
|
+
|
32
|
+
@project_options ||= all_options
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return only the options for the given task
|
36
|
+
#
|
37
|
+
def options
|
38
|
+
default_options = self.class::OPTIONS rescue {}
|
39
|
+
@options ||= default_options.deep_merge(project_options[:tasks][name])
|
40
|
+
end
|
41
|
+
end
|
data/lib/new/template.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class New::Template
|
4
|
+
include New::Interpolate
|
5
|
+
|
6
|
+
# The foundation for new template configuration files
|
7
|
+
#
|
8
|
+
CUSTOM_CONFIG_TEMPLATE = {
|
9
|
+
license: '[LICENSE]',
|
10
|
+
version: '[VERSION]',
|
11
|
+
developer: {
|
12
|
+
name: '[NAME]',
|
13
|
+
email: '[EMAIL]'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize type, name
|
18
|
+
@type = type
|
19
|
+
@name = name
|
20
|
+
|
21
|
+
interpolate template_dir, options
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create the options object
|
25
|
+
#
|
26
|
+
def options
|
27
|
+
# merge options together
|
28
|
+
CUSTOM_CONFIG_TEMPLATE.clone
|
29
|
+
.deep_merge!(template_config)
|
30
|
+
.deep_merge!(New.custom_config)
|
31
|
+
.deep_merge!({
|
32
|
+
project_name: @name,
|
33
|
+
type: @type.to_s
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Get the template directory to copy from
|
40
|
+
#
|
41
|
+
def template_dir
|
42
|
+
@template_dir ||= if New.custom_templates.include? @type
|
43
|
+
@custom = true
|
44
|
+
File.join(New::CUSTOM_DIR, New::TEMPLATES_DIR_NAME, @type.to_s)
|
45
|
+
else
|
46
|
+
File.join(New::DEFAULT_DIR, New::TEMPLATES_DIR_NAME, @type.to_s)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get the configuration for the template
|
51
|
+
#
|
52
|
+
def template_config
|
53
|
+
return @template_config if @template_config
|
54
|
+
|
55
|
+
@template_config = YAML.load(File.open(File.join(template_dir, New::CONFIG_FILE))).deep_symbolize_keys! rescue {}
|
56
|
+
if @custom
|
57
|
+
@template_config.merge!({
|
58
|
+
custom: true
|
59
|
+
})
|
60
|
+
end
|
61
|
+
|
62
|
+
@template_config
|
63
|
+
end
|
64
|
+
end
|