jsus 0.1.4 → 0.1.5

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/CHANGELOG CHANGED
@@ -1,4 +1,9 @@
1
1
  = Jsus Changelog
2
+ == Version 0.1.5
3
+ * Introduced new concept, Tag, which is going to be used instead of
4
+ provides/requires strings
5
+ * Introduced source extensions (monkey-patching, actually)
6
+ * Wrote some basic documentation for the classes
2
7
 
3
8
  == Version 0.1.4
4
9
  * Switched from OptiFlag to Choice for command-line parsing in jsus utility
data/Manifest CHANGED
@@ -11,7 +11,7 @@ lib/jsus/package.rb
11
11
  lib/jsus/packager.rb
12
12
  lib/jsus/pool.rb
13
13
  lib/jsus/source_file.rb
14
- lib/jsus/topsortable.rb
14
+ lib/jsus/tag.rb
15
15
  spec/data/Basic/README
16
16
  spec/data/Basic/app/javascripts/Orwik/Source/Library/Color.js
17
17
  spec/data/Basic/app/javascripts/Orwik/Source/Widget/Input/Input.Color.js
@@ -24,6 +24,10 @@ spec/data/ChainDependencies/app/javascripts/Hash/Source/Hash.js
24
24
  spec/data/ChainDependencies/app/javascripts/Hash/package.yml
25
25
  spec/data/ChainDependencies/app/javascripts/Mash/Source/Mash.js
26
26
  spec/data/ChainDependencies/app/javascripts/Mash/package.yml
27
+ spec/data/Extensions/app/javascripts/Core/Source/Class.js
28
+ spec/data/Extensions/app/javascripts/Core/package.yml
29
+ spec/data/Extensions/app/javascripts/Orwik/Extensions/Class.js
30
+ spec/data/Extensions/app/javascripts/Orwik/package.yml
27
31
  spec/data/ExternalDependencies/app/javascripts/Orwik/Source/Test.js
28
32
  spec/data/ExternalDependencies/app/javascripts/Orwik/package.yml
29
33
  spec/data/OutsideDependencies/README
@@ -44,7 +48,7 @@ spec/lib/jsus/package_spec.rb
44
48
  spec/lib/jsus/packager_spec.rb
45
49
  spec/lib/jsus/pool_spec.rb
46
50
  spec/lib/jsus/source_file_spec.rb
47
- spec/lib/jsus/topsortable_spec.rb
51
+ spec/lib/jsus/tag_spec.rb
48
52
  spec/shared/class_stubs.rb
49
53
  spec/spec.opts
50
54
  spec/spec_helper.rb
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
- Echoe.new('jsus', '0.1.4') do |g|
4
+ Echoe.new('jsus', '0.1.5') do |g|
5
5
  g.description = "Packager/compiler for js-files that resolves dependencies and can compile everything into one file, providing all the neccessary meta-info."
6
6
  g.url = "http://github.com/markiz/jsus"
7
7
  g.author = "Markiz, idea by Inviz (http://github.com/Inviz)"
data/bin/jsus CHANGED
@@ -44,6 +44,7 @@ pool = if Choice.choices[:dependencies]
44
44
  end
45
45
  package = Jsus::Package.new(Choice.choices[:input_directory], :pool => pool)
46
46
  package.include_dependencies! if Choice.choices[:dependencies]
47
+ package.include_extensions! if Choice.choices[:dependencies]
47
48
  output_directory = Choice.choices[:output_directory]
48
49
  package.compile(output_directory)
49
50
  package.generate_scripts_info(output_directory) unless Choice.choices[:without_scripts_info]
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{jsus}
5
- s.version = "0.1.4"
5
+ s.version = "0.1.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Markiz, idea by Inviz (http://github.com/Inviz)"]
9
- s.date = %q{2010-06-07}
9
+ s.date = %q{2010-06-15}
10
10
  s.default_executable = %q{jsus}
11
11
  s.description = %q{Packager/compiler for js-files that resolves dependencies and can compile everything into one file, providing all the neccessary meta-info.}
12
12
  s.email = %q{markizko@gmail.com}
13
13
  s.executables = ["jsus"]
14
- s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "TODO", "bin/jsus", "lib/jsus.rb", "lib/jsus/container.rb", "lib/jsus/package.rb", "lib/jsus/packager.rb", "lib/jsus/pool.rb", "lib/jsus/source_file.rb", "lib/jsus/topsortable.rb"]
15
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "TODO", "bin/jsus", "lib/jsus.rb", "lib/jsus/container.rb", "lib/jsus/package.rb", "lib/jsus/packager.rb", "lib/jsus/pool.rb", "lib/jsus/source_file.rb", "lib/jsus/topsortable.rb", "spec/data/Basic/README", "spec/data/Basic/app/javascripts/Orwik/Source/Library/Color.js", "spec/data/Basic/app/javascripts/Orwik/Source/Widget/Input/Input.Color.js", "spec/data/Basic/app/javascripts/Orwik/Source/Widget/Input/Input.js", "spec/data/Basic/app/javascripts/Orwik/Source/Widget/Widget.js", "spec/data/Basic/app/javascripts/Orwik/package.yml", "spec/data/ChainDependencies/app/javascripts/Class/Source/Class.js", "spec/data/ChainDependencies/app/javascripts/Class/package.yml", "spec/data/ChainDependencies/app/javascripts/Hash/Source/Hash.js", "spec/data/ChainDependencies/app/javascripts/Hash/package.yml", "spec/data/ChainDependencies/app/javascripts/Mash/Source/Mash.js", "spec/data/ChainDependencies/app/javascripts/Mash/package.yml", "spec/data/ExternalDependencies/app/javascripts/Orwik/Source/Test.js", "spec/data/ExternalDependencies/app/javascripts/Orwik/package.yml", "spec/data/OutsideDependencies/README", "spec/data/OutsideDependencies/app/javascripts/Core/Source/Class/Class.Extras.js", "spec/data/OutsideDependencies/app/javascripts/Core/Source/Class/Class.js", "spec/data/OutsideDependencies/app/javascripts/Core/Source/Native/Hash.js", "spec/data/OutsideDependencies/app/javascripts/Core/package.yml", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Library/Color.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Widget/Input/Input.Color.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Widget/Input/Input.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Widget/Widget.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/package.yml", "spec/data/bad_test_source_one.js", "spec/data/bad_test_source_two.js", "spec/data/test_source_one.js", "spec/lib/jsus/container_spec.rb", "spec/lib/jsus/package_spec.rb", "spec/lib/jsus/packager_spec.rb", "spec/lib/jsus/pool_spec.rb", "spec/lib/jsus/source_file_spec.rb", "spec/lib/jsus/topsortable_spec.rb", "spec/shared/class_stubs.rb", "spec/spec.opts", "spec/spec_helper.rb", "jsus.gemspec"]
14
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "TODO", "bin/jsus", "lib/jsus.rb", "lib/jsus/container.rb", "lib/jsus/package.rb", "lib/jsus/packager.rb", "lib/jsus/pool.rb", "lib/jsus/source_file.rb", "lib/jsus/tag.rb"]
15
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "TODO", "bin/jsus", "jsus.gemspec", "lib/jsus.rb", "lib/jsus/container.rb", "lib/jsus/package.rb", "lib/jsus/packager.rb", "lib/jsus/pool.rb", "lib/jsus/source_file.rb", "lib/jsus/tag.rb", "spec/data/Basic/README", "spec/data/Basic/app/javascripts/Orwik/Source/Library/Color.js", "spec/data/Basic/app/javascripts/Orwik/Source/Widget/Input/Input.Color.js", "spec/data/Basic/app/javascripts/Orwik/Source/Widget/Input/Input.js", "spec/data/Basic/app/javascripts/Orwik/Source/Widget/Widget.js", "spec/data/Basic/app/javascripts/Orwik/package.yml", "spec/data/ChainDependencies/app/javascripts/Class/Source/Class.js", "spec/data/ChainDependencies/app/javascripts/Class/package.yml", "spec/data/ChainDependencies/app/javascripts/Hash/Source/Hash.js", "spec/data/ChainDependencies/app/javascripts/Hash/package.yml", "spec/data/ChainDependencies/app/javascripts/Mash/Source/Mash.js", "spec/data/ChainDependencies/app/javascripts/Mash/package.yml", "spec/data/Extensions/app/javascripts/Core/Source/Class.js", "spec/data/Extensions/app/javascripts/Core/package.yml", "spec/data/Extensions/app/javascripts/Orwik/Extensions/Class.js", "spec/data/Extensions/app/javascripts/Orwik/package.yml", "spec/data/ExternalDependencies/app/javascripts/Orwik/Source/Test.js", "spec/data/ExternalDependencies/app/javascripts/Orwik/package.yml", "spec/data/OutsideDependencies/README", "spec/data/OutsideDependencies/app/javascripts/Core/Source/Class/Class.Extras.js", "spec/data/OutsideDependencies/app/javascripts/Core/Source/Class/Class.js", "spec/data/OutsideDependencies/app/javascripts/Core/Source/Native/Hash.js", "spec/data/OutsideDependencies/app/javascripts/Core/package.yml", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Library/Color.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Widget/Input/Input.Color.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Widget/Input/Input.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/Source/Widget/Widget.js", "spec/data/OutsideDependencies/app/javascripts/Orwik/package.yml", "spec/data/bad_test_source_one.js", "spec/data/bad_test_source_two.js", "spec/data/test_source_one.js", "spec/lib/jsus/container_spec.rb", "spec/lib/jsus/package_spec.rb", "spec/lib/jsus/packager_spec.rb", "spec/lib/jsus/pool_spec.rb", "spec/lib/jsus/source_file_spec.rb", "spec/lib/jsus/tag_spec.rb", "spec/shared/class_stubs.rb", "spec/spec.opts", "spec/spec_helper.rb"]
16
16
  s.homepage = %q{http://github.com/markiz/jsus}
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Jsus", "--main", "README"]
18
18
  s.require_paths = ["lib"]
@@ -7,12 +7,20 @@ require 'active_support/core_ext/module/delegation'
7
7
  require 'rgl/adjacency'
8
8
  require 'rgl/topsort'
9
9
 
10
- require 'jsus/topsortable'
11
10
  require 'jsus/source_file'
11
+ require 'jsus/package'
12
+ require 'jsus/tag'
12
13
  require 'jsus/container'
13
14
  require 'jsus/packager'
14
- require 'jsus/package'
15
15
  require 'jsus/pool'
16
16
 
17
+ #
18
+ # Jsus — a library for packaging up your source files.
19
+ #
20
+ # For better understanding of jsus ideas start with http://github.com/Markiz/jsus-examples
21
+ #
22
+ #
23
+
24
+
17
25
  module Jsus
18
26
  end
@@ -1,21 +1,32 @@
1
+ #
2
+ # Container is an array which contains source files. Main difference
3
+ # between it and array is the fact that container maintains topological
4
+ # sort for the source files.
5
+ #
1
6
  module Jsus
2
7
  class Container
3
- include Topsortable
4
-
8
+ #
9
+ # Every argument for initializer is pushed into the container.
10
+ #
5
11
  def initialize(*sources)
6
12
  sources.each do |source|
7
13
  self << source
8
14
  end
9
15
  end
16
+
17
+ # Public API
10
18
 
11
-
12
- # PRO TIP: #<< sorts upon every invokation
13
- # #push doesn't
19
+ #
20
+ # Pushes an item to container and sorts container.
21
+ #
22
+ # When given an array or another container, enumerates its contents.
23
+ #
14
24
  def <<(source)
15
25
  push(source)
16
26
  sort!
17
27
  end
18
28
 
29
+ # Pushes an item to container *without sorting it*. Use with care.
19
30
  def push(source)
20
31
  if source
21
32
  if source.kind_of?(Array) || source.kind_of?(Container)
@@ -27,37 +38,63 @@ module Jsus
27
38
  self
28
39
  end
29
40
 
30
- def flatten
41
+ # Flattens the container items.
42
+ def flatten
31
43
  map {|item| item.respond_to?(:flatten) ? item.flatten : item }.flatten
32
44
  end
33
45
 
34
- def to_a
35
- sources
36
- end
37
-
46
+ # Contains the source files in the correct order.
38
47
  def sources
39
48
  @sources ||= []
40
49
  end
41
-
42
- def sources=(new_value)
50
+ alias_method :to_a, :sources
51
+
52
+ def sources=(new_value) # :nodoc:
43
53
  @sources = new_value
44
54
  end
45
55
 
56
+ # Performs a sort and returns self. Executed automatically by #<< .
46
57
  def sort!
47
- self.sources = topsort(:sources)
58
+ self.sources = topsort
48
59
  self
49
60
  end
50
61
 
51
- def inspect
62
+ def inspect # :nodoc:
52
63
  "#<#{self.class.name}:#{self.object_id} #{self.sources.inspect}>"
53
64
  end
54
65
 
55
- # delegate undefined methods to #sources
66
+ # Private API
67
+
68
+ def topsort # :nodoc:
69
+ graph = RGL::DirectedAdjacencyGraph.new
70
+ provides_map = {}
71
+ # init vertices
72
+ items = self.sources
73
+ items.each do |item|
74
+ graph.add_vertex(item)
75
+ item.provides.each do |provides|
76
+ provides_map[provides] = item
77
+ end
78
+ end
79
+ # init edges
80
+ items.each do |item|
81
+ item.dependencies.each do |dependency|
82
+ if required_item = provides_map[dependency]
83
+ graph.add_edge(required_item, item)
84
+ end
85
+ end
86
+ end
87
+ result = []
88
+ graph.topsort_iterator.each { |item| result << item }
89
+ result
90
+ end
91
+
56
92
  DELEGATED_METHODS = [
57
- "==", "map", "map!", "each", "inject", "reject",
58
- "detect", "size", "length", "[]", "empty?",
59
- "index", "include?"
60
- ]
93
+ "==", "map", "map!", "each", "inject", "inject!",
94
+ "reject", "reject!", "detect", "size", "length", "[]",
95
+ "empty?", "index", "include?", "select", "-", "+", "|", "&"
96
+ ] # :nodoc:
97
+ # delegates most Enumerable methods to #sources
61
98
  (DELEGATED_METHODS).each {|m| delegate m, :to => :sources }
62
99
  end
63
100
  end
@@ -1,16 +1,34 @@
1
+ #
2
+ # Package is basically a list of source files with some meta info.
3
+ #
4
+
5
+
1
6
  module Jsus
2
7
  class Package
3
- attr_accessor :relative_directory
4
- attr_accessor :directory
5
- attr_accessor :pool
6
- # Constructors
8
+ attr_accessor :directory # directory which this package resides in (full path)
9
+ attr_accessor :pool # an instance of Pool
10
+ # Constructors
11
+
12
+ #
13
+ # Creates a package from given directory.
14
+ #
15
+ # Accepts options:
16
+ # * +:pool:+ — which pool the package should belong to.
17
+ #
18
+ # Raises an error when the given directory doesn't contain a package.yml
19
+ # file with meta info.
20
+ #
7
21
  def initialize(directory, options = {})
8
- self.relative_directory = directory
9
- self.directory = File.expand_path(directory)
10
- self.header = YAML.load_file(File.join(directory, 'package.yml'))
22
+ self.directory = File.expand_path(directory)
23
+ self.header = YAML.load_file(File.join(directory, 'package.yml'))
11
24
  Dir.chdir(directory) do
12
25
  files.each do |source|
13
- source_files << SourceFile.from_file(source, :package => self)
26
+ source_file = SourceFile.from_file(source, :package => self)
27
+ if source_file.extension?
28
+ extensions << source_file
29
+ else
30
+ source_files << source_file
31
+ end
14
32
  end
15
33
  end
16
34
  if options[:pool]
@@ -21,56 +39,78 @@ module Jsus
21
39
 
22
40
 
23
41
  # Public API
42
+
43
+ # Returns a package.yml header.
24
44
  def header
25
45
  @header ||= {}
26
46
  end
27
47
 
28
- def header=(new_header)
29
- @header = new_header
30
- end
31
-
48
+ # Returns a package name.
32
49
  def name
33
50
  header["name"] ||= ""
34
51
  end
52
+
53
+ # Returns a package description.
54
+ def description
55
+ header["description"] ||= ""
56
+ end
35
57
 
58
+ # Returns a filename for compiled package.
36
59
  def filename
37
60
  header["filename"] ||= name + ".js"
38
61
  end
39
62
 
40
- def provides
41
- (source_files.map {|source| source.provides(:short => true) } + linked_external_dependencies.map {|d| d.provides }).flatten
42
- end
43
-
63
+ # Returns a list of sources filenames.
44
64
  def files
45
65
  header["files"] = header["files"] || header["sources"] || []
46
66
  end
47
-
48
67
  alias_method :sources, :files
49
68
 
50
- def dependencies
51
- source_files.map {|source| source.dependencies(:short => true) }.flatten.compact.uniq - provides
69
+ # Returns an array of provided tags including those provided by linked external dependencies.
70
+ def provides
71
+ source_files.map {|s| s.provides }.flatten | linked_external_dependencies.map {|d| d.provides }.flatten
52
72
  end
53
73
 
54
- def external_dependencies
55
- source_files.map {|source| source.external_dependencies }
74
+ # Returns an array of provided tags names including those provided by linked external dependencies.
75
+ def provides_names
76
+ source_files.map {|s| s.provides_names(:short => true) }.flatten |
77
+ linked_external_dependencies.map {|d| d.provides_names }.flatten
56
78
  end
57
79
 
58
- def linked_external_dependencies
59
- @linked_external_dependencies ||= Container.new
80
+ # Returns an array of unresolved dependencies' tags for the package.
81
+ def dependencies
82
+ result = source_files.map {|source| source.dependencies }.flatten
83
+ result |= linked_external_dependencies.map {|d| d.dependencies}.flatten
84
+ result -= provides
85
+ result
60
86
  end
61
87
 
62
- def linked_external_dependencies=(new_value)
63
- @linked_external_dependencies = new_value
88
+ # Returns an array of unresolved dependencies' names.
89
+ def dependencies_names
90
+ dependencies.map {|d| d.name(:short => true) }
64
91
  end
65
92
 
66
- def description
67
- header["description"] ||= ""
68
- end
93
+ # Returns an array of external dependencies' tags (including resolved ones).
94
+ def external_dependencies
95
+ source_files.map {|s| s.external_dependencies }.flatten
96
+ end
97
+
98
+ # Returns an array of external dependencies' names (including resolved ones).
99
+ def external_dependencies_names
100
+ external_dependencies.map {|d| d.name }
101
+ end
69
102
 
103
+ # Returns source files with external dependencies in correct order.
104
+ def linked_external_dependencies
105
+ @linked_external_dependencies ||= Container.new
106
+ end
107
+
108
+ # Compiles source files and linked external source files into a given category.
70
109
  def compile(directory = ".")
71
110
  Packager.new(*(source_files.to_a + linked_external_dependencies.to_a)).pack(File.join(directory, filename))
72
111
  end
73
112
 
113
+ # Generates tree structure for files in package into a json file.
74
114
  def generate_tree(directory = ".", filename = "tree.json")
75
115
  FileUtils.mkdir_p(directory)
76
116
  result = ActiveSupport::OrderedHash.new
@@ -89,38 +129,62 @@ module Jsus
89
129
  result
90
130
  end
91
131
 
132
+ # Generates info about resulting compiled package into a json file.
92
133
  def generate_scripts_info(directory = ".", filename = "scripts.json")
93
134
  FileUtils.mkdir_p directory
94
135
  File.open(File.join(directory, filename), "w") { |resulting_file| resulting_file << JSON.pretty_generate(self.to_hash) }
95
136
  self.to_hash
96
137
  end
97
138
 
139
+ # Looks up all the external dependencies in the pool.
98
140
  def include_dependencies!
99
141
  source_files.each do |source|
100
142
  linked_external_dependencies << pool.lookup_dependencies(source)
101
143
  end
102
144
  end
103
145
 
146
+ # Executes #include_extensions for all the source files.
147
+ def include_extensions!
148
+ source_files.each do |source|
149
+ source.include_extensions!
150
+ end
151
+ end
104
152
 
105
- def required_files
106
- source_files.map {|s| s.filename }
153
+ # Lists the required files for the package.
154
+ def required_files
155
+ source_files.map {|s| s.required_files }.flatten
107
156
  end
108
157
 
109
- def to_hash
158
+ def to_hash # :nodoc:
110
159
  {
111
160
  name => {
112
161
  :desc => description,
113
- :provides => provides,
114
- :requires => dependencies
162
+ :provides => provides_names,
163
+ :requires => dependencies_names
115
164
  }
116
165
  }
117
166
  end
118
167
 
119
-
168
+ # Container with source files
120
169
  def source_files
121
170
  @source_files ||= Container.new
122
171
  end
123
172
 
173
+ # Container with extensions (they aren't compiled or included into #reqired_files list)
174
+ def extensions
175
+ @extensions ||= Container.new
176
+ end
177
+
178
+ # Private API
179
+
180
+ def header=(new_header) # :nodoc:
181
+ @header = new_header
182
+ end
183
+
184
+ def linked_external_dependencies=(new_value) # :nodoc:
185
+ @linked_external_dependencies = new_value
186
+ end
187
+
124
188
  protected
125
189
  end
126
- end
190
+ end
@@ -1,15 +1,30 @@
1
+ #
2
+ # Packager is a plain simple class accepting several source files
3
+ # and joining their contents.
4
+ #
5
+ # It uses Container for storage which means it automatically sorts sources.
6
+ #
1
7
  module Jsus
2
8
  class Packager
3
- attr_accessor :container
9
+ attr_accessor :container # :nodoc:
4
10
 
11
+ #
12
+ # Inits packager with the given sources.
13
+ #
5
14
  def initialize(*sources)
6
15
  self.container = Container.new(*sources)
7
16
  end
8
17
 
9
- def sources
18
+ def sources # :nodoc:
10
19
  container.sources
11
20
  end
12
21
 
22
+ #
23
+ # Concatenates all the sources' contents into a single string.
24
+ # If given a filename, outputs into a file.
25
+ #
26
+ # Returns the concatenation.
27
+ #
13
28
  def pack(output_file = nil)
14
29
  result = sources.map {|s| s.content }.join("\n")
15
30