jsus 0.3.1 → 0.3.2
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.
- data/.document +1 -1
- data/.travis.yml +1 -1
- data/.yardopts +9 -0
- data/CHANGELOG +21 -0
- data/Gemfile +3 -2
- data/{README → README.md} +10 -4
- data/TODO +1 -3
- data/VERSION +1 -1
- data/bin/jsus +33 -10
- data/jsus.gemspec +12 -7
- data/lib/jsus.rb +31 -9
- data/lib/jsus/container.rb +96 -24
- data/lib/jsus/middleware.rb +160 -43
- data/lib/jsus/package.rb +65 -25
- data/lib/jsus/packager.rb +15 -10
- data/lib/jsus/pool.rb +54 -40
- data/lib/jsus/source_file.rb +105 -80
- data/lib/jsus/tag.rb +65 -39
- data/lib/jsus/util.rb +8 -6
- data/lib/jsus/util/code_generator.rb +21 -0
- data/lib/jsus/util/documenter.rb +34 -6
- data/lib/jsus/util/file_cache.rb +16 -5
- data/lib/jsus/util/inflection.rb +9 -2
- data/lib/jsus/util/tree.rb +54 -18
- data/lib/jsus/util/validator/base.rb +13 -5
- data/lib/jsus/util/validator/mooforge.rb +8 -2
- data/markup/stylesheet.css +84 -16
- data/spec/data/ChainDependencies/app/javascripts/Class/package.yml +2 -2
- data/spec/jsus/middleware_spec.rb +25 -0
- data/spec/jsus/pool_spec.rb +9 -4
- metadata +23 -7
data/lib/jsus/tag.rb
CHANGED
@@ -3,8 +3,13 @@ module Jsus
|
|
3
3
|
# Tag is basically just a string that contains a package name and a name for class
|
4
4
|
# (or not necessarily a class) which the given SourceFile provides/requires/extends/replaces.
|
5
5
|
#
|
6
|
+
# @example
|
7
|
+
# "Core/Class" is a tag
|
6
8
|
class Tag
|
7
|
-
|
9
|
+
# Owner package
|
10
|
+
attr_accessor :package
|
11
|
+
# Whether tag is external
|
12
|
+
attr_accessor :external
|
8
13
|
|
9
14
|
# Constructors
|
10
15
|
|
@@ -14,6 +19,8 @@ module Jsus
|
|
14
19
|
# The way it works may seem a bit tricky but actually it parses name/options
|
15
20
|
# combinations in different ways and may be best described by examples:
|
16
21
|
#
|
22
|
+
# @example
|
23
|
+
#
|
17
24
|
# a = Tag.new("Class") # :package_name => "", :name => "Class", :external => false
|
18
25
|
# b = Tag.new("Core/Class") # :package_name => "Core", :name => "Class", :external => true
|
19
26
|
# core = Package.new(...) # let's consider its name is 'Core'
|
@@ -23,8 +30,14 @@ module Jsus
|
|
23
30
|
# e = Tag.new("Core/Class", :package => mash) # :package_name => "Core", :name => "Class", :external => true
|
24
31
|
#
|
25
32
|
# Between all those, tags b,c,d and e are equal, meaning they all use
|
26
|
-
# the same spot in Hash or
|
33
|
+
# the same spot in Hash or wherever else.
|
27
34
|
#
|
35
|
+
# @param [String] tag name
|
36
|
+
# @param [Hash] options
|
37
|
+
# @option options [String] :package_name owner package name
|
38
|
+
# @option options [Jsus::Package] :package :owner package
|
39
|
+
# @option options [Boolean] :external whether tag is considered external
|
40
|
+
# @api public
|
28
41
|
def initialize(name, options = {})
|
29
42
|
normalized_options = Tag.normalize_name_and_options(name, options)
|
30
43
|
[:name, :package, :package_name, :external].each do |field|
|
@@ -32,7 +45,9 @@ module Jsus
|
|
32
45
|
end
|
33
46
|
end
|
34
47
|
|
35
|
-
|
48
|
+
# When given a tag instead of tag name, just returns it.
|
49
|
+
# @api public
|
50
|
+
def self.new(tag_or_name, *args, &block)
|
36
51
|
if tag_or_name.kind_of?(Tag)
|
37
52
|
tag_or_name
|
38
53
|
else
|
@@ -40,30 +55,29 @@ module Jsus
|
|
40
55
|
end
|
41
56
|
end
|
42
57
|
|
43
|
-
#
|
58
|
+
# Alias for Tag.new
|
59
|
+
# @api public
|
44
60
|
def self.[](*args)
|
45
61
|
new(*args)
|
46
62
|
end
|
47
63
|
|
48
64
|
# Public API
|
49
65
|
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
66
|
+
# @returns [Boolean] whether tag is external
|
67
|
+
# @api public
|
53
68
|
def external?
|
54
69
|
!!external
|
55
70
|
end
|
56
71
|
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
# Tag.new('Core/Class', :package => core).name(:short => true) # => 'Class'
|
72
|
+
# @param [Hash] options
|
73
|
+
# @option options [Boolean] :short whether the tag should try using short form
|
74
|
+
# @note only non-external tags support short forms.
|
75
|
+
# @example
|
76
|
+
# Tag.new('Core/Class').name(:short => true) # => 'Core/Class'
|
77
|
+
# core = Package.new(...) # let's consider its name is 'Core'
|
78
|
+
# Tag.new('Core/Class', :package => core).name(:short => true) # => 'Class'
|
79
|
+
# @return [String] a well-formed name for the tag.
|
80
|
+
# @api public
|
67
81
|
def name(options = {})
|
68
82
|
if !package_name || package_name.empty? || (options[:short] && !external?)
|
69
83
|
@name
|
@@ -73,17 +87,19 @@ module Jsus
|
|
73
87
|
end
|
74
88
|
alias_method :to_s, :name
|
75
89
|
|
76
|
-
#
|
90
|
+
# @returns [String] package name or an empty string
|
91
|
+
# @api public
|
77
92
|
def package_name
|
78
93
|
@package_name ||= (@package ? @package.name : "")
|
79
94
|
end
|
80
95
|
|
81
|
-
#
|
96
|
+
# @return [Boolean] whether name is empty
|
97
|
+
# @api public
|
82
98
|
def empty?
|
83
99
|
@name.empty?
|
84
100
|
end
|
85
101
|
|
86
|
-
#
|
102
|
+
# @api public
|
87
103
|
def ==(other)
|
88
104
|
if other.kind_of?(Tag)
|
89
105
|
self.name == other.name
|
@@ -92,9 +108,26 @@ module Jsus
|
|
92
108
|
end
|
93
109
|
end
|
94
110
|
|
111
|
+
# @api semipublic
|
112
|
+
def eql?(other)
|
113
|
+
self.==(other)
|
114
|
+
end
|
115
|
+
|
116
|
+
# @api semipublic
|
117
|
+
def hash
|
118
|
+
self.name.hash
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [String] human-readable representation
|
122
|
+
# @api public
|
123
|
+
def inspect
|
124
|
+
"<Jsus::Tag: #{name}>"
|
125
|
+
end
|
126
|
+
|
95
127
|
# Private API
|
96
128
|
|
97
|
-
|
129
|
+
# @api private
|
130
|
+
def self.normalize_name_and_options(name, options = {})
|
98
131
|
result = {}
|
99
132
|
name.gsub!(%r(^(\.)?/), "")
|
100
133
|
if name.index("/")
|
@@ -112,39 +145,32 @@ module Jsus
|
|
112
145
|
result
|
113
146
|
end
|
114
147
|
|
115
|
-
|
148
|
+
# @api private
|
149
|
+
def self.normalized_options_to_full_name(options)
|
116
150
|
[options[:package_name], options[:name]].compact.join("/")
|
117
151
|
end
|
118
152
|
|
119
|
-
|
153
|
+
# @api private
|
154
|
+
def self.name_and_options_to_full_name(name, options = {})
|
120
155
|
normalized_options_to_full_name(normalize_name_and_options(name, options))
|
121
156
|
end
|
122
157
|
|
123
|
-
|
158
|
+
# @api private
|
159
|
+
def self.normalize_package_name(name)
|
124
160
|
package_chunks = name.split("/")
|
125
161
|
package_chunks.map do |pc|
|
126
162
|
Jsus::Util::Inflection.random_case_to_mixed_case(pc)
|
127
163
|
end.join("/")
|
128
164
|
end # normalize_name
|
129
165
|
|
130
|
-
|
166
|
+
# @api private
|
167
|
+
def package_name=(new_value)
|
131
168
|
@package_name = new_value
|
132
169
|
end
|
133
170
|
|
134
|
-
|
171
|
+
# @api private
|
172
|
+
def name=(new_value)
|
135
173
|
@name = new_value
|
136
174
|
end
|
137
|
-
|
138
|
-
def eql?(other) # :nodoc:
|
139
|
-
self.==(other)
|
140
|
-
end
|
141
|
-
|
142
|
-
def hash # :nodoc:
|
143
|
-
self.name.hash
|
144
|
-
end
|
145
|
-
|
146
|
-
def inspect # :nodoc
|
147
|
-
"<Jsus::Tag: #{name}>"
|
148
|
-
end
|
149
175
|
end
|
150
|
-
end
|
176
|
+
end
|
data/lib/jsus/util.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module Jsus
|
2
|
+
# Utility namespace.
|
2
3
|
module Util
|
3
|
-
autoload :Tree,
|
4
|
-
autoload :Documenter,
|
5
|
-
autoload :Validator,
|
6
|
-
autoload :Inflection,
|
7
|
-
autoload :FileCache,
|
4
|
+
autoload :Tree, 'jsus/util/tree'
|
5
|
+
autoload :Documenter, 'jsus/util/documenter'
|
6
|
+
autoload :Validator, 'jsus/util/validator'
|
7
|
+
autoload :Inflection, 'jsus/util/inflection'
|
8
|
+
autoload :FileCache, 'jsus/util/file_cache'
|
9
|
+
autoload :CodeGenerator, 'jsus/util/code_generator'
|
8
10
|
end # Util
|
9
|
-
end # Jsus
|
11
|
+
end # Jsus
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Jsus
|
2
|
+
module Util
|
3
|
+
# Code generation routines.
|
4
|
+
module CodeGenerator
|
5
|
+
class <<self
|
6
|
+
# @return [String] javascript for includes for a list of given paths
|
7
|
+
# @api public
|
8
|
+
def generate_includes(paths)
|
9
|
+
script = %{
|
10
|
+
(function(prefix, loader) {
|
11
|
+
var sources = %sources%;
|
12
|
+
if (!loader) loader = function(path) {
|
13
|
+
document.write('<scr' + 'ipt src="' + (prefix || '') + path + '"></script>');
|
14
|
+
}
|
15
|
+
for (var i = 0, j = sources.length; i < j; i++) loader(sources[i]);
|
16
|
+
})(window.prefix, window.loader);}.sub("%sources%", JSON.pretty_generate(paths))
|
17
|
+
end # generate_includes
|
18
|
+
end # class <<self
|
19
|
+
end # module CodeGenerator
|
20
|
+
end # module Util
|
21
|
+
end # module Jsus
|
data/lib/jsus/util/documenter.rb
CHANGED
@@ -11,6 +11,10 @@ module Jsus
|
|
11
11
|
attr_accessor :options
|
12
12
|
|
13
13
|
# Constructor. Accepts options as the argument.
|
14
|
+
# @param [Hash] options
|
15
|
+
# @option options [Boolean] :highlight_source use syntax highlighting
|
16
|
+
# (via pygments)
|
17
|
+
# @api public
|
14
18
|
def initialize(options = DEFAULT_OPTIONS)
|
15
19
|
require "murdoc"
|
16
20
|
self.options = options
|
@@ -19,6 +23,9 @@ module Jsus
|
|
19
23
|
end
|
20
24
|
|
21
25
|
# Generates documentation tree into the given directory.
|
26
|
+
#
|
27
|
+
# @param [String] output directory
|
28
|
+
# @api public
|
22
29
|
def generate(doc_dir = Dir.pwd)
|
23
30
|
#FileUtils.rm_rf(doc_dir)
|
24
31
|
FileUtils.mkdir_p(doc_dir)
|
@@ -41,6 +48,9 @@ module Jsus
|
|
41
48
|
end
|
42
49
|
|
43
50
|
# Adds a source file to the documented source tree
|
51
|
+
#
|
52
|
+
# @param [Jsus::SourceFile] pushed source
|
53
|
+
# @api public
|
44
54
|
def <<(source) # :nodoc:
|
45
55
|
filename = File.basename(source.filename)
|
46
56
|
if source.package
|
@@ -52,25 +62,34 @@ module Jsus
|
|
52
62
|
self
|
53
63
|
end
|
54
64
|
|
55
|
-
|
65
|
+
# @return [Jsus::Util::Tree] tree with all sources
|
66
|
+
# @api public
|
67
|
+
def tree
|
56
68
|
@tree ||= Tree.new
|
57
69
|
end
|
58
70
|
|
59
71
|
# Scope for documentation in pathspec format. See Jsus::Util::Tree::Node#find_children_matching
|
72
|
+
# @return [Array] scope
|
73
|
+
# @api public
|
60
74
|
def current_scope
|
61
75
|
@current_scope ||= default_scope
|
62
76
|
end
|
63
77
|
|
64
|
-
|
78
|
+
# @return [Array] default documentation scope
|
79
|
+
# @api semipublic
|
80
|
+
def default_scope
|
65
81
|
["/**/*"]
|
66
82
|
end
|
67
83
|
|
68
|
-
|
84
|
+
# @api semipublic
|
85
|
+
def current_scope=(scope)
|
69
86
|
@current_scope = scope
|
70
87
|
end
|
71
88
|
|
72
89
|
# Sets documenter to exclusive scope for documentation.
|
73
90
|
# Exclusive scope overrides all the other scopes.
|
91
|
+
# @param [Array, String] documentation scope
|
92
|
+
# @api public
|
74
93
|
def only(scope)
|
75
94
|
result = clone
|
76
95
|
result.current_scope = [scope].flatten
|
@@ -79,18 +98,24 @@ module Jsus
|
|
79
98
|
|
80
99
|
# Sets documenter to additive scope for documentation.
|
81
100
|
# Additive scopes match any of the pathspecs given
|
101
|
+
#
|
102
|
+
# @param [Array, String] documentation scope
|
103
|
+
# @api public
|
82
104
|
def or(scope)
|
83
105
|
result = clone
|
84
106
|
result.current_scope = current_scope + [scope].flatten
|
85
107
|
result
|
86
108
|
end
|
87
109
|
|
88
|
-
#
|
110
|
+
# @return [Jsus::Util::Tree] tree with documented sources only
|
111
|
+
# @api public
|
89
112
|
def documented_sources
|
90
113
|
@documented_sources ||= documented_sources!
|
91
114
|
end
|
92
115
|
|
93
|
-
|
116
|
+
# @see #documented_sources
|
117
|
+
# @api private
|
118
|
+
def documented_sources!
|
94
119
|
doctree = Tree.new
|
95
120
|
current_scope.map {|pathspec| tree.find_nodes_matching(pathspec) }.
|
96
121
|
flatten.each {|s| doctree.insert(s.full_path, s.value)}
|
@@ -99,6 +124,7 @@ module Jsus
|
|
99
124
|
|
100
125
|
protected
|
101
126
|
|
127
|
+
# @api private
|
102
128
|
def create_documentation_for_source(source, template) # :nodoc:
|
103
129
|
skipped_lines = 0
|
104
130
|
content = source.original_content.gsub(/\A\s*\/\*.*?\*\//m) {|w| skipped_lines += w.split("\n").size; "" }
|
@@ -106,13 +132,15 @@ module Jsus
|
|
106
132
|
Murdoc::Formatter.new(template).render(:paragraphs => annotator.paragraphs, :header => source.header, :source => source, :skipped_lines => skipped_lines)
|
107
133
|
end
|
108
134
|
|
135
|
+
# @api private
|
109
136
|
def create_index_for_node(node, template) # :nodoc:
|
110
137
|
Haml::Engine.new(template).render(self, :node => node)
|
111
138
|
end
|
112
139
|
|
140
|
+
# @api private
|
113
141
|
def file_from_contents(filename, contents) # :nodoc:
|
114
142
|
File.open(filename, "w+") {|f| f << contents }
|
115
143
|
end
|
116
144
|
end
|
117
145
|
end
|
118
|
-
end
|
146
|
+
end
|
data/lib/jsus/util/file_cache.rb
CHANGED
@@ -6,13 +6,18 @@ module Jsus
|
|
6
6
|
#
|
7
7
|
class FileCache
|
8
8
|
# Initializes filecache to given directory
|
9
|
+
# @param [String] output directory
|
10
|
+
# @api public
|
9
11
|
def initialize(path)
|
10
12
|
@path = path
|
11
13
|
end # initialize
|
12
14
|
|
13
15
|
# Creates a file with given value for given key in cache directory
|
14
16
|
#
|
15
|
-
#
|
17
|
+
# @param [String] key
|
18
|
+
# @param [String] value
|
19
|
+
# @return [String] actual path for stored file.
|
20
|
+
# @api public
|
16
21
|
def write(key, value)
|
17
22
|
item_path = generate_path(key)
|
18
23
|
FileUtils.mkdir_p(File.dirname(item_path))
|
@@ -20,21 +25,26 @@ module Jsus
|
|
20
25
|
item_path
|
21
26
|
end # write
|
22
27
|
|
23
|
-
#
|
24
|
-
#
|
28
|
+
# @param [String] key
|
29
|
+
# @return [String, nil] path to cached file or nil
|
30
|
+
# @api public
|
25
31
|
def read(key)
|
26
32
|
item_path = generate_path(key)
|
27
33
|
File.exists?(item_path) ? item_path : nil
|
28
34
|
end # read
|
29
35
|
alias_method :exists?, :read
|
30
36
|
|
31
|
-
#
|
32
|
-
#
|
37
|
+
# @param [String] key
|
38
|
+
# @yield block with routine to call on cache miss
|
39
|
+
# @return [String] path to stored file
|
40
|
+
# @api public
|
33
41
|
def fetch(key, &block)
|
34
42
|
read(key) || write(key, yield)
|
35
43
|
end # fetch
|
36
44
|
|
37
45
|
# Deletes cache entry for given key.
|
46
|
+
# @param [String] key
|
47
|
+
# @api public
|
38
48
|
def delete(key)
|
39
49
|
item_path = generate_path(key)
|
40
50
|
if File.exists?(item_path)
|
@@ -48,6 +58,7 @@ module Jsus
|
|
48
58
|
#
|
49
59
|
# Default strategy: append key to cache directory
|
50
60
|
# (slashes are replaced with dots)
|
61
|
+
# @api private
|
51
62
|
def generate_path(key)
|
52
63
|
key = key.gsub(File::SEPARATOR, ".")
|
53
64
|
File.join(@path, key)
|
data/lib/jsus/util/inflection.rb
CHANGED
@@ -4,31 +4,38 @@ module Jsus
|
|
4
4
|
module Inflection
|
5
5
|
class <<self
|
6
6
|
# Converts strings with various punctuation to pascal case
|
7
|
+
# @example
|
7
8
|
# hello_world => HelloWorld
|
8
9
|
# Oh.My.God => OhMyGod
|
9
10
|
# iAmCamelCase => IAmCamelCase
|
10
11
|
# some_Weird_._punctuation => SomeWeirdPunctuation
|
12
|
+
# @api public
|
11
13
|
def random_case_to_mixed_case(string)
|
12
14
|
string.split(/[^a-zA-Z]+/).map {|chunk| capitalize(chunk) }.join
|
13
15
|
end # random_case_to_mixed_case
|
14
16
|
|
15
17
|
# Same as #random_case_to_mixed_case, but preserves dots
|
16
|
-
#
|
18
|
+
# @example
|
19
|
+
# color.fx => Color.Fx
|
20
|
+
# @api public
|
17
21
|
def random_case_to_mixed_case_preserve_dots(string)
|
18
22
|
string.split(".").map {|c| random_case_to_mixed_case(c) }.join(".")
|
19
23
|
end # random_case_to_mixed_case
|
20
24
|
|
21
25
|
# Capitalizes first letter (doesn't do anything else to other letters, unlike String#capitalize)
|
26
|
+
# @api public
|
22
27
|
def capitalize(string)
|
23
28
|
string[0,1].capitalize + string[1..-1].to_s
|
24
29
|
end # capitalize
|
25
30
|
|
26
31
|
# Downcases first letter
|
32
|
+
# @api public
|
27
33
|
def decapitalize(string)
|
28
34
|
string[0,1].downcase + string[1..-1].to_s
|
29
35
|
end # decapitalize
|
30
36
|
|
31
37
|
# Translates MixedCase string to camel-case
|
38
|
+
# @api public
|
32
39
|
def snake_case(string)
|
33
40
|
decapitalize(string.gsub(/(.)([A-Z])([a-z]+)/) {|_| "#{$1}_#{$2.downcase}#{$3}"}.
|
34
41
|
gsub(/[^A-Za-z_]+/, "_"))
|
@@ -36,4 +43,4 @@ module Jsus
|
|
36
43
|
end # class <<self
|
37
44
|
end # module Inflection
|
38
45
|
end # module Util
|
39
|
-
end # module Jsus
|
46
|
+
end # module Jsus
|