skeletor 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +22 -0
- data/bin/skeletor +6 -0
- data/lib/skeletor.rb +9 -0
- data/lib/skeletor/builder.rb +129 -0
- data/lib/skeletor/cli.rb +40 -0
- data/lib/skeletor/includes.rb +49 -0
- data/lib/skeletor/protocols/http.rb +2 -0
- data/lib/skeletor/protocols/https.rb +3 -0
- data/lib/skeletor/skeletons.rb +9 -0
- data/lib/skeletor/skeletons/loader.rb +47 -0
- data/lib/skeletor/skeletons/skeleton.rb +47 -0
- data/lib/skeletor/skeletons/validator.rb +169 -0
- data/lib/skeletor/tasks.rb +16 -0
- data/lib/skeletor/templates/js-lib/js-lib.yml +14 -0
- data/lib/skeletor/templates/template-schema.yml +38 -0
- data/lib/skeletor/version.rb +3 -0
- metadata +92 -0
data/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Skeletor
|
2
|
+
========
|
3
|
+
|
4
|
+
Skeletor is a Ruby Library for setting up quick project skeletons based on code templates.
|
5
|
+
|
6
|
+
Contributing to Skeletor
|
7
|
+
------------------------
|
8
|
+
|
9
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
10
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
11
|
+
* Fork the project
|
12
|
+
* Start a feature/bugfix branch
|
13
|
+
* Commit and push until you are happy with your contribution
|
14
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
15
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
16
|
+
|
17
|
+
Copyright
|
18
|
+
---------
|
19
|
+
|
20
|
+
Copyright (c) 2011 OiNutter. See LICENSE.txt for
|
21
|
+
further details.
|
22
|
+
|
data/bin/skeletor
ADDED
data/lib/skeletor.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Skeletor
|
4
|
+
|
5
|
+
class Builder
|
6
|
+
|
7
|
+
def initialize(project,template,path)
|
8
|
+
|
9
|
+
@project = project
|
10
|
+
@template_name = File.basename(template).gsub('.yml','')
|
11
|
+
@template = Skeletons::Skeleton.new(template)
|
12
|
+
@path = path
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def build()
|
17
|
+
|
18
|
+
#check dir exists, if not, make it
|
19
|
+
if(!File.exists?(@path))
|
20
|
+
Dir.mkdir(@path)
|
21
|
+
end
|
22
|
+
|
23
|
+
#build directory structure
|
24
|
+
puts 'Building directory structure'
|
25
|
+
build_skeleton(@template.directory_structure)
|
26
|
+
|
27
|
+
#execute build tasks
|
28
|
+
puts 'Running build tasks'
|
29
|
+
execute_tasks(@template.tasks,@template.path)
|
30
|
+
|
31
|
+
puts 'Skeleton built'
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_skeleton(dirs,path=@path)
|
36
|
+
|
37
|
+
dirs.each{
|
38
|
+
|node|
|
39
|
+
|
40
|
+
if node.kind_of?(Hash) && !node.empty?()
|
41
|
+
node.each_pair{
|
42
|
+
|dir,content|
|
43
|
+
|
44
|
+
puts 'Creating directory ' + File.join(path,dir)
|
45
|
+
Dir.mkdir(File.join(path,dir))
|
46
|
+
|
47
|
+
if content.kind_of?(Array) && !content.empty?()
|
48
|
+
build_skeleton(content,File.join(path,dir))
|
49
|
+
end
|
50
|
+
|
51
|
+
}
|
52
|
+
elsif node.kind_of?(Array) && !node.empty?()
|
53
|
+
node.each{
|
54
|
+
|file|
|
55
|
+
|
56
|
+
write_file(file,path)
|
57
|
+
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
}
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.clean(path=@path)
|
66
|
+
|
67
|
+
puts 'Cleaning directory of files and folders'
|
68
|
+
start_dir = Dir.new(path)
|
69
|
+
|
70
|
+
start_dir.each{
|
71
|
+
|dir|
|
72
|
+
|
73
|
+
if dir != '.' && dir != '..'
|
74
|
+
FileUtils.rm_r File.join(path,dir), {:secure=>true}
|
75
|
+
end
|
76
|
+
|
77
|
+
}
|
78
|
+
puts 'Directory cleaned'
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
def write_file(file,path)
|
83
|
+
|
84
|
+
#if a pre-existing file is specified in the includes list, copy that, if not write a blank file
|
85
|
+
if @template.includes.has_key?(file)
|
86
|
+
begin
|
87
|
+
Includes.copy_include(@template.includes[file],File.join(path,file),@template.path)
|
88
|
+
rescue TypeError => e
|
89
|
+
puts e.message
|
90
|
+
exit
|
91
|
+
end
|
92
|
+
else
|
93
|
+
puts 'Creating blank file: ' + File.join(path,file)
|
94
|
+
File.open(File.join(path,file),'w')
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
def execute_tasks(tasks,template_path)
|
100
|
+
|
101
|
+
if File.exists?(File.expand_path(File.join(template_path,'tasks.rb')))
|
102
|
+
load File.expand_path(File.join(template_path,'tasks.rb'))
|
103
|
+
end
|
104
|
+
|
105
|
+
tasks.each{
|
106
|
+
|task|
|
107
|
+
|
108
|
+
puts 'Running Task: ' + task
|
109
|
+
|
110
|
+
task = task.gsub('<skeleton_path>',@path)
|
111
|
+
task = task.gsub('<skeleton_project>',@project)
|
112
|
+
task = task.gsub('<skelton_template>',@template_name)
|
113
|
+
|
114
|
+
options = task.split(', ')
|
115
|
+
action = options.slice!(0)
|
116
|
+
|
117
|
+
if(Tasks.respond_to?(action))
|
118
|
+
Tasks.send action, options.join(', ')
|
119
|
+
else
|
120
|
+
send action, options.join(', ')
|
121
|
+
end
|
122
|
+
|
123
|
+
}
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
data/lib/skeletor/cli.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Skeletor
|
4
|
+
|
5
|
+
class CLI < Thor
|
6
|
+
|
7
|
+
desc "build TEMPLATE [options]", "Build project skeleton from TEMPLATE"
|
8
|
+
method_option :directory,
|
9
|
+
:aliases => "-d",
|
10
|
+
:desc => "Sets the target directory. Defaults to current directory."
|
11
|
+
method_option :project,
|
12
|
+
:aliases => "-p",
|
13
|
+
:desc => "Sets the project name. Defaults to current directory name."
|
14
|
+
def build(template)
|
15
|
+
path = options[:directory] || Dir.pwd
|
16
|
+
project = options[:project] || File.basename(path)
|
17
|
+
|
18
|
+
skeleton = Builder.new(project,template,path)
|
19
|
+
skeleton.build
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "clean [options]" ,"Clean directory"
|
23
|
+
method_option :directory,
|
24
|
+
:aliases => "-d",
|
25
|
+
:desc => "Sets the target directory. Defaults to current directory"
|
26
|
+
def clean
|
27
|
+
path = options[:directory] || Dir.pwd
|
28
|
+
Builder.clean path
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "validate TEMPLATE" ,"Checks TEMPLATE is a valid YAML file and matches the required schema."
|
32
|
+
def validate(template)
|
33
|
+
skeleton = Skeletons::Loader.loadTemplate(template)
|
34
|
+
validator = Skeletons::Validator.new(skeleton)
|
35
|
+
validator.validate()
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
autoload :HTTP, 'skeletor/protocols/http'
|
4
|
+
autoload :HTTPS, 'skeletor/protocols/https'
|
5
|
+
|
6
|
+
module Skeletor
|
7
|
+
|
8
|
+
class Includes
|
9
|
+
|
10
|
+
PROTOCOL_PATTERN = /(?:([a-z][\w-]+):(?:\/{1,3}|[a-z0-9%]))/
|
11
|
+
SUPPORTED_PROTOCOLS = ['http','https']
|
12
|
+
|
13
|
+
def self.copy_include(include,target,path)
|
14
|
+
|
15
|
+
#if include path includes a protocol. Load from that
|
16
|
+
matches = PROTOCOL_PATTERN.match(include).to_a
|
17
|
+
if !matches.empty?
|
18
|
+
protocol = matches[1].to_s.downcase
|
19
|
+
if !SUPPORTED_PROTOCOLS.find_index(protocol).nil?
|
20
|
+
case protocol
|
21
|
+
when 'http'
|
22
|
+
content = HTTP.get URI.parse(include)
|
23
|
+
when 'https'
|
24
|
+
uri = URI.parse(include)
|
25
|
+
http = HTTPS.new uri.host,443
|
26
|
+
http.use_ssl = true
|
27
|
+
req = HTTPS::Get.new uri.path
|
28
|
+
request = http.request(req)
|
29
|
+
content = request.body
|
30
|
+
else
|
31
|
+
raise TypeError, 'Unsupported protocol ' + protocol + ' for remote file. Only the following are supported: ' + SUPPORTED_PROTOCOLS.join(', ')
|
32
|
+
end
|
33
|
+
puts 'Copying remote file ' + include + ' to ' + target
|
34
|
+
else
|
35
|
+
raise TypeError, 'Unsupported protocol for remote file. Only the following are supported: ' + SUPPORTED_PROTOCOLS.join(', ')
|
36
|
+
end
|
37
|
+
else
|
38
|
+
puts 'Copying ' + include + ' from template directory to ' + target
|
39
|
+
file = File.open(File.join(path,include))
|
40
|
+
content = file.gets
|
41
|
+
end
|
42
|
+
|
43
|
+
File.open(target,'w'){|f| f.write(content)}
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'YAML'
|
2
|
+
|
3
|
+
module Skeletor
|
4
|
+
|
5
|
+
module Skeletons
|
6
|
+
|
7
|
+
class Loader
|
8
|
+
|
9
|
+
TEMPLATE_PATH = File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), "templates"))
|
10
|
+
USER_TEMPLATE_PATH = File.expand_path('~/.skeletor/templates')
|
11
|
+
|
12
|
+
def self.loadTemplate(template)
|
13
|
+
|
14
|
+
puts 'Loading Template - ' + template
|
15
|
+
|
16
|
+
if File.exists?(template) && !File.directory?(template)
|
17
|
+
skeleton = YAML.load_file(template)
|
18
|
+
path = File.dirname(template)
|
19
|
+
elsif File.exists?(File.join(template,File.basename(template) + '.yml'))
|
20
|
+
skeleton = YAML.load_file(File.join(template,File.basename(template) + '.yml'))
|
21
|
+
path = template
|
22
|
+
elsif File.exists?(File.join(USER_TEMPLATE_PATH,template,template+'.yml'))
|
23
|
+
skeleton = YAML.load_file(File.join(USER_TEMPLATE_PATH,template,template+'.yml'))
|
24
|
+
path = File.join(USER_TEMPLATE_PATH,template)
|
25
|
+
elsif File.exists?(File.join(TEMPLATE_PATH,template,template+'.yml'))
|
26
|
+
skeleton = YAML.load_file(File.join(TEMPLATE_PATH,template,template+'.yml'))
|
27
|
+
path = File.join(TEMPLATE_PATH,template)
|
28
|
+
else
|
29
|
+
raise LoadError, 'Error: Template File ' + File.basename(template) + ' Could Not Be Found'
|
30
|
+
end
|
31
|
+
|
32
|
+
puts 'Template ' + File.basename(template) + '.yml loaded from ' + path
|
33
|
+
if skeleton
|
34
|
+
skeleton['path'] = path
|
35
|
+
else
|
36
|
+
raise LoadError, 'Error: Template could not be parsed as vald YAML'
|
37
|
+
end
|
38
|
+
|
39
|
+
return skeleton
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Skeletor
|
2
|
+
|
3
|
+
module Skeletons
|
4
|
+
|
5
|
+
class Skeleton
|
6
|
+
|
7
|
+
def initialize(template)
|
8
|
+
|
9
|
+
begin
|
10
|
+
@template = Loader.loadTemplate(template)
|
11
|
+
validator = Validator.new(@template)
|
12
|
+
if validator.validate
|
13
|
+
@directory_structure = @template["directory_structure"] || []
|
14
|
+
@tasks = @template["tasks"] || {}
|
15
|
+
@includes = @template["includes"] || {}
|
16
|
+
@path = @template["path"]
|
17
|
+
else
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
rescue LoadError => e
|
21
|
+
puts e.message
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
def directory_structure
|
28
|
+
@directory_structure
|
29
|
+
end
|
30
|
+
|
31
|
+
def tasks
|
32
|
+
@tasks
|
33
|
+
end
|
34
|
+
|
35
|
+
def includes
|
36
|
+
@includes
|
37
|
+
end
|
38
|
+
|
39
|
+
def path
|
40
|
+
@path
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module Skeletor
|
2
|
+
|
3
|
+
module Skeletons
|
4
|
+
|
5
|
+
class Validator
|
6
|
+
|
7
|
+
SCHEMA_FILE = File.join Skeletons::Loader::TEMPLATE_PATH,'template-schema.yml'
|
8
|
+
|
9
|
+
def initialize(template,schema=SCHEMA_FILE)
|
10
|
+
@errors = []
|
11
|
+
@template = template
|
12
|
+
@schema = Loader.loadTemplate(schema)
|
13
|
+
@types = @schema['types'] || {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate()
|
17
|
+
failed = []
|
18
|
+
|
19
|
+
@schema['sections'].each{
|
20
|
+
|section|
|
21
|
+
|
22
|
+
#check required sections are there
|
23
|
+
if (section['required'] && !@template.has_key?(section['name']))
|
24
|
+
@errors.push('Error: missing required section - ' + section['name'])
|
25
|
+
failed.push(section['name'])
|
26
|
+
elsif @template.has_key?(section['name'])
|
27
|
+
node = @template[section['name']]
|
28
|
+
validated = match_node(node,section,section['name'])
|
29
|
+
if(!validated)
|
30
|
+
failed.push(section['name'])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
}
|
35
|
+
|
36
|
+
puts 'Result: ' + (failed.empty? ? 'Validated Successfully!' : 'Validation Failed!')
|
37
|
+
|
38
|
+
if !failed.empty? && !@errors.empty?
|
39
|
+
puts 'Validation Failed with ' + @errors.count.to_s + ' errors';
|
40
|
+
puts ''
|
41
|
+
@errors.each{
|
42
|
+
|error|
|
43
|
+
puts error
|
44
|
+
}
|
45
|
+
return false
|
46
|
+
else
|
47
|
+
return true
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
def match_node(node,expected,label)
|
53
|
+
|
54
|
+
#check type
|
55
|
+
if !check_type(node,expected['type'],label,expected['ok_empty'])
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
|
59
|
+
if (node.kind_of?(Hash) || node.kind_of?(Array))
|
60
|
+
|
61
|
+
if node.empty? && !expected['ok_empty']
|
62
|
+
@errors.push('Error: node ' + label + ' cannot be empty')
|
63
|
+
return false
|
64
|
+
elsif !node.empty? && expected.has_key?('accepts')
|
65
|
+
valid_content = false
|
66
|
+
|
67
|
+
if node.kind_of?(Hash)
|
68
|
+
matched = []
|
69
|
+
unmatched = []
|
70
|
+
node.each_pair{
|
71
|
+
|key,value|
|
72
|
+
|
73
|
+
expected['accepts'].each{
|
74
|
+
|accepts|
|
75
|
+
|
76
|
+
result = check_type(value,accepts,key)
|
77
|
+
|
78
|
+
if result
|
79
|
+
matched.push(key)
|
80
|
+
if !unmatched.find_index(key).nil?
|
81
|
+
unmatched.slice(unmatched.find_index(key))
|
82
|
+
end
|
83
|
+
break
|
84
|
+
else
|
85
|
+
unmatched.push(key)
|
86
|
+
end
|
87
|
+
|
88
|
+
}
|
89
|
+
|
90
|
+
}
|
91
|
+
|
92
|
+
if(matched.count==node.count)
|
93
|
+
valid_content = true
|
94
|
+
else
|
95
|
+
unmatched.each{
|
96
|
+
|node|
|
97
|
+
|
98
|
+
@errors.push('Error: node ' + node + ' is not of an accepted type. Should be one of ' + expected['accepts'].join(', '))
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
elsif node.kind_of?(Array)
|
103
|
+
matched = []
|
104
|
+
unmatched = []
|
105
|
+
node.each_index{
|
106
|
+
|n|
|
107
|
+
|
108
|
+
expected['accepts'].each{
|
109
|
+
|accepts|
|
110
|
+
|
111
|
+
key = label + '[' + n.to_s + ']'
|
112
|
+
result = check_type(node[n],accepts,key)
|
113
|
+
|
114
|
+
if result
|
115
|
+
|
116
|
+
matched.push(key)
|
117
|
+
if !unmatched.find_index(key).nil?
|
118
|
+
unmatched.slice(unmatched.find_index(key))
|
119
|
+
end
|
120
|
+
break
|
121
|
+
else
|
122
|
+
unmatched.push(key)
|
123
|
+
end
|
124
|
+
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
if(matched.count==node.count)
|
129
|
+
valid_content = true
|
130
|
+
else
|
131
|
+
unmatched.each{
|
132
|
+
|node|
|
133
|
+
|
134
|
+
@errors.push('Error: node ' + node + ' is not of an accepted type. Should be one of ' + expected['accepts'].join(', '))
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
if !valid_content
|
141
|
+
@errors.push('Error: node ' + label + ' contains an unaccepted type.')
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
return true
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
def check_type(node,expected_type,label,accept_nil = false)
|
153
|
+
|
154
|
+
valid_type = true;
|
155
|
+
if(@types.has_key?(expected_type))
|
156
|
+
valid_type = match_node(node,@types[expected_type],label)
|
157
|
+
elsif node.class.to_s != expected_type && !(node.kind_of?(NilClass) && (expected_type=='empty' || accept_nil))
|
158
|
+
valid_type = false
|
159
|
+
end
|
160
|
+
|
161
|
+
return valid_type
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
sections:
|
2
|
+
- name: directory_structure
|
3
|
+
required: yes
|
4
|
+
type: Array
|
5
|
+
ok_empty: yes
|
6
|
+
accepts:
|
7
|
+
- directory_list
|
8
|
+
- file_list
|
9
|
+
- name: tasks
|
10
|
+
required: no
|
11
|
+
type: Array
|
12
|
+
accepts:
|
13
|
+
- String
|
14
|
+
- name: includes
|
15
|
+
required: no
|
16
|
+
type: Hash
|
17
|
+
accepts:
|
18
|
+
- String
|
19
|
+
types:
|
20
|
+
directory_list:
|
21
|
+
type: Hash
|
22
|
+
ok_empty: no
|
23
|
+
accepts:
|
24
|
+
- directory
|
25
|
+
file_list:
|
26
|
+
type: Array
|
27
|
+
ok_empty: no
|
28
|
+
accepts:
|
29
|
+
- file
|
30
|
+
directory:
|
31
|
+
type: Array
|
32
|
+
ok_empty: yes
|
33
|
+
accepts:
|
34
|
+
- empty
|
35
|
+
- directory_list
|
36
|
+
- file_list
|
37
|
+
file:
|
38
|
+
type: String
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: skeletor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 6
|
8
|
+
- 1
|
9
|
+
version: 0.6.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Will McKenzie
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-09-25 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: thor
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
description: Skeletor is a Ruby Gem for creating skeleton directory structures based on a YAML template.
|
34
|
+
email:
|
35
|
+
- will@oinutter.co.uk
|
36
|
+
executables:
|
37
|
+
- skeletor
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- README.md
|
44
|
+
- lib/skeletor/builder.rb
|
45
|
+
- lib/skeletor/cli.rb
|
46
|
+
- lib/skeletor/includes.rb
|
47
|
+
- lib/skeletor/protocols/http.rb
|
48
|
+
- lib/skeletor/protocols/https.rb
|
49
|
+
- lib/skeletor/skeletons/loader.rb
|
50
|
+
- lib/skeletor/skeletons/skeleton.rb
|
51
|
+
- lib/skeletor/skeletons/validator.rb
|
52
|
+
- lib/skeletor/skeletons.rb
|
53
|
+
- lib/skeletor/tasks.rb
|
54
|
+
- lib/skeletor/version.rb
|
55
|
+
- lib/skeletor.rb
|
56
|
+
- bin/skeletor
|
57
|
+
- lib/skeletor/templates/js-lib/js-lib.yml
|
58
|
+
- lib/skeletor/templates/template-schema.yml
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/OiNutter/skeletor
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
requirements: []
|
85
|
+
|
86
|
+
rubyforge_project: skeletor
|
87
|
+
rubygems_version: 1.3.7
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: Gem for creating project skeletons based on YAML templates
|
91
|
+
test_files: []
|
92
|
+
|