cog 0.2.2 → 0.3.0

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.
Files changed (79) hide show
  1. data/BuiltIn.cogfile +96 -0
  2. data/bin/cog +30 -39
  3. data/built_in/generators/sort.rb +3 -0
  4. data/built_in/plugins/basic/Cogfile +6 -0
  5. data/built_in/plugins/basic/templates/basic/generator.rb.erb +1 -0
  6. data/built_in/templates/cog/Cogfile.erb +40 -0
  7. data/built_in/templates/cog/plugin/generator.rb.erb.erb +3 -0
  8. data/{templates/cog/custom_tool/tool.rb.erb → built_in/templates/cog/plugin/plugin.rb.erb} +4 -11
  9. data/{templates → built_in/templates}/warning.erb +0 -0
  10. data/lib/cog.rb +25 -11
  11. data/lib/cog/config.rb +112 -49
  12. data/lib/cog/config/{language_methods.rb → language_config.rb} +23 -27
  13. data/lib/cog/config/plugin_config.rb +31 -0
  14. data/lib/cog/config/project_config.rb +48 -0
  15. data/lib/cog/controllers.rb +6 -8
  16. data/lib/cog/controllers/generator_controller.rb +30 -21
  17. data/lib/cog/controllers/plugin_controller.rb +43 -0
  18. data/lib/cog/controllers/template_controller.rb +12 -33
  19. data/lib/cog/dsl.rb +9 -0
  20. data/lib/cog/dsl/cogfile.rb +145 -0
  21. data/lib/cog/dsl/language_dsl.rb +142 -0
  22. data/lib/cog/embed_context.rb +0 -2
  23. data/lib/cog/embeds.rb +2 -7
  24. data/lib/cog/errors.rb +11 -24
  25. data/lib/cog/generator.rb +10 -15
  26. data/lib/cog/generator/file_methods.rb +2 -2
  27. data/lib/cog/generator/filters.rb +10 -14
  28. data/lib/cog/generator/language_methods.rb +2 -3
  29. data/lib/cog/generator_sandbox.rb +32 -0
  30. data/lib/cog/helpers.rb +10 -2
  31. data/lib/cog/helpers/cascading_set.rb +104 -0
  32. data/lib/cog/{embeds → helpers}/file_scanner.rb +1 -1
  33. data/lib/cog/language.rb +140 -0
  34. data/lib/cog/native_extensions.rb +2 -0
  35. data/lib/cog/native_extensions/array.rb +19 -0
  36. data/lib/cog/native_extensions/string.rb +54 -0
  37. data/lib/cog/plugin.rb +35 -0
  38. data/lib/cog/spec_helpers.rb +36 -14
  39. data/lib/cog/spec_helpers/matchers.rb +14 -4
  40. data/lib/cog/spec_helpers/matchers/match_maker.rb +1 -1
  41. data/lib/cog/spec_helpers/runner.rb +3 -9
  42. data/lib/cog/version.rb +1 -1
  43. metadata +27 -44
  44. data/Default.cogfile +0 -25
  45. data/lib/cog/built_in_tools.rb +0 -9
  46. data/lib/cog/built_in_tools/basic.rb +0 -10
  47. data/lib/cog/built_in_tools/basic/cog_tool.rb +0 -11
  48. data/lib/cog/config/cogfile.rb +0 -117
  49. data/lib/cog/config/lang_info.rb +0 -40
  50. data/lib/cog/config/project_methods.rb +0 -35
  51. data/lib/cog/config/tool_methods.rb +0 -94
  52. data/lib/cog/controllers/tool_controller.rb +0 -50
  53. data/lib/cog/helpers/cascading_template_set.rb +0 -75
  54. data/lib/cog/helpers/string.rb +0 -26
  55. data/lib/cog/languages.rb +0 -52
  56. data/lib/cog/languages/c_language.rb +0 -29
  57. data/lib/cog/languages/c_plus_plus_language.rb +0 -28
  58. data/lib/cog/languages/c_sharp_language.rb +0 -24
  59. data/lib/cog/languages/java_language.rb +0 -24
  60. data/lib/cog/languages/java_script_language.rb +0 -24
  61. data/lib/cog/languages/language.rb +0 -73
  62. data/lib/cog/languages/mixins.rb +0 -10
  63. data/lib/cog/languages/mixins/c_style_comments.rb +0 -23
  64. data/lib/cog/languages/mixins/hash_comments.rb +0 -19
  65. data/lib/cog/languages/python_language.rb +0 -20
  66. data/lib/cog/languages/qt_project_language.rb +0 -16
  67. data/lib/cog/languages/ruby_language.rb +0 -28
  68. data/lib/cog/tool.rb +0 -61
  69. data/lib/cog/tool/dsl.rb +0 -26
  70. data/templates/basic/generator.rb.erb +0 -4
  71. data/templates/cog/custom_tool/Gemfile.erb +0 -8
  72. data/templates/cog/custom_tool/LICENSE.erb +0 -18
  73. data/templates/cog/custom_tool/README.markdown.erb +0 -18
  74. data/templates/cog/custom_tool/Rakefile.erb +0 -15
  75. data/templates/cog/custom_tool/cog_tool.rb.erb +0 -17
  76. data/templates/cog/custom_tool/generator.rb.erb.erb +0 -9
  77. data/templates/cog/custom_tool/template.txt.erb.erb +0 -1
  78. data/templates/cog/custom_tool/tool.gemspec.erb +0 -17
  79. data/templates/cog/custom_tool/version.rb.erb +0 -5
@@ -0,0 +1,142 @@
1
+ module Cog
2
+ module DSL
3
+
4
+ # DSL for defining a language
5
+ class LanguageDSL
6
+
7
+ # @api developer
8
+ # @param key [String] unique case-insensitive identifier
9
+ def initialize(key)
10
+ @lang = Cog::Language.new key
11
+ end
12
+
13
+ # Define a readable name for the language
14
+ # @param value [String] readable name of the language
15
+ # @return [nil]
16
+ def name(value)
17
+ lang_eval { @name = value }
18
+ nil
19
+ end
20
+
21
+ # Define single line comment notation
22
+ # @param prefix [String] starts a single line comment in the language
23
+ # @return [nil]
24
+ def comment(prefix)
25
+ lang_eval { @comment_prefix = prefix }
26
+ nil
27
+ end
28
+
29
+ # Define multi-line comment notation
30
+ # @param prefix [String] starts a multi-line comment in the language
31
+ # @param postfix [String] ends a multi-line comment in the language
32
+ # @return [nil]
33
+ def multiline_comment(prefix, postfix)
34
+ lang_eval do
35
+ @multiline_comment_prefix = prefix
36
+ @multiline_comment_postfix = postfix
37
+ end
38
+ nil
39
+ end
40
+
41
+ # Borrow comment notation from another language
42
+ # @param lang_key [String] use comment notation from the language with the given key
43
+ # @return [nil]
44
+ def comment_style(lang_key)
45
+ lang_eval { @comment_style = lang_key.to_s.downcase }
46
+ nil
47
+ end
48
+
49
+ # Define file extensions
50
+ # @param values [Array<String>] list of file extensions for this language
51
+ def extension(*values)
52
+ lang_eval do
53
+ @extensions = values.collect {|key| key.to_s.downcase}
54
+ end
55
+ end
56
+
57
+ # Define a block to call when using a named scopes in this language
58
+ # @yieldparam name [String] name of the scope to use
59
+ # @yieldreturn [String] a using named scope statement in this language
60
+ # @return [nil]
61
+ def use_named_scope(&block)
62
+ lang_eval { @use_named_scope_block = block }
63
+ nil
64
+ end
65
+
66
+ # Define a block to call when beginning a named scope in this language
67
+ # @yieldparam name [String] name of the scope to begin
68
+ # @yieldreturn [String] a begin named scope statement in this language
69
+ # @return [nil]
70
+ def named_scope_begin(&block)
71
+ lang_eval { @named_scope_begin_block = block }
72
+ nil
73
+ end
74
+
75
+ # Define a block to call when ending a named scope in this language
76
+ # @yieldparam name [String] name of the scope to end
77
+ # @yieldreturn [String] an end named scope statement in this language
78
+ # @return [nil]
79
+ def named_scope_end(&block)
80
+ lang_eval { @named_scope_end_block = block }
81
+ nil
82
+ end
83
+
84
+ # Define a block to call when beginning an include guard in this language
85
+ # @yieldparam name [String] name of the guard
86
+ # @yieldreturn [String] a begin guard in this language
87
+ # @return [nil]
88
+ def include_guard_begin(&block)
89
+ lang_eval { @include_guard_begin_block = block }
90
+ nil
91
+ end
92
+
93
+ # Define a block to call when ending an include guard in this language
94
+ # @yieldparam name [String] name of the guard
95
+ # @yieldreturn [String] an end guard in this language
96
+ # @return [nil]
97
+ def include_guard_end(&block)
98
+ lang_eval { @include_guard_end_block = block }
99
+ nil
100
+ end
101
+
102
+ # Borrow include guard notation from another language
103
+ # @param lang_key [String] use include guard notation from the language with the given key
104
+ # @return [nil]
105
+ def include_guard_style(lang_key)
106
+ lang_eval { @include_guard_style = lang_key.to_s.downcase }
107
+ nil
108
+ end
109
+
110
+ # @api developer
111
+ # Compute the comment pattern
112
+ # @return [Cog::Language] the defined language
113
+ def finalize
114
+ pattern = /[*]/
115
+ esc = lambda do |x|
116
+ x.gsub(pattern) {|match| "\\#{match}"}
117
+ end
118
+
119
+ lang_eval do
120
+ @include_guard_style ||= key
121
+ @comment_style ||= key
122
+ @comment_pattern = if @comment_prefix && @multiline_comment_prefix
123
+ '^\s*(?:%s|%s)\s*%%s\s*(?:%s)?\s*$' % [@comment_prefix, @multiline_comment_prefix, @multiline_comment_postfix].collect(&esc)
124
+ elsif @comment_prefix
125
+ '^\s*%s\s*%%s\s*$' % esc.call(@comment_prefix)
126
+ elsif @multiline_comment_prefix
127
+ '^\s*%s\s*%%s\s*%s\s*$' % [@multiline_comment_prefix, @multiline_comment_postfix].collect(&esc)
128
+ else
129
+ '^\s*%s\s*$'
130
+ end
131
+ end
132
+ @lang
133
+ end
134
+
135
+ private
136
+
137
+ def lang_eval(&block)
138
+ @lang.instance_eval &block
139
+ end
140
+ end
141
+ end
142
+ end
@@ -1,5 +1,3 @@
1
- require 'cog/config'
2
-
3
1
  module Cog
4
2
 
5
3
  # Describes the environment of an embed statement including the file in which it was found, the line number, the language, an more.
@@ -1,14 +1,9 @@
1
- require 'cog/config'
2
- require 'cog/embed_context'
3
- require 'cog/embeds/file_scanner'
4
- require 'cog/errors'
5
-
6
1
  module Cog
7
2
 
8
3
  # @api developer
9
4
  # Methods for querying and manipulating project files
10
5
  module Embeds
11
-
6
+
12
7
  # Search through all project files for cog embeds, and remember them so that generators can refer to them later
13
8
  def gather_from_project
14
9
  @embeds ||= {}
@@ -45,7 +40,7 @@ module Cog
45
40
  # @yieldreturn [String] the value to substitute into the embed expansion
46
41
  # @return [Hash] whether or not the expansion was updated
47
42
  def update(c, &block)
48
- FileScanner.scan(c.path, statement(c.hook), :occurrence => c.actual_index) do |s|
43
+ Helpers::FileScanner.scan(c.path, statement(c.hook), :occurrence => c.actual_index) do |s|
49
44
  c.lineno = s.marked_line_number
50
45
  c.args = s.match[2].split if s.match[2]
51
46
  c.once = !s.match[3].nil?
@@ -28,37 +28,24 @@ module Cog
28
28
  end
29
29
  end
30
30
 
31
- define_error :ActionRequiresProject, 'action' do
32
- "the action requires a project, but no Cogfile was found"
33
- end
34
-
35
- define_error :CouldNotLoadTool, 'tool'
31
+ define_error :ActionRequiresProjectGeneratorPath, 'action'
32
+ define_error :ActionRequiresProjectTemplatePath, 'action'
33
+ define_error :ActionRequiresProjectPluginPath, 'action'
36
34
 
37
- define_error :DestinationAlreadyExists, 'path' do
38
- "a file or directory at the given path already exists, cannot create anything there"
39
- end
40
-
41
35
  define_error :DuplicateGenerator, 'generator'
42
-
43
- define_error :DuplicateTemplate, 'template'
44
-
45
- define_error :DuplicateTool, 'tool'
36
+ define_error :DuplicatePlugin, 'plugin'
46
37
 
47
- define_error :InvalidToolConfiguration, 'path to cog_tool.rb file' do
48
- "invalid directory structure for a cog tool"
38
+ define_error :InvalidPluginConfiguration, 'path to cog_plugin.rb file' do
39
+ "invalid directory structure for a cog plugin"
49
40
  end
50
41
 
51
42
  define_error :NoSuchFilter, 'filter'
52
-
53
43
  define_error :NoSuchGenerator, 'generator'
54
-
55
44
  define_error :NoSuchLanguage, 'language'
56
-
57
45
  define_error :NoSuchTemplate, 'template'
58
-
59
- define_error :NoSuchTool, 'tool' do
60
- "no such tool, make sure it appears in the COG_TOOLS environment variable"
61
- end
46
+ define_error :NoSuchPlugin, 'plugin'
47
+
48
+ define_error :PluginPathIsNotADirectory, 'plugin_path'
62
49
 
63
50
  define_error :ScopeStackUnderflow, 'caller' do
64
51
  "scope stack underflow: this can happen if you have too many *_end calls in a template"
@@ -68,8 +55,8 @@ module Cog
68
55
  "a embed expansion in the given file is missing the 'cog: }' terminator"
69
56
  end
70
57
 
71
- define_error :ToolMissingDefinition, 'missing' do
72
- "the tool was not fully defined"
58
+ define_error :PluginMissingDefinition, 'missing' do
59
+ "the plugin was not fully defined"
73
60
  end
74
61
  end
75
62
  end
@@ -1,13 +1,3 @@
1
- require 'cog/config'
2
- require 'cog/embeds'
3
- require 'cog/errors'
4
- require 'cog/generator/file_methods'
5
- require 'cog/generator/filters'
6
- require 'cog/generator/language_methods'
7
- require 'cog/helpers'
8
- require 'erb'
9
- require 'rainbow'
10
-
11
1
  module Cog
12
2
 
13
3
  # This module defines an interface which can be used by generator objects.
@@ -16,6 +6,10 @@ module Cog
16
6
  #
17
7
  # @see https://github.com/ktonon/cog#generators Introduction to Generators
18
8
  module Generator
9
+
10
+ autoload :FileMethods, 'cog/generator/file_methods'
11
+ autoload :Filters, 'cog/generator/filters'
12
+ autoload :LanguageMethods, 'cog/generator/language_methods'
19
13
 
20
14
  include FileMethods
21
15
  include Filters
@@ -33,10 +27,11 @@ module Cog
33
27
  end
34
28
 
35
29
  # Stamp a template into a file or return it as a string
36
- # @param template_path [String] path to template file relative one of the {Config#template_paths}
37
- # @param destination [String] path to which the generated file should be written, relative to the {Config::ProjectMethods#project_source_path}
30
+ # @param template_path [String] path to template file relative to {Config#template_path}
31
+ # @param destination [String] path to which the generated file should be written, relative to the {Config::ProjectConfig#project_path}
38
32
  # @option opt [Boolean] :absolute_template_path (false) is the +template_path+ absolute?
39
33
  # @option opt [Boolean] :absolute_destination (false) is the +destination+ absolute?
34
+ # @option opt [Boolean] :once (false) if +true+, the file will not be updated if it already exists
40
35
  # @option opt [Binding] :binding (nil) an optional binding to use while evaluating the template
41
36
  # @option opt [String, Array<String>] :filter (nil) name(s) of {Filters}
42
37
  # @option opt [Boolean] :quiet (false) suppress writing to STDOUT?
@@ -52,7 +47,7 @@ module Cog
52
47
 
53
48
  # Place it in a file
54
49
  write_scratch_file(destination, r, opt[:absolute_destination]) do |path, scratch|
55
- if files_are_same? path, scratch
50
+ if files_are_same?(path, scratch) || (opt[:once] && File.exists?(path))
56
51
  FileUtils.rm scratch
57
52
  else
58
53
  updated = File.exists? path
@@ -65,7 +60,7 @@ module Cog
65
60
 
66
61
  # Provide a value for embeds with the given hook
67
62
  # @param hook [String] hook name used in the embed statements
68
- # @yieldparam context [Embeds::EmbedContext] provides information about the environment in which the embed statement was found
63
+ # @yieldparam context [EmbedContext] provides information about the environment in which the embed statement was found
69
64
  # @yieldreturn The value which will be used to expand the embed (or replace the embedded content)
70
65
  # @return [nil]
71
66
  def embed(hook, &block)
@@ -108,7 +103,7 @@ module Cog
108
103
  # @yieldparam scratch [String] path to the scratch file
109
104
  # @return [nil]
110
105
  def write_scratch_file(original, text, absolute=false, &block)
111
- path = absolute ? original : File.join(Cog.project_source_path, original)
106
+ path = absolute ? original : File.join(Cog.project_path, original)
112
107
  FileUtils.mkpath File.dirname(path) unless File.exists? path
113
108
  scratch = "#{path}.scratch"
114
109
  File.open(scratch, 'w') {|file| file.write text}
@@ -5,7 +5,7 @@ module Cog
5
5
  module FileMethods
6
6
 
7
7
  # Get the template with the given name
8
- # @param path [String] path to template file relative one of the {Config#template_paths}
8
+ # @param path [String] path to file relative to the {Config#template_path}
9
9
  # @option opt [Boolean] :absolute (false) is the +path+ argument absolute?
10
10
  # @option opt [Boolean] :as_path (false) return the template as an ERB instance (+false+) or an absolute path to the file (+true+)
11
11
  # @return [ERB, String] an instance of {http://ruby-doc.org/stdlib-1.9.3/libdoc/erb/rdoc/ERB.html ERB} or an absolute path to the template
@@ -15,7 +15,7 @@ module Cog
15
15
  fullpath = if opt[:absolute]
16
16
  path
17
17
  else
18
- Cog.template_paths.inject('') do |found, prefix|
18
+ Cog.template_path.reverse.inject('') do |found, prefix|
19
19
  x = File.join prefix, path
20
20
  found.empty? && File.exists?(x) ? x : found
21
21
  end
@@ -1,5 +1,3 @@
1
- require 'cog/errors'
2
-
3
1
  module Cog
4
2
  module Generator
5
3
 
@@ -12,19 +10,17 @@ module Cog
12
10
  Cog.active_language.comment text
13
11
  end
14
12
 
15
- # @api developer
16
- # Adds a call_filter method which throws NoSuchFilter if
17
- # the filter is invalid
18
- def self.included(other)
19
- valid_filters = Filters.instance_eval {instance_methods}
20
- other.instance_eval do
21
- define_method "call_filter" do |name, text|
22
- raise Errors::NoSuchFilter.new(name) unless valid_filters.member?(name.to_s)
23
- method(name).call text
24
- end
25
- end
13
+ # Call a filter by name
14
+ # @param name [Symbol] the filter to call
15
+ # @param text [String] the text to pass through the filter
16
+ # @return [String] the filtered text
17
+ def call_filter(name, text)
18
+ gcontext[:filters] ||= %w(comment)
19
+ name = name.to_s
20
+ raise Errors::NoSuchFilter.new(name) unless gcontext[:filters].member? name
21
+ method(name).call text
26
22
  end
27
-
23
+
28
24
  end
29
25
  end
30
26
  end
@@ -1,12 +1,11 @@
1
- require 'cog/errors'
2
- require 'cog/generator/language_methods/scope'
3
-
4
1
  module Cog
5
2
  module Generator
6
3
 
7
4
  # Methods to help with generating language constructs
8
5
  module LanguageMethods
9
6
 
7
+ autoload :Scope, 'cog/generator/language_methods/scope'
8
+
10
9
  # @return [String] a warning comment not to edit the generated file
11
10
  def warning
12
11
  stamp 'warning', :filter => 'comment'
@@ -0,0 +1,32 @@
1
+ module Cog
2
+
3
+ # Generators files are executed as instances of this type.
4
+ # Plugins make themselves available to generators via a call to {DSL::Cogfile#autoload_plugin}
5
+ class GeneratorSandbox
6
+
7
+ include Generator
8
+
9
+ # @api developer
10
+ # @param path [String] path to the generator ruby file
11
+ def initialize(path)
12
+ @path = path
13
+ end
14
+
15
+ # Interpret the generator ruby file as this instance
16
+ # @api developer
17
+ # @return [nil]
18
+ def interpret
19
+ eval File.read(@path), binding
20
+ nil
21
+ end
22
+
23
+ # Register an autoload variable.
24
+ # @api developer
25
+ # @return [nil]
26
+ def self.autoload_plugin(name, path)
27
+ autoload name, path
28
+ nil
29
+ end
30
+
31
+ end
32
+ end
@@ -1,2 +1,10 @@
1
- require 'cog/helpers/cascading_template_set'
2
- require 'cog/helpers/string'
1
+ module Cog
2
+
3
+ # @api developer
4
+ module Helpers
5
+
6
+ autoload :CascadingSet, 'cog/helpers/cascading_set'
7
+ autoload :FileScanner, 'cog/helpers/file_scanner'
8
+
9
+ end
10
+ end
@@ -0,0 +1,104 @@
1
+ module Cog
2
+ module Helpers
3
+
4
+ # @api developer
5
+ class SourceInfo
6
+ attr_reader :name
7
+ attr_accessor :path
8
+
9
+ def initialize(name)
10
+ @info = []
11
+ @types = []
12
+ @name = name
13
+ end
14
+
15
+ def add_source(source, type=nil)
16
+ type ||= source
17
+ @info << source
18
+ @types << type
19
+ end
20
+
21
+ def style(text, type)
22
+ case type
23
+ when :built_in
24
+ text.color :cyan
25
+ when :gem
26
+ text.color :blue
27
+ when :user
28
+ text.color :green
29
+ when :plugin
30
+ text.color :yellow
31
+ when :project
32
+ text.color(:white).bright
33
+ else
34
+ text
35
+ end
36
+ end
37
+
38
+ def override_s(width=nil)
39
+ colorless = "[#{@info.join ' < '}]"
40
+ if width
41
+ x = @info.zip(@types).collect {|source, type| style source, type}
42
+ "[#{x.join ' < '}]" + " " * (width - colorless.length)
43
+ else
44
+ colorless
45
+ end
46
+ end
47
+
48
+ def <=>(other)
49
+ (@path || @name) <=> (other.path || other.name)
50
+ end
51
+
52
+ def to_s(override_column_width)
53
+ "#{override_s override_column_width} #{style @path || @name, @types.last}"
54
+ end
55
+ end
56
+
57
+ # @api developer
58
+ class CascadingSet
59
+ def initialize
60
+ @info = {}
61
+ end
62
+
63
+ # Look for sources in each of the given paths
64
+ # @param paths [Array<String>] a list of file system paths containing sources
65
+ # @option opt [String] :ext File extension of sources to glob for in each path
66
+ # @return [Array<String>] formatted listing of the sources
67
+ def self.process_paths(paths, opt={})
68
+ cs = Helpers::CascadingSet.new
69
+ paths.each_with_cog_source do |source, type, path|
70
+ opt[:source] = source
71
+ opt[:type] = type
72
+ opt[:root_dir] = path
73
+ cs.add_sources opt
74
+ end
75
+ cs.to_a
76
+ end
77
+
78
+ # @option opt [String] :source (nil) the name of the source
79
+ # @option opt [Symbol] :type (nil) must be one of <tt>:built_in</tt>, <tt>:user</tt>, <tt>:plugin</tt>, or <tt>:project</tt>
80
+ # @option opt [String] :root_dir (nil) directory in which to look for sources
81
+ def add_sources(opt={})
82
+ Dir.glob("#{opt[:root_dir]}/**/*.#{opt[:ext]}") do |path|
83
+ name = path.relative_to(opt[:root_dir]).slice(0..-(2 + opt[:ext].length))
84
+ @info[name] ||= SourceInfo.new name
85
+ @info[name].path = path if Cog.show_fullpaths?
86
+ @info[name].add_source opt[:source], opt[:type]
87
+ end
88
+ end
89
+
90
+ # @param plugin [Plugin] name of the plugin
91
+ def add_plugin(plugin, opt={})
92
+ @info[plugin.name] ||= SourceInfo.new plugin.name
93
+ @info[plugin.name].path = plugin.path if Cog.show_fullpaths?
94
+ @info[plugin.name].add_source *plugin.path.cog_source_and_type
95
+ end
96
+
97
+ def to_a
98
+ w = @info.values.collect {|t| t.override_s.length}.max
99
+ @info.values.sort.collect {|t| t.to_s(w)}
100
+ end
101
+ end
102
+
103
+ end
104
+ end