Pickaxe 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,3 +4,12 @@ Pickaxe provides a simple way to load, solve and rate tests
4
4
  (bundle of questions) written in simple text format.
5
5
 
6
6
  Documentation can be read [here](http://dejw.github.com/pickaxe/).
7
+
8
+ **Note:** pickaxe was not tested on Windows yet (and it will not work there
9
+ since `Pickaxe::Shell` executes some terminal related code).
10
+
11
+ ## instalation
12
+
13
+ sudo gem install Pickaxe
14
+
15
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
3
+ require 'pickaxe'
4
+ require "pickaxe/cli"
@@ -1,64 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require 'optparse'
4
-
5
2
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
6
-
7
3
  require 'pickaxe'
8
-
9
- # TODO:
10
- # time limit
11
- # syntax check only
12
- # default -> warns + ignore, options for exception on syntax error ;-)
13
-
14
- options = {}
15
- OptionParser.new do |opts|
16
- opts.banner = <<END_OF_BANNER
17
- Usage:
18
- pickaxe path [, path ...]
19
-
20
- Uses given paths (files or directories) to generate a test from *.txt files.
21
- END_OF_BANNER
22
-
23
- opts.separator ""
24
- opts.on("-e", "--ext [EXTENSION]", "Use files with given EXTENSION (default 'txt')") do |extension|
25
- options[:extension] = extension
26
- end
27
-
28
- opts.on("-s", "--sorted", "Do not shuffle questions") do |v|
29
- options[:sorted] = true
30
- end
31
-
32
- opts.on("--select [NUMBER]", "Select certain number of questions") do |v|
33
- options[:select] = Integer(v)
34
- end
35
-
36
- opts.on("--full-test", "Checks test after all questions are answered") do |v|
37
- options[:full_test] = true
38
- end
39
-
40
- opts.on("--strict", "Quit on syntax error in test file") do |v|
41
- options[:strict] = true
42
- end
43
-
44
- opts.on_tail("--syntax-check", "Check syntax only - do not run test") do
45
- options[:syntax_check] = true
46
- end
47
-
48
- opts.on_tail("--version", "Show version") do
49
- puts "pickaxe version #{Pickaxe::VERSION}"
50
- exit
51
- end
52
-
53
- opts.on_tail("-h", "--help", "Show this message") do
54
- puts opts
55
- exit
56
- end
57
- end.parse!
58
-
59
- begin
60
- Pickaxe::Main.new(ARGV, options)
61
- rescue Pickaxe::PickaxeError => e
62
- $stderr.puts(("! " + e.message).color(:red))
63
- exit(e.status_code)
64
- end
4
+ require "pickaxe/cli"
@@ -5,7 +5,7 @@ require "active_support/all"
5
5
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
6
6
 
7
7
  module Pickaxe
8
- VERSION = "0.4.1"
8
+ VERSION = "0.4.2"
9
9
 
10
10
  class PickaxeError < StandardError
11
11
  attr_reader :status_code
@@ -0,0 +1,53 @@
1
+ require 'optparse'
2
+
3
+ options = {}
4
+ OptionParser.new do |opts|
5
+ opts.banner = <<END_OF_BANNER
6
+ Usage:
7
+ #{$0.split("/").last} path [, path ...]
8
+
9
+ Uses given paths (files or directories) to generate a test from *.txt files.
10
+ END_OF_BANNER
11
+
12
+ opts.separator ""
13
+ opts.on("-e", "--ext [EXTENSION]", "Use files with given EXTENSION (default 'txt')") do |extension|
14
+ options[:extension] = extension
15
+ end
16
+
17
+ opts.on("-s", "--sorted", "Do not shuffle questions") do |v|
18
+ options[:sorted] = true
19
+ end
20
+
21
+ opts.on("--select [NUMBER]", "Select certain number of questions") do |v|
22
+ options[:select] = Integer(v)
23
+ end
24
+
25
+ opts.on("--full-test", "Checks test after all questions are answered") do |v|
26
+ options[:full_test] = true
27
+ end
28
+
29
+ opts.on("--strict", "Quit on syntax error in test file") do |v|
30
+ options[:strict] = true
31
+ end
32
+
33
+ opts.on_tail("--syntax-check", "Check syntax only - do not run test") do
34
+ options[:syntax_check] = true
35
+ end
36
+
37
+ opts.on_tail("--version", "Show version") do
38
+ puts "pickaxe version #{Pickaxe::VERSION}"
39
+ exit
40
+ end
41
+
42
+ opts.on_tail("-h", "--help", "Show this message") do
43
+ puts opts
44
+ exit
45
+ end
46
+ end.parse!
47
+
48
+ begin
49
+ Pickaxe::Main.new(ARGV, options)
50
+ rescue Pickaxe::PickaxeError => e
51
+ $stderr.puts(("! " + e.message).color(:red))
52
+ exit(e.status_code)
53
+ end
@@ -18,6 +18,11 @@ END_OF_TEST
18
18
  @test = Test.new(*paths)
19
19
  return if options[:syntax_check]
20
20
 
21
+ puts "! Hit Control-D to end test.\n\n"
22
+
23
+ @logger = Logger.new(File.open('answers.log', File::WRONLY|File::TRUNC|File::CREAT))
24
+ @logger.formatter = lambda { |severity, time, progname, msg| msg.to_s + "\n" }
25
+
21
26
  @questions = @test.shuffled_questions
22
27
  @answers = Hash.new([])
23
28
  @started_at = Time.now
@@ -74,7 +79,7 @@ END_OF_TEST
74
79
  if Main.options[:full_test] and @question.nil?
75
80
  Main.options[:full_test] = false
76
81
  Main.options[:force_show_answers] = true
77
-
82
+
78
83
  @current_index = 0
79
84
  else
80
85
  @current_index += 1
@@ -93,7 +98,7 @@ Available commands (whitespace does not matter):
93
98
  END_OF_HELP
94
99
  false
95
100
  else
96
- @answers[@question] = line.split(/\s+/).collect(&:strip)
101
+ @answers[@question] = line.strip.split(/\s+/).collect(&:strip)
97
102
  puts @question.check?(@answers[@question]) unless Main.options[:full_test]
98
103
  @current_index += 1
99
104
  true
@@ -102,7 +107,11 @@ END_OF_HELP
102
107
 
103
108
  def statistics!
104
109
  @stats = @test.statistics!(@answers)
105
-
110
+
111
+ @answers.each do |question, answers|
112
+ @logger << ("#{question.index}: #{answers.join(" ")}\n")
113
+ end
114
+
106
115
  puts
107
116
  puts "Time: #{spent?}"
108
117
  puts "All: #{@questions.length}"
@@ -5,6 +5,7 @@ module Pickaxe
5
5
  class TestSyntaxError < PickaxeError; status_code(2) ; end
6
6
  class MissingAnswers < TestSyntaxError; status_code(2) ; end
7
7
  class BadAnswer < TestSyntaxError; status_code(3) ; end
8
+ class BadQuestion < TestSyntaxError; status_code(4) ; end
8
9
  class NoCorrectAnswer < TestSyntaxError; status_code(3) ; end
9
10
 
10
11
  class TestLine < String
@@ -34,7 +35,7 @@ module Pickaxe
34
35
  include Enumerable
35
36
 
36
37
  # Ruby-comments and C-comments
37
- COMMENTS_RE = /^#.*|^\/\/.*/
38
+ COMMENTS_RE = /^\s*#.*|^\/\/.*/
38
39
 
39
40
  def initialize(*files)
40
41
  @files = files.collect do |file_or_directory|
@@ -44,7 +45,7 @@ module Pickaxe
44
45
  else
45
46
  Dir.glob("#{file_or_directory}/*.#{Main.options[:extension] || "txt"}")
46
47
  end
47
- end.flatten.collect(&:squeeze)
48
+ end.flatten.collect { |f| f.squeeze('/') }
48
49
 
49
50
  @questions = []
50
51
  @files.each do |file|
@@ -108,7 +109,9 @@ module Pickaxe
108
109
  end
109
110
  end
110
111
 
111
- class Question < Struct.new(:file, :content, :answers)
112
+ class Question < Struct.new(:file, :index, :content, :answers)
113
+ RE = /^\s*(\d+)\.?\s*(.+)$/
114
+
112
115
  def self.parse(file, answers)
113
116
  content = []
114
117
  until answers.first.nil? or Answer::RE.match(answers.first)
@@ -116,10 +119,22 @@ module Pickaxe
116
119
  end
117
120
 
118
121
  raise MissingAnswers, "#{file}: line #{answers.first.index}: no content (check blank lines nearby)" if content.blank?
119
-
122
+ raise BadQuestion, "#{file}: line #{content.first.index}: '#{content.first.truncate(20)}' does not look like question" unless m = RE.match(content.first)
123
+
120
124
  error_template = "#{file}: line #{content.first.index}: question '#{content.first.truncate(20)}' %s"
121
125
  raise MissingAnswers, (error_template % "has no answers") if answers.blank?
122
- Question.new(file, content, answers.collect {|answer| Answer.parse(file, answer) }).tap do |q|
126
+
127
+ answers = answers.inject([]) do |joined, line|
128
+ if Answer::RE.match(line)
129
+ joined << [line]
130
+ else
131
+ raise BadAnswer, "#{file}: line #{line.index}: '#{line.truncate(20)}' starts with weird characters" unless Answer::LINE_RE.match(line)
132
+ joined.last << line
133
+ end
134
+ joined
135
+ end
136
+
137
+ Question.new(file, m[1], content, answers.collect {|answer| Answer.parse(file, answer) }).tap do |q|
123
138
  raise NoCorrectAnswer, (error_template % "has no correct answer") if q.correct_answers.blank?
124
139
  end
125
140
  end
@@ -160,10 +175,12 @@ module Pickaxe
160
175
  end
161
176
 
162
177
  class Answer < Struct.new(:content, :index, :correctness)
163
- RE = /^\s*(>>)?(\?\?)?\s*\((\w+)\)\s*(.+)$/
164
- def self.parse(file, line)
165
- raise BadAnswer, "#{file}: line #{line.index}: '#{line.truncate(20)}' does not look like answer" if (m = RE.match(line)).nil?
166
- Answer.new(m[m.size-1].strip, m[m.size-2].strip, m[1] == ">>")
178
+ RE = /^\s*(>>)?\s*(\?\?)?\s*\((\w+)\)\s*(.+)$/
179
+ LINE_RE = /^\s*(\w+)/
180
+
181
+ def self.parse(file, lines)
182
+ m = RE.match(lines.shift)
183
+ Answer.new(m[m.size-1].strip + " " + lines.collect(&:strip).join(" "), m[m.size-2].strip, m[1] == ">>")
167
184
  end
168
185
 
169
186
  def to_s
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Pickaxe
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 1
10
- version: 0.4.1
9
+ - 2
10
+ version: 0.4.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dawid Fatyga
@@ -15,8 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-28 00:00:00 +01:00
19
- default_executable:
18
+ date: 2010-12-01 00:00:00 +01:00
19
+ default_executable: bin/pickaxe
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -73,6 +73,7 @@ description: |
73
73
  email: dawid.fatyga@gmail.com
74
74
  executables:
75
75
  - pickaxe
76
+ - drill
76
77
  extensions: []
77
78
 
78
79
  extra_rdoc_files:
@@ -82,10 +83,12 @@ extra_rdoc_files:
82
83
  files:
83
84
  - lib/pickaxe.rb
84
85
  - lib/pickaxe/test.rb
86
+ - lib/pickaxe/cli.rb
85
87
  - lib/pickaxe/color.rb
86
88
  - lib/pickaxe/extensions.rb
87
89
  - lib/pickaxe/shell.rb
88
90
  - lib/pickaxe/main.rb
91
+ - bin/drill
89
92
  - bin/pickaxe
90
93
  - README.markdown
91
94
  - Gemfile