neptune_coffee 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/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
|