cog 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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'