syntaxer 0.1.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.
@@ -0,0 +1,41 @@
1
+ require "rainbow"
2
+ module Syntaxer
3
+
4
+ # Print system messages
5
+
6
+ class Printer
7
+ class << self
8
+ attr_accessor :quite
9
+
10
+ # Print progress in dot notation
11
+ #
12
+ # @param [Boolean] (true|false)
13
+
14
+ def print_progress succ = true
15
+ if succ
16
+ s = '.'.color(:green)
17
+ else
18
+ s = 'E'.color(:red)
19
+ end
20
+ print s unless @quite
21
+ end
22
+
23
+ # Print error message for each if file
24
+ #
25
+ # @param [Array, #each] files
26
+
27
+ def print_result files
28
+ return if @quite
29
+ puts "\n"
30
+ puts "Syntax OK".color(:green) if files.empty?
31
+
32
+ files.each do |file|
33
+ puts file.file_name
34
+ file.errors.each do |error|
35
+ puts "\t #{error}".color(:red)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,12 @@
1
+ require 'syntaxer'
2
+
3
+ module Syntaxer
4
+ if defined? Rails::Railtie
5
+ require 'rails'
6
+ class Railtie < Rails::Railtie
7
+ rake_tasks do
8
+ load "tasks/syntaxer.rake"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,147 @@
1
+ # @author Artyom Kramarenko
2
+ module Syntaxer
3
+ module Reader
4
+ class DSLFileNotFoundError < Exception; end
5
+ class DSLError < Exception; end
6
+ class DSLSyntaxError < DSLError; end
7
+
8
+ class DSLReader
9
+
10
+ attr_reader :rules, :ignored_folders
11
+
12
+ def initialize
13
+ @rules = LanguageRules.new
14
+ @ignore_folders = []
15
+ end
16
+
17
+ class << self
18
+
19
+ # Read files from params and send to {#parse} method to fill in {Syntaxer::LanguageDefinition LanguageDefinition} objects.
20
+ #
21
+ # @param [Array] dsl_files Files with syntaxer rules and language definitions to be used in syntax checking
22
+ #
23
+ # @return [DSLReader] reader object
24
+ #
25
+ # @raise [DSLFileNotFoundError] If file with file is not exists
26
+ def load(*dsl_files)
27
+ reader = build
28
+ dsl_files = [dsl_files].flatten
29
+ dsl_files.each do |file|
30
+ begin
31
+ reader.parse(File.read(file))
32
+ rescue SystemCallError
33
+ raise ::Syntaxer::Reader::DSLFileNotFoundError, "Error reading syntaxer rules file with path '#{file}'! Please ensure it exists and that it is accessible."
34
+ end
35
+ end
36
+ reader
37
+ end
38
+
39
+ def build(skip_default_rules = false, default_rules_file = SYNTAXER_RULES_FILE)
40
+ reader = new
41
+ reader.parse(File.read(default_rules_file)) unless skip_default_rules
42
+ reader
43
+ end
44
+ end
45
+
46
+ # Parses a syntaxer DSL specification from the string given.
47
+ #
48
+ # @param [String] dsl_data Text of actual data to be parsed
49
+ #
50
+ # @raise [DSLSyntaxError] If errors occur on parsing
51
+ # @example
52
+ # Syntaxer::Reader::DSLReader.new.parse%|
53
+ # syntaxer do
54
+ # languages :ruby
55
+ # folders 'app/**/*', 'lib/**/*'
56
+ # end
57
+ # end
58
+ # |
59
+ def parse(dsl_data)
60
+ self.instance_eval(dsl_data)
61
+ @rules << @current_rule
62
+ rescue SyntaxError, NoMethodError, NameError => e
63
+ raise DSLSyntaxError, "Illegal DSL syntax: #{e}"
64
+ end
65
+
66
+ # The top level block executor
67
+ #
68
+ # @yield Description of block
69
+ #
70
+ # @example
71
+ # syntaxer do
72
+ # languages :ruby
73
+ # folders 'app/**/*', 'lib/**/*'
74
+ # end
75
+ # end
76
+ def syntaxer(&block)
77
+ self.instance_eval(&block)
78
+ end
79
+
80
+ # The languages block executor
81
+ #
82
+ # @yield [langs_name] Description of block
83
+ # @return [nil]
84
+ #
85
+ #
86
+ # @example
87
+ # languages :ruby do
88
+ # folders 'app/**/*', 'lib/**/*'
89
+ # end
90
+ # @see #syntaxer
91
+ def languages(*args, &block)
92
+ args.each do |lang|
93
+ @current_rule = @rules.find_or_create(lang)
94
+ self.instance_eval(&block)
95
+ end
96
+ end
97
+
98
+ # Stub for DSL folders method.
99
+ #
100
+ # @note This method won't check if files are really exist.
101
+ #
102
+ # @param [Array(String)] args File regexps to be assigned for particular language
103
+ #
104
+ # @example
105
+ # folders('app/**/*', 'lib/**/*') #=> ['app/**/*', 'lib/**/*']
106
+ # folders() # => DEFAULT_FILES_MASK
107
+ # @return [args]
108
+ #
109
+ # @see #syntaxer
110
+ def folders(*args)
111
+ current_rule.folders = (args.empty? ? [DEFAULT_FILES_MASK] : args.flatten)
112
+ end
113
+
114
+ def extensions(*args)
115
+ current_rule.extensions = args
116
+ end
117
+
118
+ def specific_files(*args)
119
+ current_rule.specific_files = args
120
+ end
121
+
122
+ def exec_rule(exec_string)
123
+ current_rule.exec_rule = exec_string
124
+ end
125
+
126
+ def ignore_folders(ignore_folders)
127
+ current_rule.ignore_folders = ignore_folders
128
+ end
129
+
130
+ def overall_ignore_folders(*args)
131
+ @ignored_folders = args
132
+ end
133
+
134
+
135
+ alias_method :ignore, :overall_ignore_folders
136
+ alias_method :lang, :languages
137
+ alias_method :f, :folders
138
+
139
+ private
140
+ def current_rule
141
+ @current_rule
142
+ end
143
+ end #end of class DSLReader
144
+
145
+
146
+ end #end of module Reader
147
+ end #end of module Syntaxer
@@ -0,0 +1,80 @@
1
+ module Syntaxer
2
+ class RepositoryError < Exception; end
3
+ class GitRepositoryError < RepositoryError; end
4
+ class SvnRepositoryError < RepositoryError; end
5
+
6
+ class Repository
7
+
8
+ def self.factory(root_path, type_of_repository)
9
+ case type_of_repository.to_sym
10
+ when :git then Git.new(root_path)
11
+ when :svn then Svn.new(root_path)
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+
18
+ class Git
19
+ require "git"
20
+
21
+ def initialize(repo_path)
22
+ @repository = ::Git.open(Dir.new(repo_path))
23
+ rescue ArgumentError => ex
24
+ raise GitRepositoryError, "The path you specified is not a git repository: '#{File.expand_path(repo_path)}'"
25
+ end
26
+
27
+ # Returns list of files what have been changed
28
+ #
29
+ # @return [Array]
30
+
31
+ def changed_files
32
+ @repository.chdir do
33
+ @changed ||= @repository.status.changed.keys
34
+ end
35
+ end
36
+
37
+ # Returns list of files what have been added
38
+ #
39
+ # @return [Array]
40
+
41
+ def added_files
42
+ @repository.chdir do
43
+ @added ||= @repository.status.added.keys
44
+ end
45
+ end
46
+
47
+ # Aggregates added and changed files in one array
48
+ #
49
+ # @return [Array]
50
+
51
+ def changed_and_added_files
52
+ changed_files + added_files
53
+ rescue
54
+ []
55
+ end
56
+ =begin
57
+ private
58
+ def check_repo repository
59
+ @logs = @repository.log
60
+ @logs.first
61
+ rescue ::Git::GitExecuteError => e
62
+ puts "\nRepository is empty. There are no any revision.".color(:red)
63
+ raise e
64
+ exit 1
65
+ end
66
+ =end
67
+ end
68
+
69
+
70
+ class Svn
71
+ def initialize
72
+ raise "TDB"
73
+ end
74
+
75
+ def changed_files_list
76
+ raise "TDB"
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,3 @@
1
+ module Syntaxer
2
+ VERSION = "0.0.1" unless defined? Syntaxer::VERSION
3
+ end
data/lib/syntaxer.rb ADDED
@@ -0,0 +1,74 @@
1
+ require "rake"
2
+ require "open3"
3
+ require "forwardable"
4
+ require "git"
5
+ require File.join(%w{syntaxer reader})
6
+ require File.join(%w{syntaxer file_status})
7
+ require File.join(%w{syntaxer checker})
8
+ require File.join(%w{syntaxer repository})
9
+ require File.join(%w{syntaxer language_definition})
10
+ require File.join(%w{syntaxer version})
11
+ require File.join(%w{syntaxer printer})
12
+
13
+ module Syntaxer
14
+ DEFAULT_FILES_MASK = "**/*"
15
+ SYNTAXER_RULES_FILE = File.join(File.dirname(__FILE__), "..", "syntaxer_rules.dist.rb")
16
+
17
+ class << self
18
+ attr_reader :reader, :repository, :root_path, :result, :verbose
19
+
20
+ def configure
21
+ yield(self) if block_given?
22
+ end
23
+
24
+ # Main method to be used for syntax checking.
25
+ #
26
+ # @return [Boolean]
27
+ #
28
+ # @param [Hash] options the options to perform syntax checking
29
+ # @option options [String] :root_path (Dir.getwd) The starting point, which will be used for all relative path's
30
+ # @option options [String] :languages (:all) Type of languages to be used in checking
31
+ # @option options [String] :repository (git|svn) Type of repository
32
+ # @option options [String] :config_file(SYNTAXER_RULES_FILE) File with syntax rules and language definitions
33
+
34
+ def check_syntax(options = {})
35
+ @root_path = options[:root_path]
36
+ Printer.quite = options[:quite] || false
37
+ @reader = Reader::DSLReader.load(options[:config_file])
38
+ @repository = Repository.factory(@root_path, options[:repository]) if options[:repository]
39
+
40
+ Checker.process(self)
41
+ error_files = Checker.error_files
42
+ Printer.print_result error_files
43
+ exit(1) unless error_files.empty?
44
+ end
45
+
46
+ # This method generate and put hook to .git/hooks
47
+ #
48
+ # @return [Nil]
49
+ #
50
+ # @see Syntaxer#check_syntax
51
+ # @raise ArgumentError if no repository indicated
52
+ # @raise ArgumentError if SVN is indicated. SVN is not supported yet.
53
+
54
+ def make_hook(options)
55
+ @root_path = options[:root_path]
56
+ raise ArgumentError, 'Indicate repository type' unless options.include?(:repository)
57
+ raise ArgumentError, "SVN is temporarily not supported" if options[:repository].to_sym == :svn
58
+ repo = Repository.factory(@root_path, options[:repository])
59
+ hook_file = "#{@root_path}/.git/hooks/pre-commit"
60
+ File.open(hook_file, 'w') do |f|
61
+ f.puts "syntaxer -r git" # #{@root_path}"
62
+ end
63
+ File.chmod(0755, hook_file)
64
+ rescue Exception => e
65
+ puts e.message.color(:red)
66
+ raise e
67
+ end
68
+
69
+ end
70
+ end
71
+ #
72
+ # Syntaxer.configure do |config|
73
+ # config.root = File.expand_path(File.dirname(__FILE__) + '../..')
74
+ # end
File without changes
data/rails/init.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'syntaxer/railtie'
2
+
3
+ Syntaxer.configure do |syntaxer|
4
+ syntaxer.root = Rails.root
5
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Syntaxer::Checker" do
4
+
5
+ context "Syntaxer::PlainChecker" do
6
+
7
+ before(:each) do
8
+ reader = mock('Reader')
9
+ reader.stub!(:rules).and_return([Syntaxer::LanguageDefinition.new(:ruby, ["rb.example", "rake"], ["Rakefile", "Thorfile"], ["**/*"], nil, "ruby -wc %filename%")])
10
+ Syntaxer.should_receive(:reader).and_return(reader)
11
+ Syntaxer.stub!(:root_path).and_return(fixtures_path(:ruby))
12
+
13
+ Syntaxer::Printer.stub!(:print_result)
14
+ Syntaxer::Printer.stub!(:print_progress)
15
+ end
16
+
17
+ subject {Syntaxer::PlainChecker.new(Syntaxer)}
18
+
19
+ it {should respond_to(:error_files)}
20
+ it {should respond_to(:fine_files)}
21
+
22
+ it "should return correct error_files " do
23
+ subject.process
24
+ subject.fine_files.size.should == 1
25
+ subject.error_files.size.should == 1
26
+ end
27
+
28
+ it "should send to FileStatus" do
29
+ Syntaxer::FileStatus.should_receive(:build).twice
30
+ subject.process
31
+ end
32
+ end
33
+
34
+ # it "fails" do
35
+ # fail "hey buddy, you should probably rename this file and start specing for real"
36
+ # end
37
+
38
+ context "Syntaxer::RepoChecker" do
39
+
40
+ before(:all) do
41
+ Syntaxer::Printer.stub!(:print_result)
42
+ Syntaxer::Printer.stub!(:print_progress)
43
+ end
44
+
45
+ before(:each) do
46
+ @repo_dir = create_temp_ruby_project
47
+ make_initial_commit(@repo_dir)
48
+ add_file_to_repo(:ruby, @repo_dir, "correct.rb.example")
49
+ add_file_to_repo(:ruby, @repo_dir, "wrong.rb.example")
50
+ make_git_add(@repo_dir)
51
+
52
+ reader = mock('Reader')
53
+ reader.stub!(:rules).and_return([Syntaxer::LanguageDefinition.new(:ruby, ["rb.example", "rake"], ["Rakefile", "Thorfile"], ["**/*"], nil, "ruby -wc %filename%")])
54
+ Syntaxer.should_receive(:reader).and_return(reader)
55
+ Syntaxer.stub!(:root_path).and_return(@repo_dir)
56
+ repo = Syntaxer::Repository.factory(@repo_dir, :git)
57
+ Syntaxer.stub!(:repository).and_return(repo)
58
+ end
59
+
60
+ subject {Syntaxer::RepoChecker.new(Syntaxer)}
61
+
62
+ it "should return correct error_files" do
63
+ subject.process
64
+ subject.fine_files.size.should_not eql(0)
65
+ subject.error_files.size.should_not eql(0)
66
+ end
67
+
68
+ it "should send to FileStatus" do
69
+ Syntaxer::FileStatus.should_receive(:build).twice
70
+ subject.process
71
+ end
72
+
73
+ after(:each) do
74
+ FileUtils.rm_rf(@repo_dir)
75
+ end
76
+
77
+ end
78
+
79
+
80
+ end
@@ -0,0 +1,4 @@
1
+ - pretty_dialog :title => "Confirm Delete", :style => "display:none;", :id => "interview_confirm_delete_dialog" do |d|
2
+ %p.center Are you sure you want to delete this interview from your list?
3
+ = d.button :ok, :text => "Yes"
4
+ = d.button :cancel, :class => "cancel", :text => "No"
@@ -0,0 +1,4 @@
1
+ - pretty_dialog :title => "Confirm Delete", :style => "display:none;", :id => "interview_confirm_delete_dialog" do |d|
2
+ %p.center Are you sure you want to delete this interview from your list?
3
+ = d.button :ok, :text => "Yes"
4
+ = d.button :cancel, :class => "cancel", :text => "No"
@@ -0,0 +1,5 @@
1
+ class A
2
+ def some_method
3
+ puts "Do nothing"
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ cals A
2
+ end
@@ -0,0 +1,13 @@
1
+ syntaxer do
2
+
3
+ languages :ruby do
4
+ folders 'app/controllers/**/*'
5
+ end
6
+
7
+ languages :haml do
8
+ folders 'app/views/**/*'
9
+ end
10
+
11
+ #ignore_folders "app/models/**" # this folders will be deleted from all languages
12
+
13
+ end
@@ -0,0 +1,7 @@
1
+ syntaxer do
2
+
3
+ languages :ruby do
4
+ folders '**/*'
5
+ end
6
+
7
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "LanguageRules" do
4
+ before(:each) do
5
+ @rules = Syntaxer::LanguageRules.new
6
+ end
7
+
8
+ it "should raise exception if obj is not LanguageDefinition instance" do
9
+ lambda do
10
+ @rules << "a"
11
+ end.should raise_exception(Syntaxer::LanguageDefinitionException)
12
+ end
13
+
14
+ it "should not raise if LanguageDefinition object added" do
15
+ lambda do
16
+ @rules << Syntaxer::LanguageDefinition.new(:ruby)
17
+ end.should_not raise_exception(Syntaxer::LanguageDefinitionException)
18
+ end
19
+
20
+ context "LanguageDefinition" do
21
+ it "should not create w/o name" do
22
+ lambda do
23
+ Syntaxer::LanguageDefinition.new
24
+ end.should raise_exception(Syntaxer::LanguageDefinitionException)
25
+ end
26
+ end
27
+
28
+ context "LanguageDefinition" do
29
+ it "#file_list should return correct file list based on rules" do
30
+ correct_array = Rake::FileList.new(File.dirname(__FILE__) + '/fixtures/ruby/*')
31
+ ld = Syntaxer::LanguageDefinition.new(:ruby, ["rb.example", "rake"], ["Rakefile", "Thorfile"], ["**/*"], nil, "`ruby -wc %filename%`")
32
+ ld.files_list(File.dirname(__FILE__) + '/fixtures/').should == correct_array
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Syntaxer" do
4
+ context "::Printer" do
5
+
6
+ before(:each) do
7
+ end
8
+
9
+ subject{Syntaxer::Printer}
10
+
11
+ it "should be quite if passed --quite option" do
12
+ IO.should_not_receive(:print)
13
+ IO.should_not_receive(:puts)
14
+
15
+ subject.quite = true
16
+ subject.print_progress true
17
+ subject.print_result ['a','b']
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,119 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Syntaxer::Reader::DSLReader" do
4
+
5
+ context "#build" do
6
+ it "should build from default distr rules files" do
7
+ @reader = Syntaxer::Reader::DSLReader.build
8
+
9
+ @reader.rules.find(:ruby).should == Syntaxer::LanguageDefinition.new(:ruby, ["rb", "rake"], ["Rakefile", "Thorfile"], ["**/*"], nil, "ruby -wc %filename%")
10
+ @reader.rules.find(:haml).should == Syntaxer::LanguageDefinition.new(:haml, ["haml"], nil, ["**/*"], nil, "haml -c %filename%")
11
+ @reader.rules.find(:sass).should == Syntaxer::LanguageDefinition.new(:sass, ["sass"], nil, ["**/*"], nil, "sass -c %filename%")
12
+
13
+ end
14
+ end
15
+
16
+ context "#parse" do
17
+
18
+ it "should parse all languages" do
19
+ reader = Syntaxer::Reader::DSLReader.new
20
+
21
+ reader.parse %|
22
+ syntaxer do
23
+ languages :ruby do
24
+ folders 'app/**/*', 'lib/**/*'
25
+ end
26
+
27
+ languages :haml do
28
+ folders 'app/haml/**/*', 'lib/haml/**/*'
29
+ end
30
+ end
31
+ |
32
+
33
+ reader.rules.find(:ruby).folders.should == ['app/**/*', 'lib/**/*']
34
+ reader.rules.find(:haml).folders.should == ["app/haml/**/*", "lib/haml/**/*"]
35
+ end
36
+
37
+ it "should load from file" do
38
+ reader = Syntaxer::Reader::DSLReader.load(syntaxer_rules_example_file)
39
+ reader.rules.find(:ruby).folders.should == ["app/controllers/**/*"]
40
+ reader.rules.find(:haml).folders.should == ["app/views/**/*"]
41
+ end
42
+
43
+ it "should do substitution for the same rules" do
44
+ reader = Syntaxer::Reader::DSLReader.build
45
+ reader.rules.find(:ruby).folders.should == ["**/*"]
46
+
47
+ reader.parse %|
48
+ syntaxer do
49
+ languages :ruby do
50
+ folders 'app/**/*', 'lib/**/*'
51
+ end
52
+ end
53
+ |
54
+
55
+ reader.rules.find(:ruby).folders.should == ["app/**/*", "lib/**/*"]
56
+
57
+ end
58
+ end
59
+
60
+ context "raise exceptions" do
61
+ before(:each) do
62
+ @reader = Syntaxer::Reader::DSLReader.new
63
+ end
64
+
65
+ it "should raise exception if illegal formating of dsl file" do
66
+ lambda do
67
+ @reader.parse %|
68
+ syntaxer2 do
69
+ end
70
+ |
71
+ end.should raise_exception(Syntaxer::Reader::DSLSyntaxError)
72
+ end
73
+ end
74
+
75
+ context "#folders should change current_rule folders attr" do
76
+
77
+ before(:each) do
78
+ @reader = Syntaxer::Reader::DSLReader.new
79
+ @current_rule = Syntaxer::LanguageDefinition.new(:name => :ruby)
80
+ @reader.stub!(:current_rule).and_return(@current_rule)
81
+ end
82
+
83
+ it "should return DEFAULT_FILES_MASK if no params given" do
84
+ @reader.folders()
85
+ @current_rule.folders.should == [Syntaxer::DEFAULT_FILES_MASK]
86
+ end
87
+
88
+ it "should return params back" do
89
+ @reader.folders('app/**/*', 'app/lib/*')
90
+ @current_rule.folders.should == ['app/**/*', 'app/lib/*']
91
+ end
92
+
93
+ it "should change predefined folders" do
94
+ old_files = "app/libs/bla/*"
95
+ new_files = ['app/**/*', 'app/lib/*']
96
+ @current_rule.folders = old_files
97
+ @current_rule.folders.should == old_files
98
+
99
+ @reader.folders(new_files)
100
+ @current_rule.folders.should == new_files
101
+ end
102
+ end
103
+
104
+ context "#overall_ignore_folders" do
105
+
106
+ before(:each) do
107
+ @reader = Syntaxer::Reader::DSLReader.new
108
+ end
109
+
110
+ it "should return DEFAULT_FILES_MASK if no params given" do
111
+ @reader.overall_ignore_folders('app/**/*', 'app/lib/*').should == ['app/**/*', 'app/lib/*']
112
+ end
113
+
114
+ it "should return params back" do
115
+ @reader.overall_ignore_folders().should == []
116
+ end
117
+ end
118
+
119
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Syntaxer::Repository" do
4
+ context "Git" do
5
+ it "should not raise exception if there are no any revision" do
6
+ @repo_dir = create_temp_ruby_project
7
+ add_file_to_repo(:ruby, @repo_dir, 'wrong.rb.example')
8
+ lambda{Syntaxer::Git.new(@repo_dir)}.should_not raise_exception
9
+ FileUtils.rm_rf(@repo_dir)
10
+ end
11
+ end
12
+ end