jsus 0.1.4 → 0.1.5

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