cog 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/API.rdoc
CHANGED
@@ -1,33 +1,6 @@
|
|
1
|
-
= cog API
|
1
|
+
= cog API Docs
|
2
2
|
|
3
|
-
+cog+ is a command line
|
4
|
-
which uses code generation. Many of your interactions with +cog+ will be using
|
5
|
-
the command line interface. However, to get any real mileage out of it you'll
|
6
|
-
need to use the API (documented here). For more information on the command line
|
7
|
-
interface see https://github.com/ktonon/cog#cog
|
3
|
+
+cog+ is a command line tool which helps you write code generators.
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
available in it are defined in the Cog::Cogfile class. It is generated for you
|
12
|
-
when you issue this command from a shell in the root directory of your project:
|
13
|
-
|
14
|
-
cog init
|
15
|
-
|
16
|
-
and it will look something like this:
|
17
|
-
|
18
|
-
# All paths are relative to the directory containing this file.
|
19
|
-
|
20
|
-
# The directory in which to place Ruby generators and +ERB+ templates.
|
21
|
-
cog_dir 'cog'
|
22
|
-
|
23
|
-
# The directory in which to place generated application code.
|
24
|
-
app_dir 'src'
|
25
|
-
|
26
|
-
# The default language in which to generate source code.
|
27
|
-
language 'c++'
|
28
|
-
|
29
|
-
== Testing
|
30
|
-
|
31
|
-
The tests are written in +RSpec+ and can be found in the <tt>spec/</tt>
|
32
|
-
directory. Custom matchers are available to make writing specs easier. See
|
33
|
-
Cog::SpecHelpers for more details.
|
5
|
+
This is the API docs. For a more general introduction to +cog+ visit
|
6
|
+
https://github.com/ktonon/cog#readme
|
data/Default.cogfile
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# All paths are relative to the directory containing this file.
|
2
2
|
|
3
|
-
#
|
4
|
-
|
3
|
+
# Define the directory in which to find project generators
|
4
|
+
project_generators_path 'cog/generators'
|
5
5
|
|
6
|
-
#
|
7
|
-
|
6
|
+
# Define the directory in which to find custom project templates
|
7
|
+
project_templates_path 'cog/templates'
|
8
8
|
|
9
|
-
#
|
9
|
+
# Define the directory to which project source code is generated
|
10
|
+
project_source_path 'src'
|
11
|
+
|
12
|
+
# Define the default language in which to generated application source code
|
10
13
|
language 'c++'
|
data/bin/cog
CHANGED
@@ -1,81 +1,91 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# 1.9 adds realpath to resolve symlinks; 1.8 doesn't
|
3
|
-
# have this method, so we add it so we get resolved symlinks
|
4
|
-
# and compatibility
|
5
|
-
unless File.respond_to? :realpath
|
6
|
-
class File #:nodoc:
|
7
|
-
def self.realpath path
|
8
|
-
return realpath(File.readlink(path)) if symlink?(path)
|
9
|
-
path
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
$: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
|
14
|
-
require 'rubygems'
|
15
|
-
require 'active_support/core_ext'
|
16
|
-
require 'cog'
|
17
|
-
require 'cog_version'
|
18
2
|
require 'gli'
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
4
|
+
require 'cog'
|
5
|
+
require 'active_support/core_ext'
|
19
6
|
require 'fileutils'
|
20
7
|
|
21
8
|
include GLI::App
|
22
9
|
|
23
10
|
program_desc 'This is a utility to help you write code generators.'
|
24
11
|
|
25
|
-
version Cog::VERSION
|
26
|
-
|
27
|
-
desc 'Write extra information'
|
28
|
-
switch [:v,:verbose]
|
12
|
+
# version Cog::VERSION
|
29
13
|
|
30
|
-
desc 'Add cog to
|
14
|
+
desc 'Add cog to the project in the present working directory'
|
15
|
+
skips_pre
|
31
16
|
command :init do |c|
|
32
|
-
|
33
|
-
|
34
|
-
|
17
|
+
|
18
|
+
c.action do |global_options, options, args|
|
19
|
+
Cog.initialize_project
|
35
20
|
end
|
36
21
|
end
|
37
22
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
23
|
+
desc 'Create a tool (or leave name blank to list available tools)'
|
24
|
+
arg_name 'name'
|
25
|
+
skips_pre
|
26
|
+
command :tool do |c|
|
27
|
+
|
28
|
+
c.action do |global_options, options, args|
|
29
|
+
if args.empty?
|
30
|
+
puts 'Available tools:'
|
31
|
+
puts (Cog::Tool.available.collect {|tool| " #{tool}"}.join "\n")
|
32
|
+
else
|
33
|
+
args.each do |name|
|
34
|
+
unless File.exists? name
|
35
|
+
Cog::Tool.generate_tool name
|
36
|
+
else
|
37
|
+
puts "Could not create tool for '#{name}', a file or directory already exists with that name"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'Create a generator (or leave name blank to list project generators)'
|
45
|
+
arg_name 'name'
|
46
|
+
command :generator do |c|
|
47
|
+
|
48
|
+
c.desc 'which tool to use to create the generator'
|
49
|
+
c.arg_name 'tool_name'
|
50
|
+
c.default_value 'generic'
|
51
|
+
c.flag :tool
|
52
|
+
|
53
|
+
c.action do |global_options, options, args|
|
54
|
+
if args.empty?
|
55
|
+
puts 'Project generators:'
|
56
|
+
puts (Cog::Generator.available.collect {|gen| " #{gen}"}.join "\n")
|
57
|
+
else
|
58
|
+
args.each do |name|
|
59
|
+
# TODO: create the generator
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
56
64
|
|
57
65
|
desc 'List supported languages'
|
66
|
+
skips_pre
|
58
67
|
command :languages do |c|
|
59
|
-
|
68
|
+
|
69
|
+
c.action do
|
60
70
|
puts 'c++'
|
61
71
|
end
|
62
72
|
end
|
63
73
|
|
64
|
-
|
74
|
+
desc 'Run generators in the current project'
|
75
|
+
arg_name 'generator_name'
|
76
|
+
command :run do |c|
|
77
|
+
end
|
78
|
+
|
79
|
+
pre do |global_options, command, options, args|
|
65
80
|
# Pre logic here
|
66
81
|
# Return true to proceed; false to abort and not call the
|
67
82
|
# chosen command
|
68
83
|
# Use skips_pre before a command to skip this block
|
69
84
|
# on that command only
|
70
|
-
|
71
|
-
|
72
|
-
puts 'No Cogfile could be found'
|
73
|
-
false
|
74
|
-
elsif cogfile && command && command.name == :init
|
75
|
-
puts "A Cogfile already exists at #{cogfile.cogfile_path.inspect}"
|
85
|
+
unless Cog::Config.instance.project?
|
86
|
+
puts 'No Cogfile could be found. Run `cog init` to prepare an existing project.'
|
76
87
|
false
|
77
88
|
else
|
78
|
-
global[:cogfile] = cogfile
|
79
89
|
true
|
80
90
|
end
|
81
91
|
end
|
data/lib/cog.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
require 'cog/config'
|
2
|
-
require 'cog/
|
3
|
-
require 'cog/
|
2
|
+
require 'cog/generator'
|
3
|
+
require 'cog/tool'
|
4
|
+
require 'cog/version'
|
5
|
+
require 'fileutils'
|
4
6
|
|
7
|
+
# The static methods on this top level module mirror the commands available to
|
8
|
+
# the +cog+ command line utility.
|
5
9
|
module Cog
|
10
|
+
|
11
|
+
# Prepare the project in the present working directory for use with +cog+
|
12
|
+
def self.initialize_project
|
13
|
+
Object.new.instance_eval do
|
14
|
+
class << self ; include Generator ; end
|
15
|
+
copy_if_missing File.join(Config.gem_dir, 'Default.cogfile'), 'Cogfile'
|
16
|
+
config = Config.instance
|
17
|
+
touch_path config.project_generators_path
|
18
|
+
touch_path config.project_templates_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
6
22
|
end
|
data/lib/cog/config.rb
CHANGED
@@ -1,45 +1,60 @@
|
|
1
|
-
require '
|
1
|
+
require 'cog/config/cogfile'
|
2
2
|
require 'singleton'
|
3
|
-
require 'cog/cogfile'
|
4
3
|
|
5
4
|
module Cog
|
6
5
|
|
7
|
-
# This interface is intended for use within generators.
|
8
|
-
#
|
6
|
+
# This interface is intended for use within generators. Apps can customize
|
7
|
+
# Instances of this type
|
8
|
+
# can be configured via Cogfile files.
|
9
9
|
class Config
|
10
10
|
|
11
|
-
#
|
12
|
-
attr_reader :app_dir
|
13
|
-
|
14
|
-
# Path to the +Cogfile+.
|
11
|
+
# Path to the project's +Cogfile+.
|
15
12
|
attr_reader :cogfile_path
|
16
13
|
|
17
|
-
#
|
18
|
-
# control exactly how the code is going to be generated.
|
19
|
-
attr_reader :generator_dir
|
20
|
-
|
21
|
-
# Default language in which to generated application source code.
|
14
|
+
# Default language in which to generated application source code
|
22
15
|
attr_reader :language
|
23
16
|
|
24
|
-
# Directory in which
|
17
|
+
# Directory in which to find project generators
|
18
|
+
attr_reader :project_generators_path
|
19
|
+
|
20
|
+
# Directory in which the project's +Cogfile+ is found
|
25
21
|
attr_reader :project_root
|
26
22
|
|
27
|
-
# Directory
|
28
|
-
attr_reader :
|
23
|
+
# Directory to which project source code is generated
|
24
|
+
attr_reader :project_source_path
|
25
|
+
|
26
|
+
# Directory in which to find custom project templates
|
27
|
+
attr_reader :project_templates_path
|
29
28
|
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
@cogfile_path = File.expand_path path
|
35
|
-
@project_root = File.dirname @cogfile_path
|
36
|
-
cogfile = Cogfile.new self
|
37
|
-
cogfile.interpret
|
29
|
+
# Are we operating in the context of a project?
|
30
|
+
# That is, could a Cogfile be found?
|
31
|
+
def project?
|
32
|
+
!@project_root.nil?
|
38
33
|
end
|
39
|
-
|
40
|
-
#
|
34
|
+
|
35
|
+
# A list of directories in which to find ERB template files.
|
36
|
+
# Priority should be given first to last.
|
37
|
+
def template_paths
|
38
|
+
[@project_templates_path, @tool_templates_path, File.join(Config.gem_dir, 'templates')].compact
|
39
|
+
end
|
40
|
+
|
41
|
+
# Location of the installed cog gem
|
42
|
+
def self.gem_dir # :nodoc:
|
43
|
+
spec = Gem.loaded_specs['cog']
|
44
|
+
if spec.nil?
|
45
|
+
# The current __FILE__ is:
|
46
|
+
# ${COG_GEM_ROOT}/lib/cog/config.rb
|
47
|
+
File.expand_path File.join(File.dirname(__FILE__), '..', '..')
|
48
|
+
else
|
49
|
+
spec.gem_dir
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# The singleton instance.
|
54
|
+
#
|
55
|
+
# Initialized using the +Cogfile+ for the current project, if any can be
|
56
|
+
# found. If not, then #project? will be +false+.
|
41
57
|
#
|
42
|
-
# Initialized using the +Cogfile+ for the current project.
|
43
58
|
# The +Cogfile+ will be looked for in the present working directory. If none
|
44
59
|
# is found there the parent directory will be checked, and then the
|
45
60
|
# grandparent, and so on.
|
@@ -47,8 +62,11 @@ module Cog
|
|
47
62
|
# ==== Returns
|
48
63
|
# An instance of Cogfile which has been configured with a +Cogfile+. If no
|
49
64
|
# such file was found then +nil+.
|
50
|
-
def self.
|
51
|
-
return @
|
65
|
+
def self.instance
|
66
|
+
return @instance if @instance
|
67
|
+
@instance = self.new
|
68
|
+
|
69
|
+
# Attempt to find a Cogfile
|
52
70
|
parts = Dir.pwd.split File::SEPARATOR
|
53
71
|
i = parts.length
|
54
72
|
while i >= 0 && !File.exists?(File.join(parts.slice(0, i) + ['Cogfile']))
|
@@ -56,22 +74,22 @@ module Cog
|
|
56
74
|
end
|
57
75
|
path = File.join(parts.slice(0, i) + ['Cogfile']) if i >= 0
|
58
76
|
if path && File.exists?(path)
|
59
|
-
@
|
77
|
+
@instance.instance_eval do
|
78
|
+
@cogfile_path = File.expand_path path
|
79
|
+
@project_root = File.dirname @cogfile_path
|
80
|
+
cogfile = Cogfile.new self
|
81
|
+
cogfile.interpret
|
82
|
+
end
|
60
83
|
end
|
84
|
+
|
85
|
+
@instance
|
61
86
|
end
|
62
87
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
# The current __FILE__ is:
|
68
|
-
# ${COG_GEM_ROOT}/lib/cog/config.rb
|
69
|
-
File.expand_path File.join(File.dirname(__FILE__), '..', '..')
|
70
|
-
else
|
71
|
-
spec.gem_dir
|
72
|
-
end
|
88
|
+
private
|
89
|
+
|
90
|
+
def initialize
|
91
|
+
@project_root = nil
|
73
92
|
end
|
74
|
-
|
93
|
+
|
75
94
|
end
|
76
|
-
|
77
95
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Cog
|
2
|
+
class Config
|
3
|
+
|
4
|
+
# In your project's +Cogfile+, +self+ has been set to an instance of this class.
|
5
|
+
#
|
6
|
+
# ==== Example +Cogfile+
|
7
|
+
# project_generators_path 'cog/generators'
|
8
|
+
# project_templates_path 'cog/templates'
|
9
|
+
# project_source_path 'src'
|
10
|
+
# language 'c++'
|
11
|
+
#
|
12
|
+
# Typing `cog init` will create a +Cogfile+ in the present working directory.
|
13
|
+
#
|
14
|
+
# +Cogfile+ files are used to configure an instance of Config.
|
15
|
+
class Cogfile
|
16
|
+
|
17
|
+
def initialize(config) # :nodoc:
|
18
|
+
@config = config
|
19
|
+
end
|
20
|
+
|
21
|
+
# Interpret the Cogfile and initialize @config
|
22
|
+
def interpret # :nodoc:
|
23
|
+
eval File.read(@config.cogfile_path), binding
|
24
|
+
rescue Exception => e
|
25
|
+
raise CogfileError.new(e.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Define the directory in which to find project generators
|
29
|
+
# ==== Arguments
|
30
|
+
# * +path+ - A file system path
|
31
|
+
# * +absolute+ - If false, the path is relative to the directory containing the +Cogfile+
|
32
|
+
def project_generators_path(path, absolute=false)
|
33
|
+
@config.instance_eval do
|
34
|
+
@project_generators_path = absolute ? path : File.join(project_root, path)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Define the directory in which to find custom project templates
|
39
|
+
# ==== Arguments
|
40
|
+
# * +path+ - A file system path
|
41
|
+
# * +absolute+ - If false, the path is relative to the directory containing the +Cogfile+
|
42
|
+
def project_templates_path(path, absolute=false)
|
43
|
+
@config.instance_eval do
|
44
|
+
@project_templates_path = absolute ? path : File.join(project_root, path)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Define the directory to which project source code is generated
|
49
|
+
# ==== Arguments
|
50
|
+
# * +path+ - A file system path
|
51
|
+
# * +absolute+ - If false, the path is relative to the directory containing the +Cogfile+
|
52
|
+
def project_source_path(path, absolute=false)
|
53
|
+
@config.instance_eval do
|
54
|
+
@project_source_path = absolute ? path : File.join(project_root, path)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Define the default language in which to generated application source code
|
59
|
+
# ==== Arguments
|
60
|
+
# * +lang+ - A code for the language. Acceptable values are <tt>c++</tt>.
|
61
|
+
def language(lang)
|
62
|
+
@config.instance_eval do
|
63
|
+
@language = lang
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# For wrapping errors which occur during the processing of a +Cogfile+.
|
69
|
+
class CogfileError < StandardError
|
70
|
+
def message
|
71
|
+
"in Cogfile, " + super
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
data/lib/cog/errors.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Cog
|
2
|
+
|
3
|
+
module Errors
|
4
|
+
# Indiciates an attempt to use a non-existant template.
|
5
|
+
class MissingTemplate < Exception
|
6
|
+
def initialize(template_path)
|
7
|
+
@template_path = template_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
"could not find the template '#{@template_path}'\n#{super}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|