neptune_coffee 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ff1151257434e5c05e89d3d20a1427855bcffe9
4
- data.tar.gz: c82d36f075b2dac5318673ff94a949ceb8c22e17
3
+ metadata.gz: 81dfeb0fbd08d00d2daeaf9a9ae6015c0f334688
4
+ data.tar.gz: bb03a3648574f04bf67c311a6e5f17b9bc2629fe
5
5
  SHA512:
6
- metadata.gz: dd73fc52706441254c998c95dc08731520d9dc2ed2ca33902a5a38208f3934a70a74c24e13b7bd1196ae0bea8f825f7384a7ddf51599be3cd4c1447da689158b
7
- data.tar.gz: 58bb0b73e9a40ddaacd23683cfd31dfeffc9f66bd0d692612772916f03ef1aea0e972d74bf7d14fecc5ceaca4e146b513479d459d4f5b20e255233e68d066f99
6
+ metadata.gz: dfae5c029030739c73c71ffcfc93c7813b7dc1e55987cca192e27364edaaba8ce97d0c5ed44647d1973ec71fcf67b8353151d6de3a3119e43ba12664a5687330
7
+ data.tar.gz: 609a3469a38bc070b7c8f25f4a98b6e97be0414297cd210c42f7916c5b75d3983bbbd06eeff2a4213989986c2039436a0f08195ce1e82ce6fa3c904a463f30e3
@@ -1,8 +1,15 @@
1
1
  # Neptune Coffee Changelog
2
2
 
3
+ ### v0.2.5
4
+
5
+ Added: rake reset_examples
6
+
7
+ Changed generated 'namespace.js' semantics. It no longer includes sub-
8
+ namespaces. Include the generated module file to get all sub-namespaces.
9
+
3
10
  ### v0.2.4
4
11
 
5
- Updated Generator#generate_all to now return a Hash of Arrays (instead Hash of Hashes)
12
+ Updated Generator#generate_all to now return a Hash of Arrays (instead Hash of Hashes).
6
13
 
7
14
  ### v0.2.3
8
15
 
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
+ require "pathname"
2
3
 
3
4
  require 'rspec'
4
5
  require 'rspec/core/rake_task'
@@ -12,4 +13,21 @@ RSpec::Core::RakeTask.new('spec') do |t|
12
13
  t.verbose = true
13
14
  end
14
15
 
16
+ desc "Regenerate examples/after based on examepls/before"
17
+ task :reset_examples do
18
+ root = Pathname.new(__FILE__).parent.relative_path_from Pathname.pwd
19
+ binary = root + "bin/neptune_coffee"
20
+ examples = root + "examples"
21
+ examples_before = examples + "before"
22
+ examples_after = examples + "after"
23
+ puts "rm -r #{examples_after}"
24
+ examples_after.rmtree
25
+ command = "cp -v -R #{examples_before} #{examples_after}"
26
+ puts command
27
+ system command
28
+ # `#{command}`
29
+ command = "#{binary} -o -r #{examples_after}"
30
+ `#{command}`
31
+ end
32
+
15
33
  task :default => :spec
data/TODO.md ADDED
@@ -0,0 +1,58 @@
1
+ # Neptune Coffee Todo
2
+
3
+ ## .directories (dot-directories)
4
+
5
+ #### Goals
6
+ * Support putting test files inside the directory of the module they are testing.
7
+ * Reduce management and refactoring complexity: Just move the module's directory and all its tests move with it.
8
+ * Make it easy to load the test files of one module, and all its sub-modules.
9
+ * Make it so you don't have to load all test files globally.
10
+ * Make a general solution so many different types of cross-cutting, non-production support files can be co-located within their modules. For example, performance-testing is separate from correctness testing.
11
+
12
+ #### Status Quo
13
+
14
+ * Currently requiring a module includes all js files in all sub-directories. This makes it impossible to co-locate test files in the same structure unless you want the test files deployed to production.
15
+ * Currently all tests are loaded at once, globally. This is getting awkward and slow. Mocha supports only running selected tests, but the current system sill loads all test and, consequently, all source-code. Combine that with live-reload and there is a lot of uneccessary work being done with every red-green test cycle.
16
+ * Currently directories that start with a dot don't work at all. It generates namespaces that start with a "." - illegal in javascript.
17
+
18
+ #### Propsed Solution
19
+
20
+ * Place your test files in a subdirectory named ".test"
21
+ * Directories that start with a dot are treated specially:
22
+ * They are not included by default when requiring a parent module-directory.
23
+ * They must be explicitly required: require ".test"
24
+ * They are linked into the NeptuneCoffee namespace structure as-if their directory-name didn't have a ".". Ex: ".test" becomes the Test namespace under its parent directory
25
+ * NOTE: You shouldn't have both "test" and ".test" subdirs under the same parent.
26
+ * To included all dot-directories of the same name anywhere under a parent-directory, require the parent-directory's path and name concatinated with the dot-directory's name. Ex:
27
+ * Directory structure:
28
+ * foo
29
+ * foo/.test
30
+ * foo/.perf
31
+ * foo/bar
32
+ * foo/bar/.test
33
+ * foo/bar/.perf
34
+ * require ["foo.test"], (Foo) ->
35
+ * imports all .test directories in foo and all its sub-directories
36
+ * returns Foo, with (at-least) the following namespaces set:
37
+ * Foo.Bar
38
+ * Foo.Test
39
+ * Foo.Bar.Test
40
+ * require ["foo.perf"], (Foo) ->
41
+ * imports all .perf directories in foo and all its sub-directories
42
+ * returns Foo, with (at-least) the following namespaces set:
43
+ * Foo.Bar
44
+ * Foo.Perf
45
+ * Foo.Bar.Perf
46
+ * require ["foo", "foo.perf", "foo.test"], (Foo, FooPerf, FooTest) ->
47
+ * Foo == FooPerf == FooTest
48
+ * returns Foo, with (at-least) the following namespaces set:
49
+ * Foo.Bar
50
+ * Foo.Perf
51
+ * Foo.Bar.Perf
52
+ * Foo.Test
53
+ * Foo.Bar.Test
54
+
55
+ ## don't generate files for directories with no JavaScript files
56
+ ## Auto-delete generated files no longer needed
57
+ ## should we support CSS concatination?
58
+ ## including a namespace file and one JavaScript file in that namespace doesn't guarantee the JavaScript file's return value is attached to that namespace.
@@ -1,12 +1,13 @@
1
- // Generated by NeptuneCoffee 0.2.3
1
+ // Generated by NeptuneCoffee 0.3.0
2
2
  // path: geometry.js
3
3
  define([
4
4
  './geometry/namespace',
5
5
  './geometry/box',
6
6
  './geometry/circle',
7
7
  './geometry/solids'
8
- ], function(Geometry, Box, Circle) {
8
+ ], function(Geometry, Box, Circle, Solids) {
9
9
  if (typeof Box == 'function') {Geometry.Box = Box; Box.namespace = Geometry;}
10
10
  if (typeof Circle == 'function') {Geometry.Circle = Circle; Circle.namespace = Geometry;}
11
+ if (typeof Solids == 'function') {Geometry.Solids = Solids; Solids.namespace = Geometry;}
11
12
  return Geometry;
12
- });
13
+ });
@@ -1,12 +1,9 @@
1
- // Generated by NeptuneCoffee 0.2.3
1
+ // Generated by NeptuneCoffee 0.3.0
2
2
  // path: geometry/namespace.js
3
- define([
4
- './solids/namespace'
5
- ], function(Solids) {
3
+ define([], function() {
6
4
  var Geometry = (function() {
7
5
  function Geometry() {}
8
6
  return Geometry;
9
7
  })();
10
- Geometry.Solids = Solids; Solids.namespace = Geometry;
11
8
  return Geometry;
12
- });
9
+ });
@@ -1,4 +1,4 @@
1
- // Generated by NeptuneCoffee 0.2.3
1
+ // Generated by NeptuneCoffee 0.3.0
2
2
  // path: geometry/solids.js
3
3
  define([
4
4
  './solids/namespace',
@@ -6,4 +6,4 @@ define([
6
6
  ], function(Solids, Cone) {
7
7
  if (typeof Cone == 'function') {Solids.Cone = Cone; Cone.namespace = Solids;}
8
8
  return Solids;
9
- });
9
+ });
@@ -1,4 +1,4 @@
1
- // Generated by NeptuneCoffee 0.2.3
1
+ // Generated by NeptuneCoffee 0.3.0
2
2
  // path: geometry/solids/namespace.js
3
3
  define([], function() {
4
4
  var Solids = (function() {
@@ -6,4 +6,4 @@ define([], function() {
6
6
  return Solids;
7
7
  })();
8
8
  return Solids;
9
- });
9
+ });
@@ -1,12 +1,9 @@
1
- // Generated by NeptuneCoffee 0.2.3
1
+ // Generated by NeptuneCoffee 0.3.0
2
2
  // path: namespace.js
3
- define([
4
- './geometry/namespace'
5
- ], function(Geometry) {
3
+ define([], function() {
6
4
  var Neptune = (function() {
7
5
  function Neptune() {}
8
6
  return Neptune;
9
7
  })();
10
- Neptune.Geometry = Geometry; Geometry.namespace = Neptune;
11
8
  return Neptune;
12
- });
9
+ });
@@ -0,0 +1,14 @@
1
+ <%
2
+ class_files = class_files.map{|f|f.sub_ext("")}.select {|c|c.basename.to_s!="namespace"}.sort.uniq
3
+ files = [dir + "namespace"] + class_files + subdirs.sort.uniq
4
+ file_class_names = class_files.map {|files| files.basename.to_s.camel_case}
5
+
6
+ sub_namespaces = subdirs.map {|files| files.basename.to_s.camel_case}
7
+
8
+ define_js files_relative_to(files, dir.dirname), [namespace_name]+file_class_names+sub_namespaces do
9
+ (file_class_names+sub_namespaces).map do |fcn| %>
10
+ <%= "if (typeof #{fcn} == 'function') {#{namespace_name}.#{fcn} = #{fcn}; #{fcn}.namespace = #{namespace_name};}" %><%
11
+ end
12
+ %>
13
+ return <%= namespace_name %>;
14
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <%
2
+ define_js [], [] do %>
3
+ var <%= namespace_name %> = (function() {
4
+ function <%= namespace_name %>() {}
5
+ return <%= namespace_name %>;
6
+ })();
7
+ return <%= namespace_name %>;
8
+ <% end %>
@@ -1,4 +1,4 @@
1
- require 'guard/guard'
1
+ require 'guard'
2
2
 
3
3
  module ::Guard
4
4
  module UI
@@ -1,32 +1,55 @@
1
+ require "pathname"
2
+ require "erb"
3
+
1
4
  module NeptuneCoffee
2
5
  class JavascriptGenerator
3
- attr_accessor :root, :dir
6
+ class <<self
7
+ attr_accessor :generators
8
+ def load_erb
9
+ generator_root = Pathname.new(__FILE__).parent + "generators"
10
+ @generators = {}
11
+ generator_root.children(false).each do |erb_file|
12
+ name = erb_file.to_s.split(/\.erb$/)[0]
13
+ path = generator_root + erb_file
14
+ @generators[name] = ERB.new path.read, nil, "<>-"
15
+ @generators[name].filename = erb_file
16
+ end
17
+ end
18
+ end
19
+ JavascriptGenerator.load_erb
20
+
21
+ attr_accessor :root, :dir, :class_files, :subdirs
4
22
  def initialize root, dir
5
23
  @root = root
6
24
  @dir = dir
7
25
  end
8
26
 
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"
27
+ def files_relative_to files, relative_to_path
28
+ files.map {|f| f.relative_path_from relative_to_path}
29
+ end
30
+
31
+ def define_js relative_file_paths, local_names
32
+ files_js = if relative_file_paths.length == 0 then ""
33
+ else
34
+ "\n " + relative_file_paths.map{|f| "'./#{f}'"}.join(",\n ") + "\n"
35
+ end
36
+
37
+ old_buffer, @output_buffer = @output_buffer, ''
38
+ begin
39
+ content = yield
40
+ ensure
41
+ @output_buffer = old_buffer
42
+ end
43
+
44
+ @output_buffer << "define([#{files_js}], function(#{local_names.join ', '}) {#{content}});"
12
45
  end
13
46
 
14
- def module sub_modules, class_files
15
- # subfiles ||= dir.children.select{|c| !c.directory? && c.extname == ".js"}
16
- class_files = class_files.map{|f|f.sub_ext("")}.select {|c|c.basename.to_s!="namespace"}.sort.uniq
17
- files = [dir + "namespace"] + class_files + sub_modules.sort.uniq
18
-
19
- file_class_names = class_files.map {|files| files.basename.to_s.camel_case}
20
-
21
- <<-ENDJS
22
- #{define_js files, dir.dirname}(#{([namespace_name]+file_class_names).join ', '}) {#{
23
- file_class_names.map do |fcn|
24
- "\n if (typeof #{fcn} == 'function') {#{namespace_name}.#{fcn} = #{fcn}; #{fcn}.namespace = #{namespace_name};}"
25
- end.join
26
- }
27
- return #{namespace_name};
28
- });
29
- ENDJS
47
+ def module subdirs, class_files
48
+ @output_buffer = ""
49
+ @subdirs = subdirs
50
+ @class_files = class_files
51
+ JavascriptGenerator.generators["module.js"].result(binding)
52
+ @output_buffer
30
53
  end
31
54
 
32
55
  def namespace_name
@@ -34,23 +57,10 @@ ENDJS
34
57
  end
35
58
 
36
59
  def namespace subdirs
37
- sub_namespace_files = subdirs.map {|subdirs| subdirs + "namespace"}
38
-
39
- sub_namespaces = subdirs.map {|files| files.basename.to_s.camel_case}
40
-
41
- <<-ENDJS
42
- #{define_js sub_namespace_files, dir}(#{sub_namespaces.join ', '}) {
43
- var #{namespace_name} = (function() {
44
- function #{namespace_name}() {}
45
- return #{namespace_name};
46
- })();#{
47
- sub_namespaces.map do |sns|
48
- "\n #{namespace_name}.#{sns} = #{sns}; #{sns}.namespace = #{namespace_name};"
49
- end.join
50
- }
51
- return #{namespace_name};
52
- });
53
- ENDJS
60
+ @output_buffer = ""
61
+ @subdirs = subdirs
62
+ JavascriptGenerator.generators["namespace.js"].result(binding)
63
+ @output_buffer
54
64
  end
55
65
  end
56
66
  end
@@ -1,3 +1,3 @@
1
1
  module NeptuneCoffee
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -18,12 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "trollop"
22
- spec.add_dependency "extlib" # for camel_case
23
- spec.add_dependency "coderay"
24
- spec.add_dependency "guard"
21
+ spec.add_dependency "trollop", "~> 2.0"
22
+ spec.add_dependency "extlib" , "~> 0.9" # for camel_case
23
+ spec.add_dependency "coderay", "~> 1.1"
24
+ spec.add_dependency "guard" , "2.2"
25
25
 
26
26
  spec.add_development_dependency "bundler", "~> 1.3"
27
- spec.add_development_dependency "rake"
28
- spec.add_development_dependency 'rspec', '~> 2.14.0'
27
+ spec.add_development_dependency "rake", "~> 10.1"
28
+ spec.add_development_dependency 'rspec', '~> 2.14.0'
29
29
  end
@@ -21,8 +21,8 @@ describe JavascriptGenerator do
21
21
  Pathname["foo/bar/file2"]
22
22
  ]
23
23
 
24
- module_js.should == <<ENDJS
25
- define([
24
+ module_js.should ==
25
+ "define([
26
26
  './bar/namespace',
27
27
  './bar/file1',
28
28
  './bar/file2',
@@ -32,41 +32,33 @@ define([
32
32
  if (typeof File1 == 'function') {Bar.File1 = File1; File1.namespace = Bar;}
33
33
  if (typeof File2 == 'function') {Bar.File2 = File2; File2.namespace = Bar;}
34
34
  return Bar;
35
- });
36
- ENDJS
35
+ });"
37
36
  end
38
37
 
39
38
  it "namespace_js" do
40
39
  namespace_js = JavascriptGenerator.new(Pathname["foo"], Pathname["foo/bar"]).namespace [
41
40
  Pathname["foo/bar/sub_dir1"], Pathname["foo/bar/sub_dir2"]
42
41
  ]
43
- namespace_js.should == <<ENDJS
44
- define([
45
- './sub_dir1/namespace',
46
- './sub_dir2/namespace'
47
- ], function(SubDir1, SubDir2) {
42
+ namespace_js.should ==
43
+ "define([], function() {
48
44
  var Bar = (function() {
49
45
  function Bar() {}
50
46
  return Bar;
51
47
  })();
52
- Bar.SubDir1 = SubDir1; SubDir1.namespace = Bar;
53
- Bar.SubDir2 = SubDir2; SubDir2.namespace = Bar;
54
48
  return Bar;
55
- });
56
- ENDJS
49
+ });"
57
50
  end
58
51
 
59
52
  it "namespace_js with no subdirs" do
60
53
  namespace_js = JavascriptGenerator.new(Pathname["foo"], Pathname["foo/bar"]).namespace []
61
- namespace_js.should == <<ENDJS
62
- define([], function() {
54
+ namespace_js.should ==
55
+ "define([], function() {
63
56
  var Bar = (function() {
64
57
  function Bar() {}
65
58
  return Bar;
66
59
  })();
67
60
  return Bar;
68
- });
69
- ENDJS
61
+ });"
70
62
  end
71
63
 
72
64
  end
metadata CHANGED
@@ -1,111 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neptune_coffee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
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-07-09 00:00:00.000000000 Z
11
+ date: 2014-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trollop
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: extlib
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '0.9'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '0.9'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: coderay
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '1.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '1.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: guard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '2.2'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '2.2'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '1.3'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.3'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '10.1'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '10.1'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: 2.14.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: 2.14.0
111
111
  description: opinionated javascript-AMD-module generator
@@ -116,12 +116,13 @@ executables:
116
116
  extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
- - .gitignore
119
+ - ".gitignore"
120
120
  - CHANGELOG.md
121
121
  - Gemfile
122
122
  - LICENSE.txt
123
123
  - README.md
124
124
  - Rakefile
125
+ - TODO.md
125
126
  - bin/neptune_coffee
126
127
  - examples/after/geometry.js
127
128
  - examples/after/geometry/box.js
@@ -136,6 +137,8 @@ files:
136
137
  - examples/before/geometry/solids/cone.js
137
138
  - lib/neptune_coffee.rb
138
139
  - lib/neptune_coffee/generator.rb
140
+ - lib/neptune_coffee/generators/module.js.erb
141
+ - lib/neptune_coffee/generators/namespace.js.erb
139
142
  - lib/neptune_coffee/guard.rb
140
143
  - lib/neptune_coffee/javascript_generator.rb
141
144
  - lib/neptune_coffee/simple_directory_structure.rb
@@ -156,17 +159,17 @@ require_paths:
156
159
  - lib
157
160
  required_ruby_version: !ruby/object:Gem::Requirement
158
161
  requirements:
159
- - - '>='
162
+ - - ">="
160
163
  - !ruby/object:Gem::Version
161
164
  version: '0'
162
165
  required_rubygems_version: !ruby/object:Gem::Requirement
163
166
  requirements:
164
- - - '>='
167
+ - - ">="
165
168
  - !ruby/object:Gem::Version
166
169
  version: '0'
167
170
  requirements: []
168
171
  rubyforge_project:
169
- rubygems_version: 2.0.7
172
+ rubygems_version: 2.4.1
170
173
  signing_key:
171
174
  specification_version: 4
172
175
  summary: NeptuneCoffee is an opinionated module generator. Modules and namespaces