neptune_coffee 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -22
- data/Rakefile +14 -0
- data/examples/after/geometry/namespace.js +11 -0
- data/examples/after/geometry/solids/namespace.js +8 -0
- data/examples/after/geometry/solids.js +7 -0
- data/examples/after/geometry.js +9 -0
- data/examples/after/namespace.js +11 -0
- data/examples/before/geometry/box.js +4 -0
- data/examples/before/geometry/circle.js +4 -0
- data/examples/before/geometry/solids/cone.js +4 -0
- data/lib/neptune_coffee/generator.rb +44 -143
- data/lib/neptune_coffee/guard.rb +13 -0
- data/lib/neptune_coffee/javascript_generator.rb +51 -0
- data/lib/neptune_coffee/simple_directory_structure.rb +46 -0
- data/lib/neptune_coffee/util.rb +24 -0
- data/lib/neptune_coffee/version.rb +1 -1
- data/lib/neptune_coffee.rb +6 -4
- data/neptune_coffee.gemspec +5 -4
- data/spec/generator_spec.rb +29 -0
- data/spec/javascript_generator_spec.rb +70 -0
- data/spec/simple_directory_structure_spec.rb +34 -0
- data/spec/util_spec.rb +39 -0
- metadata +45 -18
- data/examples/geometry/namespace.js +0 -2
- data/examples/geometry/neptune.js +0 -8
- data/examples/geometry/solids/namespace.js +0 -8
- data/examples/geometry/solids/neptune.js +0 -6
- data/examples/geometry/solids.js +0 -8
- data/examples/geometry.js +0 -10
- /data/examples/{geometry → after/geometry}/box.js +0 -0
- /data/examples/{geometry → after/geometry}/circle.js +0 -0
- /data/examples/{geometry → after/geometry}/solids/cone.js +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3bf480ad75d53f487a64adf993fff7ad3392c54
|
4
|
+
data.tar.gz: 17f93ddd45dd00c50289bf0723a6384e40a29f00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5cd0385135c576572689bf3afc7ac557e16ca0fa091bc42a4fe7da26860ef3fdead7596be370e356dd677a8ae7a4b811d137834629fd8e49f31c73323be9e15
|
7
|
+
data.tar.gz: 6223ffaf80634ccd66ad3bf8dbe1f3a0c6a55ff055314359a7c31ac987908c95750a5910b65188982391b4e155f2d1c125dcdc5128355a49aa054b7ef02c1c0c
|
data/README.md
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# NeptuneCoffee
|
2
2
|
|
3
|
-
## WORK IN PROGRESS
|
4
|
-
This is a work in progress. The basic idea of directories-define-modules is core, as is including the directory_name.js file to included the module. However, the other generated files are still experimental as-is the requirements pattern for module internals.
|
5
|
-
|
6
3
|
## What is it?
|
7
4
|
|
8
5
|
* opinionated javascript-AMD-module generator
|
@@ -12,14 +9,15 @@ This is a work in progress. The basic idea of directories-define-modules is core
|
|
12
9
|
* make working with javascript AMD modules easier
|
13
10
|
* minimize refactoring complexity
|
14
11
|
* minimize the amount of code you have to write
|
12
|
+
* integrate easily with javascript or coffeescript projects
|
15
13
|
|
16
|
-
If you are working with dozens or hundreds of Javascript files, wouldn't you like some way to easily organize them into modules?
|
14
|
+
If you are working with dozens or hundreds of Javascript files, wouldn't you like some way to easily organize them into modules?
|
17
15
|
|
18
|
-
NeptuneCoffee is an opinionated module generator.
|
16
|
+
NeptuneCoffee is an opinionated module generator. Modules and namespaces are automatically generated based on the project's directory names and structure.
|
19
17
|
|
20
18
|
NeptuneCoffee generates the .js files to define your AMD modules.
|
21
19
|
|
22
|
-
##
|
20
|
+
## Opinionated?
|
23
21
|
NeptuneCoffee has an opinion about how you should organize your javascript for AMD modules. It is:
|
24
22
|
|
25
23
|
* Directories are AMD modules
|
@@ -37,50 +35,54 @@ Refactoring module structure is as simple as renaming and moving directories and
|
|
37
35
|
|
38
36
|
For every $subdir, NeptuneCoffee generates:
|
39
37
|
|
40
|
-
$subdir/neptune.js // loads and attaches all sub-namespaces to $subdir's namespace object
|
41
38
|
$subdir/namespace.js // defines $subdir's namespace object
|
42
39
|
$subdir.js // loads all .js files in $subdir recursively
|
43
40
|
// all three files return $subdir's namespace object
|
44
41
|
|
42
|
+
## WARNING: Work in Progress
|
43
|
+
This is a work in progress. Unlikely to change:
|
44
|
+
* directories-define-modules
|
45
|
+
* including the directory_name.js to included the module
|
46
|
+
* include ./namespace.js to get the local module's namespace
|
47
|
+
|
45
48
|
# How to Use
|
46
49
|
|
47
50
|
Install neptune_coffee (see below). Then, whenever your directory structure changes or you move/add/rename/delete files, run:
|
48
|
-
|
51
|
+
|
49
52
|
neptune_coffee -r source/root
|
50
53
|
|
51
54
|
* Client should require: **$subdir.js** for the AMD module **source/root/$subdir**
|
52
|
-
* Source files in **source/root/$subdir/** should require:
|
55
|
+
* Source files in **source/root/$subdir/** should require: **./namespace.js**
|
53
56
|
|
54
57
|
## Example
|
55
58
|
|
56
59
|
Given this directory structure and files:
|
57
60
|
|
58
61
|
geometry/solids/cone.js
|
59
|
-
geometry/box.js
|
62
|
+
geometry/box.js
|
60
63
|
geometry/circle.js
|
61
|
-
|
62
|
-
|
64
|
+
|
65
|
+
NeptuneCoffee generates:
|
63
66
|
|
64
67
|
geometry.js
|
65
68
|
geometry/namespace.js
|
66
|
-
geometry/neptune.js
|
67
69
|
geometry/solids.js
|
68
70
|
geometry/solids/namespace.js
|
69
|
-
geometry/solids/neptune.js
|
70
71
|
|
71
72
|
geometry.js might look like:
|
72
73
|
|
73
|
-
// Generated by NeptuneCoffee 0.0.
|
74
|
+
// Generated by NeptuneCoffee 0.0.2
|
74
75
|
define([
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
], function(Geometry) {
|
76
|
+
'./geometry/namespace'
|
77
|
+
'./geometry/box'
|
78
|
+
'./geometry/circle'
|
79
|
+
'./geometry/solids'
|
80
|
+
], function(Geometry) {
|
81
81
|
return Geometry;
|
82
82
|
});
|
83
|
-
|
83
|
+
|
84
|
+
See [examples](https://github.com/Imikimi-LLC/neptune_coffee/tree/master/examples) a complete and current before & after example.
|
85
|
+
|
84
86
|
## Installation
|
85
87
|
|
86
88
|
Add this line to your application's Gemfile:
|
data/Rakefile
CHANGED
@@ -1 +1,15 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc "Run all examples with RCov"
|
7
|
+
RSpec::Core::RakeTask.new('spec:rcov') do |t|
|
8
|
+
t.rcov = true
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => :spec
|
@@ -0,0 +1,11 @@
|
|
1
|
+
// Generated by NeptuneCoffee 0.0.2
|
2
|
+
define([
|
3
|
+
'./geometry/namespace'
|
4
|
+
], function(Geometry) {
|
5
|
+
Neptune = (function() {
|
6
|
+
function Neptune() {}
|
7
|
+
return Neptune;
|
8
|
+
})();
|
9
|
+
Neptune.Geometry = Geometry; Geometry.namespace = Neptune;
|
10
|
+
return Neptune;
|
11
|
+
});
|
@@ -1,42 +1,34 @@
|
|
1
|
-
require 'extlib'
|
2
|
-
require 'guard/guard'
|
1
|
+
require 'extlib' # for camel_case
|
3
2
|
require "coderay"
|
4
|
-
|
5
|
-
module ::Guard
|
6
|
-
module UI
|
7
|
-
class << self
|
8
|
-
def success(message, options = {})
|
9
|
-
_filtered_logger_message(message, :info, :green, options)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
3
|
+
require "pathname"
|
14
4
|
|
15
5
|
module NeptuneCoffee
|
6
|
+
|
16
7
|
class Generator
|
8
|
+
attr_accessor :generated_files, :to_generate_files, :current_files, :skipped_files
|
9
|
+
attr_accessor :dirs, :force, :verbose, :quiet, :overwrite
|
17
10
|
|
18
11
|
SAFE_GENERATE_FIRST_LINE = "// Generated by NeptuneCoffee"
|
19
12
|
|
20
13
|
def initialize(options)
|
21
|
-
|
14
|
+
raise ArgumentError.new(":root option required, must be a string and valid path") unless Pathname.new(options[:root]).directory?
|
15
|
+
@dirs = SimpleDirectoryStructure.new options[:root]
|
16
|
+
@dirs.add_all
|
22
17
|
@force = options[:force]
|
23
18
|
@verbose = options[:verbose]
|
24
19
|
@overwrite = options[:overwrite]
|
20
|
+
@quiet = options[:quiet]
|
25
21
|
reset_file_info
|
26
22
|
end
|
27
23
|
|
28
|
-
|
24
|
+
def root
|
25
|
+
@dirs.root
|
26
|
+
end
|
29
27
|
|
28
|
+
def warning(message) Guard::UI.warning "NeptuneCoffee: "+message unless @quiet; end
|
29
|
+
def info(message) Guard::UI.info "NeptuneCoffee: "+message unless @quiet; end
|
30
|
+
def success(message) Guard::UI.success "NeptuneCoffee: "+message unless @quiet; end
|
30
31
|
def error(message) Guard::UI.error "NeptuneCoffee: "+message; end
|
31
|
-
def warning(message) Guard::UI.warning "NeptuneCoffee: "+message; end
|
32
|
-
def info(message) Guard::UI.info "NeptuneCoffee: "+message; end
|
33
|
-
def success(message) Guard::UI.success "NeptuneCoffee: "+message; end
|
34
|
-
|
35
|
-
def in_root
|
36
|
-
Dir.chdir @root do
|
37
|
-
yield
|
38
|
-
end
|
39
|
-
end
|
40
32
|
|
41
33
|
def reset_file_info
|
42
34
|
@generated_files = {}
|
@@ -47,60 +39,45 @@ module NeptuneCoffee
|
|
47
39
|
|
48
40
|
def generate_all
|
49
41
|
reset_file_info
|
50
|
-
success "generating all files in: #{
|
51
|
-
|
42
|
+
success "generating all files in: #{root}"
|
43
|
+
success "#{@dirs.length} directories found"
|
44
|
+
|
45
|
+
@dirs.all.each do |dir|
|
46
|
+
generate_module dir unless dir == root
|
47
|
+
generate_namespace dir
|
48
|
+
end
|
49
|
+
|
52
50
|
success "#{@current_files.length}/#{@to_generate_files.length} files current"
|
53
|
-
success "#{@generated_files.length} files
|
51
|
+
success "#{@generated_files.length} files generated" # if @generated_files.length > 0
|
54
52
|
warning "#{@skipped_files.length} files skipped (this is a name conflict. We recommend renaming your source file(s)." if @skipped_files.length> 0
|
55
53
|
end
|
56
54
|
|
57
|
-
def
|
58
|
-
|
59
|
-
p = path.split(@root+"/", 2)[1] || ""
|
60
|
-
dir = File.dirname p
|
61
|
-
subdir = join dir, File.basename(p, File.extname(p))
|
62
|
-
if subdir.length>0 && File.directory?(join @root, subdir)
|
63
|
-
[dir,subdir]
|
64
|
-
else
|
65
|
-
dir
|
66
|
-
end
|
67
|
-
end.flatten.uniq.sort.reverse
|
68
|
-
end
|
69
|
-
|
70
|
-
def generate_on_changes(paths)
|
71
|
-
dirs = dirs_effected paths
|
72
|
-
in_root do
|
73
|
-
dirs.each do |dir|
|
74
|
-
generate_neptune dir
|
75
|
-
generate_namespace dir
|
76
|
-
generate_loader dir
|
77
|
-
end
|
78
|
-
end
|
55
|
+
def file_was_generated_by_neptune_coffee file
|
56
|
+
!file.exist? || (file.read(SAFE_GENERATE_FIRST_LINE.length) == SAFE_GENERATE_FIRST_LINE)
|
79
57
|
end
|
80
58
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
return SAFE_GENERATE_FIRST_LINE == file.read(SAFE_GENERATE_FIRST_LINE.length)
|
85
|
-
end
|
86
|
-
false
|
59
|
+
def show_generated contents
|
60
|
+
highlighted = CodeRay.scan(new_contents, :javascript).terminal
|
61
|
+
info "output:\n "+highlighted.gsub("\n","\n ")
|
87
62
|
end
|
88
63
|
|
64
|
+
# writes to "file" whatever the block yields IF
|
65
|
+
# the file was originally generated by NeptuneCoffee (unless @overwrite)
|
66
|
+
# the file contents changed (unless @force)
|
89
67
|
def safe_generate file
|
90
68
|
@to_generate_files[file] = true
|
91
|
-
|
92
|
-
|
93
|
-
|
69
|
+
info_file = file #join @root, file.split(@root)[-1]
|
70
|
+
if @overwrite || file_was_generated_by_neptune_coffee(file)
|
71
|
+
|
94
72
|
new_contents = SAFE_GENERATE_FIRST_LINE + " #{NeptuneCoffee::VERSION}\n" + yield
|
95
|
-
|
73
|
+
|
74
|
+
if @force || !file.exist? || file.read != new_contents
|
96
75
|
@generated_files[file] = true
|
97
76
|
success "generating: #{info_file}"
|
98
|
-
|
99
|
-
|
100
|
-
File.write file, new_contents
|
77
|
+
show_generated new_contents if @verbose
|
78
|
+
file.open("w") {|f| f.write new_contents}
|
101
79
|
else
|
102
80
|
@current_files[file] = true
|
103
|
-
# success "unchanged: #{info_file}"
|
104
81
|
end
|
105
82
|
else
|
106
83
|
@skipped_files[file] = true
|
@@ -108,90 +85,14 @@ module NeptuneCoffee
|
|
108
85
|
end
|
109
86
|
end
|
110
87
|
|
111
|
-
def
|
112
|
-
files =
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
def generate_loader dir
|
117
|
-
return if dir == "."
|
118
|
-
files = js_files_to_load dir
|
119
|
-
files = [join(dir, "namespace")]+files
|
120
|
-
namespace_name = File.basename(dir).camel_case
|
121
|
-
safe_generate dir+".js" do
|
122
|
-
<<-ENDJS
|
123
|
-
define([
|
124
|
-
"#{files.join "\",\n \""}"
|
125
|
-
], function(#{namespace_name}) {
|
126
|
-
return #{namespace_name};
|
127
|
-
});
|
128
|
-
ENDJS
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def join(dir, file)
|
133
|
-
if dir == "." || dir == ""
|
134
|
-
file
|
135
|
-
else
|
136
|
-
File.join dir, file
|
137
|
-
end
|
88
|
+
def generate_module dir
|
89
|
+
files = dir.children.select {|f| f.extname.downcase == ".js"}
|
90
|
+
safe_generate(dir.sub_ext(".js")) {JavascriptGenerator.new(root, dir).module(@dirs.subdirs(dir) + files)}
|
138
91
|
end
|
139
92
|
|
140
|
-
def sub_namespaces_to_include dir
|
141
|
-
Dir.glob(dir+"/*").select {|f| File.directory?(f) && File.exists?(File.join f, "namespace.js")}.sort
|
142
|
-
end
|
143
|
-
|
144
|
-
def generate_neptune dir
|
145
|
-
path = join dir, "neptune.js"
|
146
|
-
root = dir == "."
|
147
|
-
sub_namespaces = sub_namespaces_to_include dir
|
148
|
-
camel_subs = sub_namespaces.map {|s| s.split("/")[-1].camel_case}
|
149
|
-
subs_files = sub_namespaces.map {|s| File.join s, "neptune"}
|
150
|
-
namespace_name = File.basename(dir).camel_case
|
151
|
-
namespace_name = "Neptune" if dir == "."
|
152
|
-
subs_files = [join(dir, "namespace")]+subs_files unless root
|
153
|
-
function_params = camel_subs
|
154
|
-
function_params = [namespace_name] + function_params unless root
|
155
|
-
safe_generate path do
|
156
|
-
<<-ENDJS
|
157
|
-
define([
|
158
|
-
"#{subs_files.join "\",\n \""}"
|
159
|
-
], function(#{function_params.join ", "}) {#{"
|
160
|
-
Neptune = window.Neptune = {};" if root}#{
|
161
|
-
camel_subs.map do |s|"
|
162
|
-
#{namespace_name}.#{s} = #{s}; #{s}.namespace = #{namespace_name};"
|
163
|
-
end.join
|
164
|
-
}
|
165
|
-
return #{namespace_name};
|
166
|
-
});
|
167
|
-
ENDJS
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
|
172
93
|
def generate_namespace dir
|
173
|
-
|
174
|
-
parent_namespace_name = File.basename(File.dirname dir).camel_case
|
175
|
-
parent_namespace_name = "Root" if parent_namespace_name == "."
|
176
|
-
namespace_name = File.basename(dir).camel_case
|
177
|
-
safe_generate path do
|
178
|
-
if dir == "." || dir == ""
|
179
|
-
<<-ENDJS
|
180
|
-
define([], function() {return window;})
|
181
|
-
ENDJS
|
182
|
-
else
|
183
|
-
parent_namespace = join File.dirname(dir), "namespace"
|
184
|
-
<<-ENDJS
|
185
|
-
define(["#{parent_namespace}"], function(#{parent_namespace_name}) {
|
186
|
-
return #{parent_namespace_name}.#{namespace_name} = (function() {
|
187
|
-
function #{namespace_name}() {}
|
188
|
-
#{namespace_name}.namespace = #{parent_namespace_name};
|
189
|
-
return #{namespace_name};
|
190
|
-
})();
|
191
|
-
});
|
192
|
-
ENDJS
|
193
|
-
end
|
194
|
-
end
|
94
|
+
safe_generate(dir + "namespace.js") {JavascriptGenerator.new(root, dir).namespace(@dirs.subdirs(dir))}
|
195
95
|
end
|
96
|
+
|
196
97
|
end
|
197
98
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'guard/guard'
|
2
|
+
|
3
|
+
module ::Guard
|
4
|
+
module UI
|
5
|
+
class << self
|
6
|
+
# add "success" to extend "warning", "error" and "info"
|
7
|
+
# "success" is like "info" except it is green to stand out
|
8
|
+
def success(message, options = {})
|
9
|
+
_filtered_logger_message(message, :info, :green, options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module NeptuneCoffee
|
2
|
+
class JavascriptGenerator
|
3
|
+
attr_accessor :root, :dir
|
4
|
+
def initialize root, dir
|
5
|
+
@root = root
|
6
|
+
@dir = dir
|
7
|
+
end
|
8
|
+
|
9
|
+
def define_js files, relative_to_path
|
10
|
+
files_js = files.length == 0 ? "" : files.map{|f| "\n './#{f.relative_path_from(relative_to_path)}'"}.join + "\n"
|
11
|
+
"define([#{files_js}], function"
|
12
|
+
end
|
13
|
+
|
14
|
+
def module files
|
15
|
+
# subfiles ||= dir.children.select{|c| !c.directory? && c.extname == ".js"}
|
16
|
+
files = files.map{|f|f.sub_ext("")}
|
17
|
+
files = [dir + "namespace"] + files.select{|c|c.basename.to_s!="namespace"}.sort.uniq
|
18
|
+
|
19
|
+
<<-ENDJS
|
20
|
+
#{define_js files, dir.dirname}(#{namespace_name}) {
|
21
|
+
return #{namespace_name};
|
22
|
+
});
|
23
|
+
ENDJS
|
24
|
+
end
|
25
|
+
|
26
|
+
def namespace_name
|
27
|
+
@namespace_name ||= (dir == root ? "Neptune" : dir.basename.to_s.camel_case)
|
28
|
+
end
|
29
|
+
|
30
|
+
def namespace subdirs
|
31
|
+
sub_namespace_files = subdirs.map {|subdirs| subdirs + "namespace"}
|
32
|
+
|
33
|
+
sub_namespaces = subdirs.map {|files| files.basename.to_s.camel_case}
|
34
|
+
|
35
|
+
<<-ENDJS
|
36
|
+
#{define_js sub_namespace_files, dir}(#{sub_namespaces.join ', '}) {
|
37
|
+
#{namespace_name} = (function() {
|
38
|
+
function #{namespace_name}() {}
|
39
|
+
return #{namespace_name};
|
40
|
+
})();#{
|
41
|
+
sub_namespaces.map do |sns|
|
42
|
+
"\n #{namespace_name}.#{sns} = #{sns}; #{sns}.namespace = #{namespace_name};"
|
43
|
+
end.join
|
44
|
+
}
|
45
|
+
return #{namespace_name};
|
46
|
+
});
|
47
|
+
ENDJS
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module NeptuneCoffee
|
2
|
+
|
3
|
+
class SimpleDirectoryStructure
|
4
|
+
attr_accessor :directories, :root
|
5
|
+
def initialize root
|
6
|
+
@root = Pathname.new root
|
7
|
+
@directories={@root => []}
|
8
|
+
end
|
9
|
+
|
10
|
+
def length; @directories.length; end
|
11
|
+
|
12
|
+
def valid_path path
|
13
|
+
path = case path
|
14
|
+
when Pathname then path
|
15
|
+
when String then Pathname.new path
|
16
|
+
else raise "invalid path object type: #{path.class}"
|
17
|
+
end
|
18
|
+
raise "path #{path.to_s.inspect} has not been added" unless @directories[path]
|
19
|
+
path
|
20
|
+
end
|
21
|
+
|
22
|
+
def add path, subdir
|
23
|
+
path = valid_path path
|
24
|
+
subdir_path = path + subdir
|
25
|
+
@directories[subdir_path] = []
|
26
|
+
@directories[path] << subdir_path
|
27
|
+
subdir_path
|
28
|
+
end
|
29
|
+
|
30
|
+
def all
|
31
|
+
@directories.keys
|
32
|
+
end
|
33
|
+
|
34
|
+
def subdirs path = @root
|
35
|
+
@directories[valid_path(path)]
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_all path = @root
|
39
|
+
valid_path(path).children.each do |c|
|
40
|
+
next unless c.directory?
|
41
|
+
add path, c.basename
|
42
|
+
add_all c
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module NeptuneCoffee
|
2
|
+
|
3
|
+
class Util
|
4
|
+
class << self
|
5
|
+
# returns a hash of path's subdirectories mapped to recursive calls on subdir_hash on those subdirs
|
6
|
+
def subdir_hash path
|
7
|
+
result = {}
|
8
|
+
path.children.each do |c|
|
9
|
+
result[c] = subdir_hash c if c.directory?
|
10
|
+
end
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
# returns number of hash and array elements recursively
|
15
|
+
def deep_length data
|
16
|
+
case data
|
17
|
+
when Hash then data.length + data.inject(0) {|sum,v| sum + deep_length(v[1])}
|
18
|
+
when Array then data.length + data.inject(0) {|sum,v| sum + deep_length(v)}
|
19
|
+
else 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/neptune_coffee.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
require "pathname"
|
1
2
|
%w{
|
2
3
|
version
|
4
|
+
util
|
5
|
+
guard
|
3
6
|
generator
|
7
|
+
javascript_generator
|
8
|
+
simple_directory_structure
|
4
9
|
}.each do |mod|
|
5
|
-
require
|
6
|
-
end
|
7
|
-
|
8
|
-
module NeptuneCoffee
|
10
|
+
require Pathname.new(__FILE__).dirname + "neptune_coffee" + mod
|
9
11
|
end
|
data/neptune_coffee.gemspec
CHANGED
@@ -8,9 +8,9 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = NeptuneCoffee::VERSION
|
9
9
|
spec.authors = ["Shane Brinkman-Davis"]
|
10
10
|
spec.email = ["shanebdavis@gmail.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{NeptuneCoffee is an opinionated module generator.
|
13
|
-
spec.homepage = ""
|
11
|
+
spec.description = %q{opinionated javascript-AMD-module generator}
|
12
|
+
spec.summary = %q{NeptuneCoffee is an opinionated module generator. Modules and namespaces are automatically generated based on the project's directory names and structure.}
|
13
|
+
spec.homepage = "https://github.com/Imikimi-LLC/neptune_coffee"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -19,10 +19,11 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "trollop"
|
22
|
-
spec.add_dependency "extlib"
|
22
|
+
spec.add_dependency "extlib" # for camel_case
|
23
23
|
spec.add_dependency "coderay"
|
24
24
|
spec.add_dependency "guard"
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.3"
|
27
27
|
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency 'rspec', '~> 2.14.0'
|
28
29
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tmpdir'
|
4
|
+
require Pathname.new(__FILE__).dirname + "../lib/neptune_coffee"
|
5
|
+
|
6
|
+
module NeptuneCoffee
|
7
|
+
describe Generator do
|
8
|
+
|
9
|
+
it "deep_length number" do
|
10
|
+
before_example_path = Pathname.new(__FILE__).dirname + "../examples/before/geometry"
|
11
|
+
before_example_path.directory?.should == true
|
12
|
+
|
13
|
+
after_example_path = Pathname.new(__FILE__).dirname + "../examples/after/geometry"
|
14
|
+
after_example_path.directory?.should == true
|
15
|
+
|
16
|
+
dir = Dir.mktmpdir do |dir|
|
17
|
+
path = Pathname.new dir
|
18
|
+
FileUtils.cp_r before_example_path.to_s, dir
|
19
|
+
|
20
|
+
generator = NeptuneCoffee::Generator.new root:path, quiet:true
|
21
|
+
generator.generate_all
|
22
|
+
|
23
|
+
# puts `find #{dir}` # list all files in temp dir
|
24
|
+
`diff -ru #{after_example_path.dirname} #{path}`.should == ""
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname.new(__FILE__).dirname + "../lib/neptune_coffee"
|
3
|
+
|
4
|
+
class Pathname
|
5
|
+
class <<self
|
6
|
+
def [](str)
|
7
|
+
Pathname.new str
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module NeptuneCoffee
|
13
|
+
describe JavascriptGenerator do
|
14
|
+
|
15
|
+
it "module_js" do
|
16
|
+
module_js = JavascriptGenerator.new(Pathname["foo"], Pathname["foo/bar"]).module [
|
17
|
+
Pathname["foo/bar/subdir1.js"],
|
18
|
+
Pathname["foo/bar/subdir2.js"],
|
19
|
+
Pathname["foo/bar/file1"],
|
20
|
+
Pathname["foo/bar/file2"]
|
21
|
+
]
|
22
|
+
|
23
|
+
module_js.should == <<ENDJS
|
24
|
+
define([
|
25
|
+
'./bar/namespace'
|
26
|
+
'./bar/file1'
|
27
|
+
'./bar/file2'
|
28
|
+
'./bar/subdir1'
|
29
|
+
'./bar/subdir2'
|
30
|
+
], function(Bar) {
|
31
|
+
return Bar;
|
32
|
+
});
|
33
|
+
ENDJS
|
34
|
+
end
|
35
|
+
|
36
|
+
it "namespace_js" do
|
37
|
+
namespace_js = JavascriptGenerator.new(Pathname["foo"], Pathname["foo/bar"]).namespace [
|
38
|
+
Pathname["foo/bar/sub_dir1"], Pathname["foo/bar/sub_dir2"]
|
39
|
+
]
|
40
|
+
namespace_js.should == <<ENDJS
|
41
|
+
define([
|
42
|
+
'./sub_dir1/namespace'
|
43
|
+
'./sub_dir2/namespace'
|
44
|
+
], function(SubDir1, SubDir2) {
|
45
|
+
Bar = (function() {
|
46
|
+
function Bar() {}
|
47
|
+
return Bar;
|
48
|
+
})();
|
49
|
+
Bar.SubDir1 = SubDir1; SubDir1.namespace = Bar;
|
50
|
+
Bar.SubDir2 = SubDir2; SubDir2.namespace = Bar;
|
51
|
+
return Bar;
|
52
|
+
});
|
53
|
+
ENDJS
|
54
|
+
end
|
55
|
+
|
56
|
+
it "namespace_js with no subdirs" do
|
57
|
+
namespace_js = JavascriptGenerator.new(Pathname["foo"], Pathname["foo/bar"]).namespace []
|
58
|
+
namespace_js.should == <<ENDJS
|
59
|
+
define([], function() {
|
60
|
+
Bar = (function() {
|
61
|
+
function Bar() {}
|
62
|
+
return Bar;
|
63
|
+
})();
|
64
|
+
return Bar;
|
65
|
+
});
|
66
|
+
ENDJS
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname.new(__FILE__).dirname + "../lib/neptune_coffee"
|
3
|
+
|
4
|
+
module NeptuneCoffee
|
5
|
+
describe SimpleDirectoryStructure do
|
6
|
+
|
7
|
+
it "initialize" do
|
8
|
+
sds = SimpleDirectoryStructure.new "."
|
9
|
+
sds.root.should == Pathname.new(".")
|
10
|
+
sds.subdirs(sds.root).should == []
|
11
|
+
end
|
12
|
+
|
13
|
+
it "add subdir" do
|
14
|
+
sds = SimpleDirectoryStructure.new "."
|
15
|
+
sds.add ".", "foo"
|
16
|
+
sds.add ".", "bar"
|
17
|
+
sds.subdirs.map{|sd|sd.basename.to_s}.should == ["foo", "bar"]
|
18
|
+
sds.subdirs("foo").map{|sd|sd.basename.to_s}.should == []
|
19
|
+
sds.subdirs("bar").map{|sd|sd.basename.to_s}.should == []
|
20
|
+
sds.all.map{|sd|sd.basename.to_s}.should == [".", "foo", "bar"]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "read example_dir" do
|
24
|
+
path = Pathname.new(__FILE__).dirname + ".." + "examples/before/"
|
25
|
+
sds = SimpleDirectoryStructure.new path
|
26
|
+
sds.add_all
|
27
|
+
sds.subdirs.map{|sd|sd.basename.to_s}.should == ["geometry"]
|
28
|
+
sds.subdirs(path+"geometry").map{|sd|sd.basename.to_s}.should == ["solids"]
|
29
|
+
sds.subdirs(path+"geometry/solids").map{|sd|sd.basename.to_s}.should == []
|
30
|
+
sds.all.map{|sd|sd.basename.to_s}.should == ["before", "geometry", "solids"]
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/spec/util_spec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname.new(__FILE__).dirname + "../lib/neptune_coffee"
|
3
|
+
|
4
|
+
module NeptuneCoffee
|
5
|
+
describe Util do
|
6
|
+
|
7
|
+
it "subdir_hash" do
|
8
|
+
root = Pathname.new(__FILE__).dirname + "../examples/before"
|
9
|
+
a = Util.subdir_hash root
|
10
|
+
|
11
|
+
geometry = root + "geometry"
|
12
|
+
solids = geometry + "solids"
|
13
|
+
b = {geometry => {solids => {}}}
|
14
|
+
|
15
|
+
a.should == b
|
16
|
+
end
|
17
|
+
|
18
|
+
it "deep_length number" do
|
19
|
+
Util.deep_length(1).should == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
it "deep_length string" do
|
23
|
+
Util.deep_length("foo").should == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
it "deep_length array" do
|
27
|
+
Util.deep_length([1,2,3]).should == 3
|
28
|
+
end
|
29
|
+
|
30
|
+
it "deep_length hash" do
|
31
|
+
Util.deep_length({a:1, b:2}).should == 2
|
32
|
+
end
|
33
|
+
|
34
|
+
it "deep_length everything" do
|
35
|
+
Util.deep_length([1,"foo",3,[4,5,6,7],{a:1, b:[4,5]}]).should == 13
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neptune_coffee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shane Brinkman-Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trollop
|
@@ -94,7 +94,21 @@ dependencies:
|
|
94
94
|
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 2.14.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.14.0
|
111
|
+
description: opinionated javascript-AMD-module generator
|
98
112
|
email:
|
99
113
|
- shanebdavis@gmail.com
|
100
114
|
executables:
|
@@ -108,20 +122,30 @@ files:
|
|
108
122
|
- README.md
|
109
123
|
- Rakefile
|
110
124
|
- bin/neptune_coffee
|
111
|
-
- examples/geometry.js
|
112
|
-
- examples/geometry/box.js
|
113
|
-
- examples/geometry/circle.js
|
114
|
-
- examples/geometry/namespace.js
|
115
|
-
- examples/geometry/
|
116
|
-
- examples/geometry/solids.js
|
117
|
-
- examples/geometry/solids/
|
118
|
-
- examples/
|
119
|
-
- examples/geometry/
|
125
|
+
- examples/after/geometry.js
|
126
|
+
- examples/after/geometry/box.js
|
127
|
+
- examples/after/geometry/circle.js
|
128
|
+
- examples/after/geometry/namespace.js
|
129
|
+
- examples/after/geometry/solids.js
|
130
|
+
- examples/after/geometry/solids/cone.js
|
131
|
+
- examples/after/geometry/solids/namespace.js
|
132
|
+
- examples/after/namespace.js
|
133
|
+
- examples/before/geometry/box.js
|
134
|
+
- examples/before/geometry/circle.js
|
135
|
+
- examples/before/geometry/solids/cone.js
|
120
136
|
- lib/neptune_coffee.rb
|
121
137
|
- lib/neptune_coffee/generator.rb
|
138
|
+
- lib/neptune_coffee/guard.rb
|
139
|
+
- lib/neptune_coffee/javascript_generator.rb
|
140
|
+
- lib/neptune_coffee/simple_directory_structure.rb
|
141
|
+
- lib/neptune_coffee/util.rb
|
122
142
|
- lib/neptune_coffee/version.rb
|
123
143
|
- neptune_coffee.gemspec
|
124
|
-
|
144
|
+
- spec/generator_spec.rb
|
145
|
+
- spec/javascript_generator_spec.rb
|
146
|
+
- spec/simple_directory_structure_spec.rb
|
147
|
+
- spec/util_spec.rb
|
148
|
+
homepage: https://github.com/Imikimi-LLC/neptune_coffee
|
125
149
|
licenses:
|
126
150
|
- MIT
|
127
151
|
metadata: {}
|
@@ -141,10 +165,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
165
|
version: '0'
|
142
166
|
requirements: []
|
143
167
|
rubyforge_project:
|
144
|
-
rubygems_version: 2.0.
|
168
|
+
rubygems_version: 2.0.3
|
145
169
|
signing_key:
|
146
170
|
specification_version: 4
|
147
|
-
summary: NeptuneCoffee is an opinionated module generator.
|
148
|
-
|
149
|
-
|
150
|
-
|
171
|
+
summary: NeptuneCoffee is an opinionated module generator. Modules and namespaces
|
172
|
+
are automatically generated based on the project's directory names and structure.
|
173
|
+
test_files:
|
174
|
+
- spec/generator_spec.rb
|
175
|
+
- spec/javascript_generator_spec.rb
|
176
|
+
- spec/simple_directory_structure_spec.rb
|
177
|
+
- spec/util_spec.rb
|
data/examples/geometry/solids.js
DELETED
data/examples/geometry.js
DELETED
File without changes
|
File without changes
|
File without changes
|