cog 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/BuiltIn.cogfile +96 -0
- data/bin/cog +30 -39
- data/built_in/generators/sort.rb +3 -0
- data/built_in/plugins/basic/Cogfile +6 -0
- data/built_in/plugins/basic/templates/basic/generator.rb.erb +1 -0
- data/built_in/templates/cog/Cogfile.erb +40 -0
- data/built_in/templates/cog/plugin/generator.rb.erb.erb +3 -0
- data/{templates/cog/custom_tool/tool.rb.erb → built_in/templates/cog/plugin/plugin.rb.erb} +4 -11
- data/{templates → built_in/templates}/warning.erb +0 -0
- data/lib/cog.rb +25 -11
- data/lib/cog/config.rb +112 -49
- data/lib/cog/config/{language_methods.rb → language_config.rb} +23 -27
- data/lib/cog/config/plugin_config.rb +31 -0
- data/lib/cog/config/project_config.rb +48 -0
- data/lib/cog/controllers.rb +6 -8
- data/lib/cog/controllers/generator_controller.rb +30 -21
- data/lib/cog/controllers/plugin_controller.rb +43 -0
- data/lib/cog/controllers/template_controller.rb +12 -33
- data/lib/cog/dsl.rb +9 -0
- data/lib/cog/dsl/cogfile.rb +145 -0
- data/lib/cog/dsl/language_dsl.rb +142 -0
- data/lib/cog/embed_context.rb +0 -2
- data/lib/cog/embeds.rb +2 -7
- data/lib/cog/errors.rb +11 -24
- data/lib/cog/generator.rb +10 -15
- data/lib/cog/generator/file_methods.rb +2 -2
- data/lib/cog/generator/filters.rb +10 -14
- data/lib/cog/generator/language_methods.rb +2 -3
- data/lib/cog/generator_sandbox.rb +32 -0
- data/lib/cog/helpers.rb +10 -2
- data/lib/cog/helpers/cascading_set.rb +104 -0
- data/lib/cog/{embeds → helpers}/file_scanner.rb +1 -1
- data/lib/cog/language.rb +140 -0
- data/lib/cog/native_extensions.rb +2 -0
- data/lib/cog/native_extensions/array.rb +19 -0
- data/lib/cog/native_extensions/string.rb +54 -0
- data/lib/cog/plugin.rb +35 -0
- data/lib/cog/spec_helpers.rb +36 -14
- data/lib/cog/spec_helpers/matchers.rb +14 -4
- data/lib/cog/spec_helpers/matchers/match_maker.rb +1 -1
- data/lib/cog/spec_helpers/runner.rb +3 -9
- data/lib/cog/version.rb +1 -1
- metadata +27 -44
- data/Default.cogfile +0 -25
- data/lib/cog/built_in_tools.rb +0 -9
- data/lib/cog/built_in_tools/basic.rb +0 -10
- data/lib/cog/built_in_tools/basic/cog_tool.rb +0 -11
- data/lib/cog/config/cogfile.rb +0 -117
- data/lib/cog/config/lang_info.rb +0 -40
- data/lib/cog/config/project_methods.rb +0 -35
- data/lib/cog/config/tool_methods.rb +0 -94
- data/lib/cog/controllers/tool_controller.rb +0 -50
- data/lib/cog/helpers/cascading_template_set.rb +0 -75
- data/lib/cog/helpers/string.rb +0 -26
- data/lib/cog/languages.rb +0 -52
- data/lib/cog/languages/c_language.rb +0 -29
- data/lib/cog/languages/c_plus_plus_language.rb +0 -28
- data/lib/cog/languages/c_sharp_language.rb +0 -24
- data/lib/cog/languages/java_language.rb +0 -24
- data/lib/cog/languages/java_script_language.rb +0 -24
- data/lib/cog/languages/language.rb +0 -73
- data/lib/cog/languages/mixins.rb +0 -10
- data/lib/cog/languages/mixins/c_style_comments.rb +0 -23
- data/lib/cog/languages/mixins/hash_comments.rb +0 -19
- data/lib/cog/languages/python_language.rb +0 -20
- data/lib/cog/languages/qt_project_language.rb +0 -16
- data/lib/cog/languages/ruby_language.rb +0 -28
- data/lib/cog/tool.rb +0 -61
- data/lib/cog/tool/dsl.rb +0 -26
- data/templates/basic/generator.rb.erb +0 -4
- data/templates/cog/custom_tool/Gemfile.erb +0 -8
- data/templates/cog/custom_tool/LICENSE.erb +0 -18
- data/templates/cog/custom_tool/README.markdown.erb +0 -18
- data/templates/cog/custom_tool/Rakefile.erb +0 -15
- data/templates/cog/custom_tool/cog_tool.rb.erb +0 -17
- data/templates/cog/custom_tool/generator.rb.erb.erb +0 -9
- data/templates/cog/custom_tool/template.txt.erb.erb +0 -1
- data/templates/cog/custom_tool/tool.gemspec.erb +0 -17
- 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
|
data/lib/cog/embed_context.rb
CHANGED
data/lib/cog/embeds.rb
CHANGED
@@ -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?
|
data/lib/cog/errors.rb
CHANGED
@@ -28,37 +28,24 @@ module Cog
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
define_error :
|
32
|
-
|
33
|
-
|
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 :
|
48
|
-
"invalid directory structure for a cog
|
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
|
-
|
60
|
-
|
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 :
|
72
|
-
"the
|
58
|
+
define_error :PluginMissingDefinition, 'missing' do
|
59
|
+
"the plugin was not fully defined"
|
73
60
|
end
|
74
61
|
end
|
75
62
|
end
|
data/lib/cog/generator.rb
CHANGED
@@ -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
|
37
|
-
# @param destination [String] path to which the generated file should be written, relative to the {Config::
|
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?
|
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 [
|
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.
|
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
|
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.
|
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
|
-
#
|
16
|
-
#
|
17
|
-
# the
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
data/lib/cog/helpers.rb
CHANGED
@@ -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
|