cog 0.0.10 → 0.0.11
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.
- data/API.rdoc +4 -31
- data/Default.cogfile +8 -5
- data/bin/cog +61 -51
- data/lib/cog.rb +18 -2
- data/lib/cog/config.rb +60 -42
- data/lib/cog/config/cogfile.rb +76 -0
- data/lib/cog/errors.rb +16 -0
- data/lib/cog/generator.rb +138 -0
- data/lib/cog/spec_helpers.rb +35 -0
- data/lib/cog/spec_helpers/matchers.rb +17 -17
- data/lib/cog/spec_helpers/matchers/match_maker.rb +51 -0
- data/lib/cog/spec_helpers/runner.rb +9 -5
- data/lib/cog/tool.rb +51 -0
- data/lib/cog/version.rb +3 -0
- data/templates/{snippets → cog/snippets}/c++/generated_warning.h.erb +0 -0
- data/templates/{snippets → cog/snippets}/generated_warning.txt +0 -0
- data/templates/cog/tool/API.rdoc.erb +7 -0
- data/templates/cog/tool/Gemfile.erb +4 -0
- data/templates/cog/tool/LICENSE.erb +18 -0
- data/templates/cog/tool/README.markdown.erb +18 -0
- data/templates/cog/tool/Rakefile.erb +15 -0
- data/templates/cog/tool/generator.rb.erb +5 -0
- data/templates/cog/tool/tool.gemspec.erb +18 -0
- data/templates/cog/tool/tool.rb.erb +4 -0
- data/templates/cog/tool/version.rb.erb +5 -0
- metadata +21 -19
- data/lib/cog/cogfile.rb +0 -65
- data/lib/cog/meta.rb +0 -9
- data/lib/cog/meta/gen_gen.rb +0 -85
- data/lib/cog/meta/mirror_gen.rb +0 -39
- data/lib/cog/mixins.rb +0 -13
- data/lib/cog/mixins/mirror.rb +0 -61
- data/lib/cog/mixins/uses_templates.rb +0 -152
- data/lib/cog_version.rb +0 -3
- data/templates/c++/mirror-abstract.cpp.erb +0 -0
- data/templates/c++/mirror-abstract.h.erb +0 -6
- data/templates/c++/mirror-impl.cpp.erb +0 -1
- data/templates/c++/mirror-impl.h.erb +0 -0
- data/templates/mirror.rb.erb +0 -10
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'cog/config'
|
2
|
+
require 'cog/errors'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Cog
|
6
|
+
|
7
|
+
# Generators have the ability to #stamp templates into source code.
|
8
|
+
#
|
9
|
+
# This module defines a low-level interface for writing generators. To use it,
|
10
|
+
# just include the Generator module in your class or object.
|
11
|
+
module Generator
|
12
|
+
|
13
|
+
# A list of available project generators
|
14
|
+
def self.available
|
15
|
+
[:dummy1, :dummy2]
|
16
|
+
end
|
17
|
+
|
18
|
+
# Get the template with the given name.
|
19
|
+
#
|
20
|
+
# ==== Parameters
|
21
|
+
# * +path+ - a path to a template file which is relative to
|
22
|
+
# one of the template directories
|
23
|
+
#
|
24
|
+
# ==== Options
|
25
|
+
# * <tt>:absolute</tt> - is the +path+ argument absolute? (default: +false+)
|
26
|
+
#
|
27
|
+
# ==== Returns
|
28
|
+
# An instance of ERB.
|
29
|
+
def get_template(path, opt={})
|
30
|
+
path += '.erb'
|
31
|
+
fullpath = if opt[:absolute]
|
32
|
+
path
|
33
|
+
else
|
34
|
+
Config.instance.template_paths.inject('') do |found, prefix|
|
35
|
+
x = File.join prefix, path
|
36
|
+
found.empty? && File.exists?(x) ? x : found
|
37
|
+
end
|
38
|
+
end
|
39
|
+
raise Errors::MissingTemplate.new fullpath unless File.exists? fullpath
|
40
|
+
ERB.new File.read(fullpath), 0, '>'
|
41
|
+
end
|
42
|
+
|
43
|
+
# Stamp a template +source+ onto a +destination+.
|
44
|
+
#
|
45
|
+
# ==== Arguments
|
46
|
+
# * +template_path+ - a path to a template file which is relative to one
|
47
|
+
# of the template directories
|
48
|
+
# * +destination+ - a path to which the generated file should be written
|
49
|
+
#
|
50
|
+
# ==== Options
|
51
|
+
# * <tt>:absolute_template_path</tt> - is the +template_path+ argument absolute? (default: +false+)
|
52
|
+
def stamp(template_path, destination, opt={})
|
53
|
+
t = get_template template_path, :absolute => opt[:absolute_template_path]
|
54
|
+
b = opt[:binding] || binding
|
55
|
+
FileUtils.mkpath File.dirname(destination) unless File.exists? destination
|
56
|
+
scratch = "#{destination}.scratch"
|
57
|
+
File.open(scratch, 'w') {|file| file.write t.result(b)}
|
58
|
+
if same? destination, scratch
|
59
|
+
FileUtils.rm scratch
|
60
|
+
else
|
61
|
+
puts "Generated #{destination}"
|
62
|
+
FileUtils.mv scratch, destination
|
63
|
+
end
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
# Copy a file from +src+ to +dest+, but only if +dest+ does not already exist.
|
68
|
+
def copy_if_missing(src, dest)
|
69
|
+
unless File.exists? dest
|
70
|
+
FileUtils.cp src, dest
|
71
|
+
puts "Created #{dest}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Recursively create directories in the given path if they are missing.
|
76
|
+
def touch_path(*path_components)
|
77
|
+
path = File.join path_components
|
78
|
+
unless File.exists? path
|
79
|
+
FileUtils.mkdir_p path
|
80
|
+
puts "Created #{path}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# File extension for a snippet of the given source code language.
|
85
|
+
# ==== Example
|
86
|
+
# snippet_extension 'c++' # => 'h'
|
87
|
+
def snippet_extension(lang = 'text')
|
88
|
+
case lang
|
89
|
+
when /(c\+\+|c|objc)/i
|
90
|
+
'h'
|
91
|
+
else
|
92
|
+
'txt'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# A warning that indicates a file is maintained by a generator
|
97
|
+
def generated_warning
|
98
|
+
lang = Config.instance.language
|
99
|
+
t = get_template "snippets/#{lang}/generated_warning.#{snippet_extension lang}", :cog_template => true
|
100
|
+
t.result(binding)
|
101
|
+
end
|
102
|
+
|
103
|
+
def include_guard_begin(name)
|
104
|
+
full = "COG_INCLUDE_GUARD_#{name.upcase}"
|
105
|
+
"#ifndef #{full}\n#define #{full}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def include_guard_end
|
109
|
+
"#endif // COG_INCLUDE_GUARD_[...]"
|
110
|
+
end
|
111
|
+
|
112
|
+
def namespace_begin(name)
|
113
|
+
return if name.nil?
|
114
|
+
case Config.instance.language
|
115
|
+
when /c\+\+/
|
116
|
+
"namespace #{name} {"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def namespace_end(name)
|
121
|
+
return if name.nil?
|
122
|
+
case Config.instance.language
|
123
|
+
when /c\+\+/
|
124
|
+
"} // namespace #{name}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
def same?(original, scratch) # :nodoc:
|
130
|
+
if File.exists? original
|
131
|
+
File.read(original) == File.read(scratch)
|
132
|
+
else
|
133
|
+
false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
data/lib/cog/spec_helpers.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'cog/spec_helpers/runner'
|
2
2
|
require 'cog/spec_helpers/matchers'
|
3
|
+
require 'fileutils'
|
3
4
|
|
4
5
|
module Cog
|
5
6
|
|
@@ -24,6 +25,40 @@ module Cog
|
|
24
25
|
#
|
25
26
|
# end
|
26
27
|
module SpecHelpers
|
28
|
+
|
29
|
+
# Absolute path to the root spec directory
|
30
|
+
def spec_root
|
31
|
+
File.expand_path File.join(File.dirname(__FILE__), '..', '..', 'spec')
|
32
|
+
end
|
33
|
+
|
34
|
+
# Directory of an active spec fixture.
|
35
|
+
def active_fixture_dir
|
36
|
+
File.join spec_root, 'active_fixture'
|
37
|
+
end
|
38
|
+
|
39
|
+
# Path to the Cogfile in the active spec fixture
|
40
|
+
def cogfile_path
|
41
|
+
File.join active_fixture_dir, 'Cogfile'
|
42
|
+
end
|
43
|
+
|
44
|
+
# Path to the cog directory in the active spec fixture
|
45
|
+
def cog_directory
|
46
|
+
File.join active_fixture_dir, 'cog'
|
47
|
+
end
|
48
|
+
|
49
|
+
# The next cog spec will execute in a fresh copy of the given fixture directory.
|
50
|
+
# Fixture directories are stored in <tt>spec/fixtures</tt>.
|
51
|
+
def use_fixture(name)
|
52
|
+
path = File.join spec_root, 'fixtures', name.to_s
|
53
|
+
if File.exists?(path) && File.directory?(path)
|
54
|
+
FileUtils.rmtree active_fixture_dir if File.exists? active_fixture_dir
|
55
|
+
FileUtils.cp_r path, active_fixture_dir
|
56
|
+
Dir.chdir active_fixture_dir
|
57
|
+
else
|
58
|
+
throw :invalid_fixture_name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
27
62
|
end
|
28
63
|
|
29
64
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'cog/spec_helpers/matchers/match_maker'
|
1
2
|
require 'rspec'
|
2
3
|
|
3
4
|
module Cog
|
@@ -6,26 +7,25 @@ module Cog
|
|
6
7
|
# Extra should or should_not matchers for RSpec.
|
7
8
|
module Matchers
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@second_line = o.readline
|
15
|
-
/help.*code gen/ =~ @second_line
|
16
|
-
end
|
17
|
-
end
|
18
|
-
def failure_message
|
19
|
-
"expected #{@runner} to show the default help text, got #{@first_line.inspect}"
|
20
|
-
end
|
21
|
-
def negative_failure_message
|
22
|
-
"expected #{@runner} to not show the default help text, got #{@first_line.inspect}"
|
10
|
+
# The target Invocation should output the default help text
|
11
|
+
def show_help
|
12
|
+
match_maker do
|
13
|
+
message { "to [show|not show] the default help text, got #{lines.first.inspect}" }
|
14
|
+
test { (/help.*code gen/ =~ lines[1]) }
|
23
15
|
end
|
24
16
|
end
|
25
17
|
|
26
|
-
# The target Invocation should
|
27
|
-
def
|
28
|
-
|
18
|
+
# The target Invocation should create a +Cogfile+ where none existed before
|
19
|
+
def make(path)
|
20
|
+
match_maker do
|
21
|
+
message { "to [create|not create] the #{path}" }
|
22
|
+
before do
|
23
|
+
@existed = File.exists? path
|
24
|
+
end
|
25
|
+
test do
|
26
|
+
!@existed && File.exists?(path)
|
27
|
+
end
|
28
|
+
end
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Cog
|
2
|
+
module SpecHelpers
|
3
|
+
module Matchers
|
4
|
+
|
5
|
+
class MatchMaker
|
6
|
+
attr_reader :lines
|
7
|
+
|
8
|
+
# Define the failure message
|
9
|
+
def message(&block)
|
10
|
+
@msg_block = block
|
11
|
+
end
|
12
|
+
|
13
|
+
# Define a block which runs before the Invocation
|
14
|
+
def before(&block)
|
15
|
+
@before_block = block
|
16
|
+
end
|
17
|
+
|
18
|
+
# Define the test which runs after the Invocation
|
19
|
+
def test(&block)
|
20
|
+
@test_block = block
|
21
|
+
end
|
22
|
+
|
23
|
+
def matches?(runner) # :nodoc:
|
24
|
+
@runner = runner
|
25
|
+
instance_eval &@before_block unless @before_block.nil?
|
26
|
+
@runner.exec do |input, output, error|
|
27
|
+
@lines = output.readlines
|
28
|
+
end
|
29
|
+
instance_eval &@test_block
|
30
|
+
end
|
31
|
+
def failure_message # :nodoc:
|
32
|
+
msg = instance_eval &@msg_block
|
33
|
+
msg = msg.gsub /\[([^\|\]]*)(?:\|([^\]]*)\])?/, '\1'
|
34
|
+
"expected #{@runner} #{msg}"
|
35
|
+
end
|
36
|
+
def negative_failure_message # :nodoc:
|
37
|
+
msg = instance_eval &@msg_block
|
38
|
+
msg = msg.gsub /\[([^\|\]]*)(?:\|([^\]]*)\])?/, '\2'
|
39
|
+
"expected #{@runner} #{msg}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def match_maker(&block)
|
44
|
+
m = MatchMaker.new
|
45
|
+
m.instance_eval &block
|
46
|
+
m
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -4,10 +4,10 @@ module Cog
|
|
4
4
|
module SpecHelpers
|
5
5
|
|
6
6
|
# Points to the +cog+ command-line app
|
7
|
-
class
|
7
|
+
class Runner
|
8
8
|
|
9
9
|
def initialize(path_to_cl_app)
|
10
|
-
@cog = path_to_cl_app
|
10
|
+
@cog = File.expand_path path_to_cl_app
|
11
11
|
end
|
12
12
|
|
13
13
|
# Run cog with the given arguments
|
@@ -16,8 +16,8 @@ module Cog
|
|
16
16
|
# An instance of Invocation configured with the arguments. Use should and
|
17
17
|
# should_not with the custom Matchers
|
18
18
|
def run(*args)
|
19
|
-
args
|
20
|
-
Invocation.new
|
19
|
+
args = ['bundle', 'exec', @cog] + args
|
20
|
+
Invocation.new(args.collect {|x| x.to_s})
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -30,11 +30,15 @@ module Cog
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def exec(*args, &block) # :nodoc:
|
33
|
+
@s = ([File.basename @cmd[2]] + @cmd.slice(3..-1)).join ' '
|
33
34
|
Open3.popen3 *@cmd do |i,o,e,t|
|
34
35
|
block.call i,o,e
|
35
36
|
end
|
36
37
|
end
|
37
|
-
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
"`#{@s}`"
|
41
|
+
end
|
38
42
|
end
|
39
43
|
|
40
44
|
end
|
data/lib/cog/tool.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'cog/config'
|
2
|
+
require 'cog/generator'
|
3
|
+
|
4
|
+
module Cog
|
5
|
+
|
6
|
+
class Tool
|
7
|
+
|
8
|
+
# Lower case command-line version of the name
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# Capitalized module name
|
12
|
+
attr_reader :module_name
|
13
|
+
|
14
|
+
# Name of the person who will be given copyright for the generated code
|
15
|
+
attr_reader :author
|
16
|
+
|
17
|
+
# Email address of the author
|
18
|
+
attr_reader :email
|
19
|
+
|
20
|
+
# A one-line description of the tool
|
21
|
+
attr_reader :description
|
22
|
+
|
23
|
+
# A list of available tools
|
24
|
+
def self.available
|
25
|
+
# TODO: use paths to instantiate a list of Tool objects
|
26
|
+
paths = ENV['COG_TOOLS'] || []
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.generate_tool(name)
|
30
|
+
Object.new.instance_eval do
|
31
|
+
class << self ; include Generator ; end
|
32
|
+
@name = name.to_s.downcase
|
33
|
+
@module_name = name.to_s.capitalize
|
34
|
+
@author = '<Your name goes here>'
|
35
|
+
@email = 'youremail@...'
|
36
|
+
@description = 'A one-liner'
|
37
|
+
@cog_version = Cog::VERSION
|
38
|
+
stamp 'cog/tool/tool.rb', "#{@name}/lib/#{@name}.rb"
|
39
|
+
stamp 'cog/tool/version.rb', "#{@name}/lib/#{@name}/version.rb"
|
40
|
+
stamp 'cog/tool/generator.rb', "#{@name}/cog/templates/#{@name}/generator.rb.erb"
|
41
|
+
stamp 'cog/tool/Gemfile', "#{@name}/Gemfile"
|
42
|
+
stamp 'cog/tool/Rakefile', "#{@name}/Rakefile"
|
43
|
+
stamp 'cog/tool/tool.gemspec', "#{@name}/#{@name}.gemspec"
|
44
|
+
stamp 'cog/tool/API.rdoc', "#{@name}/API.rdoc"
|
45
|
+
stamp 'cog/tool/LICENSE', "#{@name}/LICENSE"
|
46
|
+
stamp 'cog/tool/README.markdown', "#{@name}/README.markdown"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/lib/cog/version.rb
ADDED
File without changes
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2012 <%= @author %>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
|
6
|
+
Rake::RDocTask.new do |rd|
|
7
|
+
rd.main = "API.rdoc"
|
8
|
+
rd.rdoc_files.include("API.rdoc", "lib/**/*.rb")
|
9
|
+
rd.title = '<%= @module_name %> API Docs'
|
10
|
+
end
|
11
|
+
|
12
|
+
spec = eval(File.read('<%= @name %>.gemspec'))
|
13
|
+
|
14
|
+
Gem::PackageTask.new(spec) do |pkg|
|
15
|
+
end
|