epic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,28 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+
23
+ tmp
24
+ vendor/bin/*
25
+ vendor/gems/*
26
+ !vendor/gems/cache/
27
+ features/data/servers
28
+ features/data/tmp
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ gem "w3c_validators"
2
+ gem "activesupport", :require_as => "active_support"
3
+ gem "progressions-g", :require_as => "g"
4
+
5
+ bin_path "vendor/bin"
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 0.0.1 2010-01-25
2
+ * validates JavaScript and HTML (CSS coming soon)
3
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Capital Thought
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = epic
2
+
3
+ Epic validator which can validate HTML, JavaScript and CSS.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Capital Thought. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "epic"
8
+ gem.summary = %Q{Epic validation of HTML, JavaScript and CSS}
9
+ gem.description = %Q{Epic validator, wraps validation for HTML, JavaScript and CSS.}
10
+ gem.email = "progressions@gmail.com"
11
+ gem.homepage = "http://github.com/progressions/epic"
12
+ gem.authors = ["Jeff Coleman"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.6"
14
+ gem.add_runtime_dependency "w3c_validators"
15
+ gem.add_runtime_dependency "progressions-g"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ spec.spec_opts = ['-c']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+
37
+ task :bundle do
38
+ require 'vendor/gems/environment'
39
+ Bundler.require_env
40
+ end
41
+
42
+ task :spec => [:bundle, :check_dependencies]
43
+
44
+ task :default => :spec
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "epic #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/epic ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir)
5
+
6
+ require 'epic'
7
+
8
+ file = ARGV[0]
9
+
10
+ Epic::Validator::Base.configure do |config|
11
+ config.base_path = "./"
12
+ config.tmp_path = "./tmp"
13
+ end
14
+
15
+ if file =~ /.js$/
16
+ Epic::Validator::JavaScript.new.validate(file)
17
+ end
18
+
19
+ system "rm -rf ./tmp"
data/epic.gemspec ADDED
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{epic}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jeff Coleman"]
12
+ s.date = %q{2010-01-25}
13
+ s.default_executable = %q{epic}
14
+ s.description = %q{Epic validator, wraps validation for HTML, JavaScript and CSS.}
15
+ s.email = %q{progressions@gmail.com}
16
+ s.executables = ["epic"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "Gemfile",
25
+ "History.txt",
26
+ "LICENSE",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "bin/epic",
31
+ "epic.gemspec",
32
+ "lib/epic.rb",
33
+ "lib/file.rb",
34
+ "spec/epic_spec.rb",
35
+ "spec/spec.opts",
36
+ "spec/spec_helper.rb",
37
+ "spec/stubs.rb",
38
+ "vendor/ext/js.jar",
39
+ "vendor/ext/jslint.js"
40
+ ]
41
+ s.homepage = %q{http://github.com/progressions/epic}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.5}
45
+ s.summary = %q{Epic validation of HTML, JavaScript and CSS}
46
+ s.test_files = [
47
+ "spec/epic_spec.rb",
48
+ "spec/spec_helper.rb",
49
+ "spec/stubs.rb"
50
+ ]
51
+
52
+ if s.respond_to? :specification_version then
53
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
+ s.specification_version = 3
55
+
56
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
57
+ s.add_development_dependency(%q<rspec>, [">= 1.2.6"])
58
+ s.add_runtime_dependency(%q<w3c_validators>, [">= 0"])
59
+ s.add_runtime_dependency(%q<progressions-g>, [">= 0"])
60
+ else
61
+ s.add_dependency(%q<rspec>, [">= 1.2.6"])
62
+ s.add_dependency(%q<w3c_validators>, [">= 0"])
63
+ s.add_dependency(%q<progressions-g>, [">= 0"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<rspec>, [">= 1.2.6"])
67
+ s.add_dependency(%q<w3c_validators>, [">= 0"])
68
+ s.add_dependency(%q<progressions-g>, [">= 0"])
69
+ end
70
+ end
71
+
data/lib/epic.rb ADDED
@@ -0,0 +1,158 @@
1
+ require 'rubygems'
2
+ require 'lib/file'
3
+ require 'g'
4
+ require 'active_support'
5
+ require 'w3c_validators'
6
+
7
+ module Epic
8
+ module Validator
9
+ class Configuration
10
+ attr_accessor :base_path, :tmp_path, :doctype, :jslint_settings
11
+ end
12
+
13
+ class Base
14
+ class << self
15
+ def configuration
16
+ @@configuration ||= Epic::Validator::Configuration.new
17
+ end
18
+
19
+ def configure
20
+ yield configuration
21
+ end
22
+ end
23
+
24
+ def configuration
25
+ self.class.configuration
26
+ end
27
+
28
+ # Parses out the <tt>base_path</tt> setting from a path to display it in a
29
+ # less verbose way.
30
+ #
31
+ def display_path(path)
32
+ path = File.expand_path(path)
33
+ path.gsub(base_path.to_s, "")
34
+ end
35
+
36
+ def base_path
37
+ configuration.base_path || ""
38
+ end
39
+
40
+ def tmp_path
41
+ configuration.tmp_path || ""
42
+ end
43
+ end
44
+
45
+ class HTML < Base
46
+ def validator
47
+ @validator ||= W3CValidators::MarkupValidator.new
48
+ end
49
+
50
+ def validate(path)
51
+ $stdout.print " #{path} validating . . . "
52
+
53
+ doctype = configuration.doctype || "HTML 4.01 Transitional"
54
+ validator.set_doctype!(doctype)
55
+
56
+ results = validator.validate_file(path)
57
+
58
+ valid = results.errors.length <= 0
59
+
60
+ if valid
61
+ $stdout.puts "OK"
62
+ else
63
+ $stdout.puts "validation errors"
64
+ results.errors.each do |err|
65
+ $stdout.puts
66
+ $stdout.puts err.to_s
67
+ end
68
+ end
69
+
70
+ valid
71
+ end
72
+ end
73
+
74
+ class JavaScript < Base
75
+ def use_jslint_settings?
76
+ !jslint_settings.blank?
77
+ end
78
+
79
+ def jslint_settings
80
+ configuration.jslint_settings
81
+ end
82
+
83
+ def jslint_settings_count
84
+ jslint_settings.to_s.split("\n").size
85
+ end
86
+
87
+ def pre_process(content)
88
+ content
89
+ end
90
+
91
+ def validate(path)
92
+ display = display_path(path)
93
+ $stdout.print " #{display} validating . . . "
94
+ output = ""
95
+
96
+ File.open(path) do |f|
97
+ output = f.read
98
+ end
99
+
100
+ output = pre_process(output)
101
+
102
+ FileUtils.mkdir_p(tmp_path)
103
+
104
+ js_fragment_path = File.expand_path("#{tmp_path}/#{File.basename(path)}_fragment")
105
+ fragment_display_path = display_path(js_fragment_path)
106
+
107
+ if File.exists?(js_fragment_path)
108
+ puts "That already exists?"
109
+ else
110
+ File.open(js_fragment_path,'w') do |f|
111
+ f.puts jslint_settings if use_jslint_settings?
112
+ f.puts output
113
+ end
114
+
115
+ jslint_path = File.expand_path("#{File.dirname(__FILE__)}/../vendor/ext/jslint.js")
116
+ raise "#{jslint_path} does not exist" unless File.exists?(jslint_path)
117
+ rhino_path = File.expand_path("#{File.dirname(__FILE__)}/../vendor/ext/js.jar")
118
+ raise "#{rhino_path} does not exist" unless File.exists?(rhino_path)
119
+
120
+ results = F.execute("java -jar #{rhino_path} #{jslint_path} #{js_fragment_path}", :return => true)
121
+
122
+ if results =~ /jslint: No problems found/
123
+ $stdout.puts "OK"
124
+ else
125
+ $stdout.puts "errors found!"
126
+ results.split("\n").each do |result|
127
+ if result =~ /line (\d+) character (\d+): (.*)/
128
+ line_number = $1.to_i
129
+ error = "Error at #{fragment_display_path} line #{line_number-jslint_settings_count} character #{$2}: #{$3}"
130
+ error += F.get_line_from_file(js_fragment_path, line_number)
131
+
132
+ $stdout.puts error
133
+ end
134
+ end
135
+ message = "JavaScript Errors embedded in #{display}"
136
+ g(message)
137
+ raise message
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ class JSON < JavaScript
144
+ def pre_process(output)
145
+ output
146
+ end
147
+
148
+ def jslint_settings
149
+ end
150
+ end
151
+
152
+ class Stylesheet < Base
153
+ def validate(filename)
154
+ true
155
+ end
156
+ end
157
+ end
158
+ end
data/lib/file.rb ADDED
@@ -0,0 +1,63 @@
1
+ # Provides a wrapper around common calls that interact with the file system.
2
+ #
3
+ module F
4
+
5
+ module_function
6
+
7
+ # Concatenates together the contents of all the files in the <tt>source_path</tt>
8
+ # into the <tt>destination_path</tt>.
9
+ #
10
+ def concat_files(source_path, destination_path)
11
+ File.open(destination_path, "a") do |output|
12
+ Dir[source_path].each do |path|
13
+ output.puts File.read(path)
14
+ end
15
+ end
16
+ end
17
+
18
+ # Saves the <tt>output</tt> string to the <tt>destination_path</tt> given.
19
+ #
20
+ # Returns <tt>true</tt> if the destination file was newly created, <tt>false</tt> if
21
+ # it already existed.
22
+ #
23
+ def save_to_file(output, destination_path)
24
+ if File.exists?(destination_path)
25
+ false
26
+ else
27
+ File.open(destination_path, "w") do |w|
28
+ w.write(output)
29
+ end
30
+ true
31
+ end
32
+ end
33
+
34
+ # Given a <tt>path</tt> and <tt>line_number</tt>, returns the line and two lines previous
35
+ #
36
+ # Used for displaying validation errors.
37
+ #
38
+ def get_line_from_file(path, line_number)
39
+ line_number = line_number.to_i
40
+ output = "\n"
41
+ lines = File.readlines(path)
42
+
43
+ 3.times do |i|
44
+ line = lines[line_number-(3-i)]
45
+ output += line if line
46
+ end
47
+
48
+ output += "\n"
49
+ output
50
+ end
51
+
52
+ # Execute a system command. If the parameter <tt>:return</tt> is true, execute the command
53
+ # with the backtick (`) command and return the results. Otherwise, just execute the command
54
+ # and let the output go to the screen.
55
+ #
56
+ def execute(command, params={})
57
+ if params[:return]
58
+ `#{command}`
59
+ else
60
+ Kernel.system command
61
+ end
62
+ end
63
+ end