jsdm 0.3.2 → 0.4.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.
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2009, 2010 Border Stylo
2
+ Copyright (c) 2010 Min Huang
3
+
4
+ Permission is hereby granted, free of charge, to any person
5
+ obtaining a copy of this software and associated documentation
6
+ files (the "Software"), to deal in the Software without
7
+ restriction, including without limitation the rights to use,
8
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the
10
+ Software is furnished to do so, subject to the following
11
+ conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,73 @@
1
+ Description
2
+ ===========
3
+
4
+ JSDM is a JavaScript dependency management library written in Ruby - that is
5
+ all. It does not do anything special; in fact, it could be used to manage
6
+ dependencies for any language as you can change what JSDM considers a
7
+ comment or a require statement. JSDM will also...
8
+
9
+ * Perform topological sort to report circular dependencies to you.
10
+ * Allow you to have globs in your require statements.
11
+ * Allow you to specify load paths.
12
+
13
+ Installation
14
+ ============
15
+ To install from source:
16
+
17
+ rake clobber
18
+ rake package
19
+ gem install pkg/jsdm-*.gem
20
+
21
+ To install from rubygems.org:
22
+
23
+ gem install jsdm
24
+
25
+ Usage
26
+ =====
27
+ In your Javascript files, put #require directives in comments at the top of
28
+ your file (note that they must be the non-whitespace characters in your file
29
+ for JSDM to process them correctly):
30
+
31
+ // #require jquery.js
32
+ // #require MyLibrary1.js
33
+ // #require MyLibrary2.js
34
+ // #require other/*.js
35
+ // #require thing/**/*.js
36
+
37
+ Next you will need to tell JSDM which directories contain your Javascript
38
+ files (this is your load path).
39
+
40
+ jsdm = JSDM.new :load_path => %w(path_1 path_2 path_3)
41
+
42
+ Here is an example for using JSDM to concatenate all your sources into one
43
+ big JavaScript file:
44
+
45
+ require 'jsdm'
46
+
47
+ jsdm = JSDM.new :load_path => %w(path_1 path_2 path_3 path_4)
48
+ File.open('result.js', 'w') do |out|
49
+ jsdm.sources.each do |f|
50
+ out.puts "// Filename: #{f}"
51
+ out.puts File.read(f)
52
+ end
53
+ end
54
+
55
+ Here is an example that finds all the dependencies for file foo.js so it
56
+ can generate the script tags for that file:
57
+
58
+ require 'jsdm'
59
+
60
+ Dir.chdir '/path/to/local/js/files' do
61
+ jsdm = JSDM.new :load_path => '.'
62
+ jsdm.dependencies_for('foo.js') do |f|
63
+ puts "<script src='/path/to/server/js/files/#{f}' />"
64
+ end
65
+ end
66
+
67
+ License
68
+ =======
69
+ The following is retained from BorderStylo's licensing terms:
70
+
71
+ JSDM version 0.2.20 and above is licensed under the MIT license.
72
+
73
+ No license is granted for versions previous to 0.2.20.
data/Rakefile CHANGED
@@ -1,42 +1,41 @@
1
1
  require 'fileutils'
2
2
  require 'rake'
3
+ require 'rake/clean'
3
4
  require 'rake/gempackagetask'
4
5
  require 'rake/rdoctask'
5
6
 
6
7
  spec = Gem::Specification.new do |s|
7
- s.platform = Gem::Platform::RUBY
8
- s.name = "jsdm"
9
- s.author = "Min Huang"
10
- s.email = "min.huang@alumni.usc.edu"
11
- s.files = Dir["lib/**/*"] + %w(Rakefile)
12
- s.require_path = "lib"
13
- s.has_rdoc = true
14
- s.homepage = "http://www.borderstylo.com/#{s.name}"
15
- s.version = "0.3.2"
16
- s.summary = "Javascript dependency manager"
17
- s.description = "Use #require statements to declare dependencies"
8
+ s.platform = Gem::Platform::RUBY
9
+ s.name = 'jsdm'
10
+ s.author = 'Min Huang'
11
+ s.email = 'min.huang@alumni.usc.edu'
12
+ s.files = Dir["{lib,doc,bin,ext}/**/*"].delete_if { |f|
13
+ /\/rdoc(\/|$)/i.match f
14
+ } + %w(Rakefile LICENSE README.md)
15
+ s.require_path = 'lib'
16
+ s.has_rdoc = true
17
+ s.homepage = "http://www.borderstylo.com/#{s.name}"
18
+ s.version = '0.4.0'
19
+ s.summary = 'Javascript dependency manager'
20
+ s.description = 'Use #require statements to declare dependencies'
21
+ s.rubyforge_project = 'jsdm'
18
22
  end
19
23
 
20
24
  Rake::GemPackageTask.new(spec) do |pkg|
21
25
  pkg.need_tar_bz2 = true
22
26
  end
23
27
 
24
- desc "Clean the build"
25
- task :clean do
26
- FileUtils.rm_rf "pkg", :verbose => true
27
- end
28
-
29
- desc "Run tests (no arg), or single test (with arg)"
28
+ desc 'Run tests (no arg), or single test (with arg)'
30
29
  task :test, :name do |t, args|
31
- opts = args.name.nil? ? "" : "-n test_#{args.name}"
30
+ opts = args.name.nil? ? '' : "-n test_#{args.name}"
32
31
  cmd = "ruby test/run_tests.rb #{opts}"
33
32
  puts cmd
34
- system(cmd) || raise("Build error")
33
+ system(cmd) || raise('Build error')
35
34
  end
36
35
 
37
- task :install => [:test, :package] do
36
+ task :install => :package do
38
37
  g = "pkg/#{spec.name}-#{spec.version}.gem"
39
38
  system "sudo gem install -l #{g}"
40
39
  end
41
40
 
42
- task :default => :test
41
+ task :default => :package
@@ -4,32 +4,40 @@ require 'jsdm/errors'
4
4
  require 'jsdm/preprocessor'
5
5
 
6
6
  class JSDM
7
- attr_accessor :load_path,
7
+ attr_accessor :options,
8
8
  :sources,
9
9
  :requires,
10
10
  :preprocessor,
11
11
  :manager,
12
- :resolver,
13
- :ext
12
+ :resolver
14
13
 
15
- def initialize(load_path = [], options = {})
16
- self.load_path = load_path
14
+ def initialize(opts = {})
15
+ defaults = {
16
+ :randomize => true,
17
+ :load_path => '.',
18
+ :extension => 'js',
19
+ :comment_pattern => Preprocessor.comment_pattern,
20
+ :require_pattern => Preprocessor.require_pattern
21
+ }
22
+ self.options = defaults.merge opts
17
23
  self.sources = []
18
24
  self.preprocessor = nil
19
25
  self.manager = nil
20
26
  self.resolver = nil
21
- self.ext = options[:ext].nil? ? 'js' : options[:ext]
22
- process!
27
+ unless options[:load_path].is_a?(Array)
28
+ options[:load_path] = [options[:load_path]]
29
+ end
30
+ process
23
31
  end
24
32
 
25
- def process!
26
- self.sources = load_path.map { |path| Dir["#{path}/**/*.#{ext}"] }.
27
- flatten.
28
- sort
29
- self.sources = sources.sort { rand }
30
- self.preprocessor = Preprocessor.new sources
33
+ def process
34
+ self.sources = options[:load_path].map { |path|
35
+ Dir[File.join(path, '**', "*.#{options[:extension]}")]
36
+ }.flatten
37
+ self.sources = sources.sort { rand } if options[:randomize]
38
+ self.preprocessor = Preprocessor.new sources, options
31
39
  self.manager = DependencyManager.new sources
32
- self.resolver = DependencyResolver.new load_path
40
+ self.resolver = DependencyResolver.new options[:load_path]
33
41
  self.requires = preprocessor.process
34
42
  begin
35
43
  source = nil
@@ -47,21 +55,19 @@ class JSDM
47
55
  sources
48
56
  end
49
57
 
50
- def sources_for(source)
51
- ds = manager.dependencies_of(source)
52
- ds.push(source)
53
- ds
58
+ def dependencies
59
+ manager.dependencies
54
60
  end
55
61
 
56
- def requires_for(source)
57
- requires.select { |r| r.first == source }.first.last
62
+ def dependencies_for(source)
63
+ manager.dependencies_for(source)
58
64
  end
59
65
 
60
- def dependencies
61
- manager.dependencies
66
+ def sources_for(source)
67
+ dependencies_for(source) << source
62
68
  end
63
69
 
64
- def self.same_file?(a, b)
65
- File.expand_path(a) == File.expand_path(b)
70
+ def requires_for(source)
71
+ requires.select { |r| r.first == source }.first.last
66
72
  end
67
73
  end
@@ -15,17 +15,17 @@ class JSDM
15
15
  end
16
16
 
17
17
  def add_dependency(source, dependency)
18
- unless JSDM.same_file? dependency, source
18
+ unless same_file? dependency, source
19
19
  dependencies << [dependency, source]
20
20
  end
21
21
  end
22
22
 
23
- def dependencies_of(source, acc = [])
23
+ def dependencies_for(source, acc = [])
24
24
  ds = dependencies.select { |d| d.last == source }.
25
25
  map { |d| d.first }
26
26
  return acc if ds.empty?
27
27
  acc = acc | ds
28
- ds.each { |d| acc = acc | dependencies_of(d, acc) }
28
+ ds.each { |d| acc = acc | dependencies_for(d, acc) }
29
29
  acc
30
30
  end
31
31
 
@@ -38,5 +38,11 @@ class JSDM
38
38
  raise CircularDependencyError.new(loops) unless loops.empty?
39
39
  result[:sorted]
40
40
  end
41
+
42
+ private
43
+
44
+ def same_file?(a, b)
45
+ File.expand_path(a) == File.expand_path(b)
46
+ end
41
47
  end
42
48
  end
@@ -9,15 +9,14 @@ class JSDM
9
9
  end
10
10
 
11
11
  def process(entries)
12
- entries = entries.map { |entry| process_single entry }
13
- entries = entries.flatten
14
- entries
12
+ entries.map { |entry| process_single entry }.
13
+ flatten
15
14
  end
16
15
 
17
16
  def process_single(entry)
18
- resolved = load_path.map { |path| Dir["#{path}/#{entry.strip}"] }
19
- resolved = resolved.drop_while { |sources| sources.empty? }
20
- resolved = resolved.first
17
+ resolved = load_path.map { |path| Dir[File.join(path, entry.strip)] }.
18
+ drop_while { |sources| sources.empty? }.
19
+ first
21
20
  raise FileNotFoundError.new(entry) if resolved.nil? || resolved.empty?
22
21
  resolved
23
22
  end
@@ -1,19 +1,22 @@
1
1
  class JSDM
2
2
  class Preprocessor
3
- attr_accessor :sources, :comment_pattern, :require_pattern
3
+ attr_accessor :sources, :options
4
4
 
5
- def initialize(sources)
5
+ def initialize(sources, options = {})
6
+ defaults = {
7
+ :comment_pattern => Preprocessor.comment_pattern,
8
+ :require_pattern => Preprocessor.require_pattern
9
+ }
6
10
  self.sources = sources
7
- self.comment_pattern = /^\s*\/\/\s*/
8
- self.require_pattern = /#{comment_pattern}#\s*require\s*/
11
+ self.options = defaults.merge options
9
12
  end
10
13
 
11
14
  def process_single(source)
12
15
  File.open(source).
13
16
  each_line.
14
- take_while { |line| line =~ comment_pattern }.
15
- select { |line| line =~ require_pattern }.
16
- map { |line| line.sub!(require_pattern, "").split(",") }.
17
+ take_while { |line| line =~ options[:comment_pattern] }.
18
+ select { |line| line =~ options[:require_pattern] }.
19
+ map { |line| line.sub!(options[:require_pattern], '').split(',') }.
17
20
  flatten.
18
21
  map { |entry| entry.strip }
19
22
  end
@@ -21,5 +24,13 @@ class JSDM
21
24
  def process
22
25
  sources.map { |source| [source, process_single(source)] }
23
26
  end
27
+
28
+ class << self
29
+ attr_accessor :comment_pattern, :require_pattern
30
+ private :comment_pattern=, :require_pattern=
31
+ end
32
+
33
+ self.comment_pattern = /^\s*\/\/\s*/
34
+ self.require_pattern = /#{self.comment_pattern}#\s*require\s*/
24
35
  end
25
36
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
8
- - 2
9
- version: 0.3.2
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Min Huang
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-30 00:00:00 -07:00
17
+ date: 2010-05-31 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -36,6 +36,8 @@ files:
36
36
  - lib/jsdm/natural_loops.rb
37
37
  - lib/jsdm/dependency_resolver.rb
38
38
  - Rakefile
39
+ - LICENSE
40
+ - README.md
39
41
  has_rdoc: true
40
42
  homepage: http://www.borderstylo.com/jsdm
41
43
  licenses: []
@@ -61,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
63
  version: "0"
62
64
  requirements: []
63
65
 
64
- rubyforge_project:
66
+ rubyforge_project: jsdm
65
67
  rubygems_version: 1.3.6
66
68
  signing_key:
67
69
  specification_version: 3