cog 0.0.6 → 0.0.7

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.
@@ -0,0 +1,7 @@
1
+ # All paths are relative to the directory containing this file.
2
+
3
+ # The directory in which to place Ruby generators and +ERB+ templates.
4
+ cog_dir 'cog'
5
+
6
+ # The directory in which to place generated application code.
7
+ app_dir 'src'
data/bin/cog CHANGED
@@ -12,9 +12,10 @@ unless File.respond_to? :realpath
12
12
  end
13
13
  $: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
14
14
  require 'rubygems'
15
- require 'gli'
16
- require 'cog_version'
17
15
  require 'cog'
16
+ require 'cog_version'
17
+ require 'gli'
18
+ require 'fileutils'
18
19
 
19
20
  include GLI
20
21
 
@@ -27,15 +28,37 @@ switch [:v,:verbose]
27
28
 
28
29
  desc 'Add cog to a project by generating a Cogfile in the current directory'
29
30
  command :init do |c|
30
- c.action do |global_options, options, args|
31
- Cog.copy_default_cogfile 'Cogfile'
31
+ c.action do |g,o,a|
32
+ puts "Generated Cogfile"
33
+ FileUtils.cp File.join(Cog::Config.gem_dir, 'Default.cogfile'), 'Cogfile'
34
+ end
35
+ end
36
+
37
+ desc 'Create a new mirror class'
38
+ arg_name 'ClassName'
39
+ command :mirror do |c|
40
+ c.desc 'The target language (see languages command)'
41
+ c.arg_name 'language'
42
+ c.flag [:language, :l]
43
+
44
+ c.desc 'Slash (/) separated prefix for generator, templates, and app code'
45
+ c.arg_name 'path'
46
+ c.flag [:package, :p]
47
+
48
+ c.action do |g,o,a|
49
+ tc = Cog::TemplateController.new
50
+ a.each do |class_name|
51
+ tc.stamp_generator 'mirror', class_name, o
52
+ tc.stamp_module 'mirror-abstract', "abstract_#{class_name}", o
53
+ tc.stamp_module 'mirror-impl', class_name, o
54
+ end
32
55
  end
33
56
  end
34
57
 
35
- desc 'Create a new template'
36
- arg_name 'NAME'
37
- command :template do |c|
38
- c.action do |global_options, options, args|
58
+ desc 'List supported languages'
59
+ command :languages do |c|
60
+ c.action do |g,o,a|
61
+ puts 'c++'
39
62
  end
40
63
  end
41
64
 
@@ -45,7 +68,7 @@ pre do |global, command, options, args|
45
68
  # chosen command
46
69
  # Use skips_pre before a command to skip this block
47
70
  # on that command only
48
- cogfile = Cog::Cogfile.for_project
71
+ cogfile = Cog::Config.for_project
49
72
  if !cogfile && command && command.name != :init
50
73
  puts 'No Cogfile could be found'
51
74
  false
data/lib/cog.rb CHANGED
@@ -1,14 +1,6 @@
1
- require 'cog/cogfile'
1
+ require 'cog/config'
2
2
  require 'cog/template_controller'
3
3
  require 'cog/mixins'
4
- require 'fileutils'
5
4
 
6
5
  module Cog
7
-
8
- # Make a cogfile at the given destination path.
9
- def self.copy_default_cogfile(dest)
10
- puts "Generated #{dest}"
11
- FileUtils.cp Cogfile.default_cogfile_path, dest
12
- end
13
-
14
6
  end
@@ -5,17 +5,13 @@ module Cog
5
5
 
6
6
  # When the +Cogfile+ is processed, +self+ will be the singleton instance of
7
7
  # this object.
8
- class Cogfile
8
+ class Config
9
9
 
10
- # Path to the master +Cogfile+.
11
- def self.master_cogfile_path
12
- File.join gem_dir, 'Master.cogfile'
13
- end
14
-
15
- # Path to the default +Cogfile+.
16
- def self.default_cogfile_path
17
- File.join gem_dir, 'templates/Default.cogfile'
18
- end
10
+ # The directory in which the +Cogfile+ is found.
11
+ attr_reader :project_root
12
+
13
+ # The path to the +Cogfile+.
14
+ attr_reader :cogfile_path
19
15
 
20
16
  # Loads the default +Cogfile+ for the current project.
21
17
  #
@@ -39,12 +35,6 @@ module Cog
39
35
  end
40
36
  end
41
37
 
42
- # Loads the master +Cogfile+.
43
- def self.master
44
- return @master if @master
45
- @master = self.new master_cogfile_path
46
- end
47
-
48
38
  # Initialize from a +Cogfile+ at the given path.
49
39
  def initialize(path)
50
40
  @cogfile_path = File.expand_path path
@@ -56,51 +46,42 @@ module Cog
56
46
  end
57
47
  end
58
48
 
59
- def get_or_set(name, val, &block) # :nodoc:
60
- if val.nil?
61
- instance_variable_get "@#{name}"
62
- else
63
- val = block.call val unless block.nil?
64
- instance_variable_set "@#{name}", val
65
- end
49
+ # The directory in which to place Ruby generators and +ERB+ templates.
50
+ #
51
+ # Can be used as a getter, or a setter within the +Cogfile+. As a setter,
52
+ # +val+ is relative to project_root unless the option <tt>:absolute</tt>
53
+ # is truthy.
54
+ def cog_dir(val=nil, opt={})
55
+ get_or_set :cog_dir, val, opt
66
56
  end
67
57
 
68
- # The directory in which the +Cogfile+ is found.
69
- attr_reader :project_root
70
-
71
- # The path to the +Cogfile+.
72
- attr_reader :cogfile_path
73
-
74
- # The directory in which to find ERB template files. This is relative to
75
- # project_root unless the option <tt>:absolute</tt> is passed.
76
- #
77
- # Can be used as a getter or a setter (within the +Cogfile+).
78
- def template_dir(val=nil, opt={})
79
- get_or_set(:template_dir, val) do |val|
80
- if opt[:absolute]
81
- val
82
- else
83
- File.join project_root, val
84
- end
85
- end
58
+ # The directory in which to place generated application code.
59
+ #
60
+ # Can be used as a getter, or a setter within the +Cogfile+. As a setter,
61
+ # +val+ is relative to project_root unless the option <tt>:absolute</tt>
62
+ # is truthy.
63
+ def app_dir(val=nil, opt={})
64
+ get_or_set :app_dir, val, opt
86
65
  end
87
66
 
88
- # The directory in which application code can be found. This is where
89
- # generated code will go. Probably along side non-generated code. It is
90
- # relative to project_root unless the option <tt>:absolute</tt> is passed.
91
- #
92
- # Can be used as a getter or a setter (within the +Cogfile+).
93
- def code_dir(val=nil, opt={})
94
- get_or_set(:code_dir, val) do |val|
95
- if opt[:absolute]
96
- val
97
- else
98
- File.join project_root, val
99
- end
100
- end
67
+ # The path to the routes file which maps defines how generators map to
68
+ # generated application code.
69
+ def routes_path
70
+ File.join cog_dir, 'routes.rb'
71
+ end
72
+
73
+ # The directory in which to find Ruby source files. These are files which
74
+ # control exactly how the code is going to be generated.
75
+ def generator_dir(val=nil, opt={})
76
+ File.join cog_dir, 'generators'
101
77
  end
102
78
 
103
- private
79
+ # The directory in which to find ERB template files.
80
+ def template_dir(val=nil, opt={})
81
+ File.join cog_dir, 'templates'
82
+ end
83
+
84
+ # Location of the installed gem
104
85
  def self.gem_dir
105
86
  spec = Gem.loaded_specs['cog']
106
87
  if spec.nil?
@@ -109,6 +90,16 @@ module Cog
109
90
  spec.gem_dir
110
91
  end
111
92
  end
93
+
94
+ private
95
+ def get_or_set(name, val, opt={}, &block)
96
+ if val.nil?
97
+ instance_variable_get "@#{name}"
98
+ else
99
+ val = File.join project_root, val unless opt[:absolute]
100
+ instance_variable_set "@#{name}", val
101
+ end
102
+ end
112
103
  end
113
104
 
114
105
  # For wrapping errors which occur during the processing of a +Cogfile+.
@@ -4,7 +4,9 @@ module Cog
4
4
 
5
5
  # Modules that extend your code generating classes with helper methods.
6
6
  #
7
- # * Mixins::UsesTemplates has methods for using +ERB+ template files
7
+ # * Mixins::UsesTemplates - methods for using +ERB+ template files.
8
+ # * Mixins::Mirror - code the interface in Ruby and implement in the target
9
+ # langauge.
8
10
  module Mixins
9
11
  end
10
12
 
@@ -0,0 +1,61 @@
1
+ require 'cog/mixins/uses_templates'
2
+ module Cog
3
+ module Mixins
4
+
5
+ # Code the interface in Ruby and implement in the target langauge.
6
+ #
7
+ # <b>Not implemented</b>
8
+ #
9
+ # === Example
10
+ #
11
+ # In Ruby
12
+ # class Dog
13
+ # include Cog::Mixins::Mirror
14
+ #
15
+ # cog_reader :name, Cog::Type.string
16
+ # cog_accessor :age, Cog::Type.int
17
+ #
18
+ # meth :speak
19
+ # end
20
+ #
21
+ # In C++
22
+ # class CogDog
23
+ # {
24
+ # protected:
25
+ # char* _name;
26
+ # int _age;
27
+ # public:
28
+ # AbstractDog();
29
+ # virtual ~AbstractDog();
30
+ #
31
+ # virtual const char* name() const { return _name; }
32
+ #
33
+ # virtual int age() const { return _age; }
34
+ # virtual void setAge(int age) { _age = age; }
35
+ #
36
+ # virtual void speak() = 0;
37
+ # };
38
+ #
39
+ # class Dog : public CogDog
40
+ # {
41
+ # public:
42
+ # Dog();
43
+ # virtual ~Dog();
44
+ #
45
+ # virtual void speak();
46
+ # };
47
+ #
48
+ # The abstract class +CogDog+ will be regenerated whenever the source Ruby
49
+ # specification is changed. The derived C++ class +Dog+ will only be
50
+ # generated once. The C++ compiler will let you know if any abstract methods
51
+ # are missing from +Dog+ when you try to instantiate it.
52
+ module Mirror
53
+ def self.included(base)
54
+ base.include UsesTemplates
55
+ end
56
+
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -1,4 +1,4 @@
1
- require 'cog/cogfile'
1
+ require 'cog/config'
2
2
  require 'erb'
3
3
 
4
4
  module Cog
@@ -6,59 +6,67 @@ module Cog
6
6
 
7
7
  # Mixin for classes that can use templates to generate code
8
8
  module UsesTemplates
9
-
10
- # Use an alternate Cogfile
11
- def using_cogfile(cogfile)
12
- @cogfile = cogfile
13
- end
14
9
 
15
10
  # Get the template with the given name.
16
11
  #
17
12
  # === Parameters
18
13
  # * +path+ - a path to a template file which is relative to
19
- # Cogfile#template_dir and does not include the +.erb+ extension.
14
+ # Config#template_dir and does not include the +.erb+ extension.
15
+ #
16
+ # === Options
17
+ # * <tt>:absolute</tt> - set to +true+ to indicate that path is absolute
18
+ # and should not be prefixed. Default value is +false+.
20
19
  #
21
20
  # === Returns
22
21
  # An instance of ERB.
23
- def get_template(path)
24
- @cogfile ||= Cogfile.for_project
25
- path = File.join @cogfile.template_dir, "#{path}.erb"
26
- unless File.exists? path
27
- raise MissingTemplate.new path
28
- end
22
+ def get_template(path, opt={})
23
+ path += '.erb'
24
+ path = File.join Config.for_project.template_dir, path unless opt[:absolute]
25
+ raise MissingTemplate.new path unless File.exists? path
29
26
  ERB.new File.read(path)
30
27
  end
31
28
 
32
29
  # Stamp this object using the template at the given path.
33
30
  #
34
31
  # === Parameters
35
- # * +path+ - the path to the template to use which is relative to
36
- # Cogfile#template_dir and does not include the +.erb+ extension.
37
- # * +dest+ - the destination path to the generated file which is relative
38
- # to Cogfile#code_dir. If this is not provided, then the generated code
39
- # will be returned as a string.
32
+ # * +path+ - to the template which is relative to Config#template_dir and
33
+ # does not include the +.erb+ extension.
40
34
  #
41
- # === Context
42
- # All keys are added as instance variables to the context that is passed
43
- # into the template.
35
+ # === Options
36
+ # * <tt>:target</tt> - the destination path to the generated file which is
37
+ # relative to either Config#app_dir or Config#cog_dir, depending on the
38
+ # value of the <tt>:target_type</tt> option.
39
+ # * <tt>:target_type</tt> - either <tt>:cog</tt> or <tt>:app</tt>.
40
+ # Determines what path to prefix to the <tt>:target</tt> option. The
41
+ # default value is <tt>:app</tt>
42
+ # * <tt>:use_absolute_path</tt> - set to +true+ to indicate that path is
43
+ # absolute and should not be prefixed. Default value is +false+.
44
+ # * <tt>:binding</tt> - specify an alternate binding to use when resolving
45
+ # the +ERB+ template. If none is provided +self.binding+ will be used.
44
46
  #
45
47
  # === Returns
46
48
  # +nil+ if generated to a file, otherwise returns the generated code as a
47
49
  # string.
48
- def stamp(path, dest=nil, context={})
49
- t = get_template path
50
- context = TemplateContext.new self, context
51
- b = context.instance_eval {binding}
52
- if dest.nil?
50
+ def stamp(path, opt={})
51
+ t = get_template path, :absolute => opt[:use_absolute_path]
52
+ b = opt[:binding] || binding
53
+ target = opt[:target]
54
+ if target.nil?
53
55
  t.result(b)
54
56
  else
55
- dest = File.join @cogfile.code_dir, dest
56
- FileUtils.mkpath File.dirname(dest) unless File.exists? dest
57
+ target_type = opt[:target_type] || :app
58
+ target = case target_type.to_s
59
+ when /cog/i
60
+ File.join Config.for_project.cog_dir, target
61
+ when /app/i
62
+ File.join Config.for_project.app_dir, target
63
+ end
64
+ FileUtils.mkpath File.dirname(target) unless File.exists? target
57
65
  scratch = "#{path}.scratch"
58
66
  File.open(scratch, 'w') {|file| file.write t.result(b)}
59
- unless same? dest, scratch
60
- puts "Generated #{dest}"
61
- FileUtils.mv scratch, dest
67
+ unless same? target, scratch
68
+ puts "Generated #{target}"
69
+ FileUtils.mv scratch, target
62
70
  else
63
71
  FileUtils.rm scratch
64
72
  end
@@ -74,23 +82,6 @@ module Cog
74
82
  false
75
83
  end
76
84
  end
77
-
78
- class TemplateContext
79
- def initialize(obj, context={})
80
- @obj = obj
81
- context.each do |key, value|
82
- instance_variable_set "@#{key}", value
83
- end
84
- end
85
-
86
- def method_missing(meth, *args, &block)
87
- if @obj.respond_to? meth
88
- @obj.method(meth).call *args, &block
89
- else
90
- super
91
- end
92
- end
93
- end
94
85
  end
95
86
 
96
87
  end
@@ -1,16 +1,74 @@
1
1
  require 'cog/mixins/uses_templates'
2
- require 'cog/cogfile'
2
+ require 'cog/config'
3
3
 
4
4
  module Cog
5
5
 
6
6
  class TemplateController
7
7
 
8
8
  include Mixins::UsesTemplates
9
-
10
- def initialize(opt={})
11
- using_cogfile Cogfile.master
9
+
10
+ # Create a ruby generator from a template.
11
+ #
12
+ # === Parameters
13
+ # * +ruby_template+ - name of the ruby template. This is a template
14
+ # which is distributed in the cog gem. It is relative to
15
+ # <tt>templates/</tt>
16
+ # * +generator_name+ - name of the generator
17
+ #
18
+ # === Options
19
+ # * <tt>:language</tt> - only <tt>'c++'</tt> is accepted at this time
20
+ # * <tt>:package</tt> - slash (/) separated path which will prefix
21
+ # +generator_name+
22
+ def stamp_generator(ruby_template, generator_name, opt={})
23
+ template = File.join Config.gem_dir, 'templates', "#{ruby_template}.rb"
24
+ target = "#{generator_name}.rb"
25
+ target = File.join opt[:package], target if opt[:package]
26
+ target = File.join 'generators', target
27
+ stamp template,
28
+ :target => target,
29
+ :target_type => :cog,
30
+ :use_absolute_path => true
31
+ end
32
+
33
+ # Create an app module template from a template.
34
+ #
35
+ # === Parameters
36
+ # * +source_template+ - name of the source template. This is a template
37
+ # which is distributed in the cog gem. It is relative to
38
+ # <tt>templates/{language}/</tt>, where language is specified by the
39
+ # <tt>:language</tt> option. Do not include any file extension such as
40
+ # <tt>.h</tt> (the <tt>:language</tt> will also determine this)
41
+ # * +module_name+ - name of the module. For languages like <tt>:c++</tt>,
42
+ # two templates will be generated (i.e. one <tt>.h</tt> and one
43
+ # <tt>.cpp</tt>)
44
+ #
45
+ # === Options
46
+ # * <tt>:language</tt> - only <tt>'c++'</tt> is accepted at this time
47
+ # * <tt>:package</tt> - slash (/) separated path which will prefix
48
+ # +module_name+
49
+ def stamp_module(source_template, module_name, opt={})
50
+ lang = opt[:language] || 'c++'
51
+ extensions_for_language(lang).each do |ext|
52
+ template = File.join Config.gem_dir, 'templates', lang, "#{source_template}.#{ext}"
53
+ target = "#{module_name}.#{ext}"
54
+ target = File.join opt[:package], target if opt[:package]
55
+ target = File.join 'templates', target
56
+ stamp template,
57
+ :target => target,
58
+ :target_type => :cog,
59
+ :use_absolute_path => true
60
+ end
12
61
  end
13
62
 
63
+ private
64
+ def extensions_for_language(lang)
65
+ case lang.to_s
66
+ when /(cpp|c\+\+)/i
67
+ [:h, :cpp]
68
+ else
69
+ []
70
+ end
71
+ end
14
72
  end
15
73
 
16
74
  end
@@ -1,3 +1,3 @@
1
1
  module Cog
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
  end
File without changes
File without changes
File without changes
File without changes
File without changes
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cog
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kevin Tonon
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-13 00:00:00 Z
18
+ date: 2012-05-15 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rake
@@ -55,9 +55,14 @@ extra_rdoc_files:
55
55
  - API.rdoc
56
56
  files:
57
57
  - bin/cog
58
- - Master.cogfile
59
- - templates/Default.cogfile
60
- - lib/cog/cogfile.rb
58
+ - Default.cogfile
59
+ - templates/c++/mirror-abstract.cpp.erb
60
+ - templates/c++/mirror-abstract.h.erb
61
+ - templates/c++/mirror-impl.cpp.erb
62
+ - templates/c++/mirror-impl.h.erb
63
+ - templates/mirror.rb.erb
64
+ - lib/cog/config.rb
65
+ - lib/cog/mixins/mirror.rb
61
66
  - lib/cog/mixins/uses_templates.rb
62
67
  - lib/cog/mixins.rb
63
68
  - lib/cog/spec_helpers/matchers.rb
@@ -1,10 +0,0 @@
1
- # This is the master Cogfile. It is used by cog.
2
-
3
- # All paths are relative to the directory containing this file.
4
-
5
- # The directory in which to find ERB template files.
6
- template_dir 'templates'
7
-
8
- # The directory in which application code can be found. This is where
9
- # generated code will go. Probably along side non-generated code.
10
- code_dir Cogfile.for_project.template_dir, :absolute => true
@@ -1,8 +0,0 @@
1
- # All paths are relative to the directory containing this file.
2
-
3
- # The directory in which to find ERB template files.
4
- template_dir 'templates'
5
-
6
- # The directory in which application code can be found. This is where
7
- # generated code will go. Probably along side non-generated code.
8
- code_dir 'src'