hx 0.8.2 → 0.8.3

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.2
1
+ 0.8.3
data/lib/hx/cli.rb CHANGED
@@ -42,6 +42,7 @@ Usage: hx [--config CONFIG_FILE] [upgen]
42
42
  hx [--config CONFIG_FILE] regen
43
43
  hx [--config CONFIG_FILE] post[up] SOURCE:PATH
44
44
  hx [--config CONFIG_FILE] edit[up] SOURCE:PATH
45
+ hx [--config CONFIG_FILE] list SOURCE:PATTERN
45
46
 
46
47
  EOS
47
48
 
@@ -128,31 +129,47 @@ def self.cmd_postup(site, entry_spec)
128
129
  cmd_upgen(site)
129
130
  end
130
131
 
131
- def self.parse_entry_spec(entry_spec)
132
+ def self._parse_entry_spec(site, entry_spec)
132
133
  source_name, path = entry_spec.split(':', 2)
134
+ source = site.sources[source_name]
135
+ raise ArgumentError, "No such source #{source_name}" unless source
136
+ return source, path
137
+ end
138
+
139
+ def self.parse_entry_spec(site, entry_spec)
140
+ source, path = _parse_entry_spec(site, entry_spec)
133
141
  raise "Invalid entry specification #{entry_spec}" unless path
134
- return source_name, path
142
+ return source, path
143
+ end
144
+
145
+ def self.parse_entry_pattern(site, entry_pattern)
146
+ source, pattern = _parse_entry_spec(site, entry_pattern)
147
+ pattern = "**" unless pattern
148
+ selector = Hx::Path.parse_pattern(pattern)
149
+ return source, selector
135
150
  end
136
151
 
137
152
  def self.cmd_edit(site, entry_spec)
138
- source_name, path = parse_entry_spec(entry_spec)
139
- do_edit(site, source_name, path, nil)
153
+ source, path = parse_entry_spec(site, entry_spec)
154
+ do_edit(site, source, path, nil)
140
155
  end
141
156
 
142
157
  def self.cmd_post(site, entry_spec)
143
- source_name, path = parse_entry_spec(entry_spec)
158
+ source, path = parse_entry_spec(site, entry_spec)
144
159
  prototype = {
145
160
  'title' => Hx.make_default_title(site.options, path),
146
161
  'author' => Hx.get_default_author(site.options),
147
162
  'content' => ""
148
163
  }
149
- do_edit(site, source_name, path, prototype)
164
+ do_edit(site, source, path, prototype)
150
165
  end
151
166
 
152
- def self.do_edit(site, source_name, path, prototype)
153
- source = site.sources[source_name]
154
- raise ArgumentError, "No such source #{source_name}" unless source
167
+ def self.cmd_list(site, entry_spec)
168
+ source, selector = parse_entry_pattern(site, entry_spec)
169
+ source.each_entry_path(selector) { |path| puts path }
170
+ end
155
171
 
172
+ def self.do_edit(site, source, path, prototype)
156
173
  catch(:unchanged) do
157
174
  begin
158
175
  tempfile = Tempfile.new('hx-entry')
@@ -74,7 +74,7 @@ class LiquidTemplate
74
74
  template_file = template_dir + "#{options[:template]}.liquid"
75
75
  @template = Liquid::Template.parse(template_file.read)
76
76
  @extension = options[:extension]
77
- @mime_type = options[:mime_type]
77
+ @content_type = options[:content_type]
78
78
  @strip_extension_re = nil
79
79
  @strip_extension_re = /\.#{Regexp.quote(@extension)}$/ if @extension
80
80
  end
@@ -99,7 +99,7 @@ class LiquidTemplate
99
99
  'entry' => entry
100
100
  )
101
101
  end
102
- output_entry['mime_type'] = @mime_type if @mime_type
102
+ output_entry['content_type'] = @content_type if @content_type
103
103
  if entry.has_key? 'updated'
104
104
  output_entry['created'] = output_entry['updated'] = entry['updated']
105
105
  end
data/lib/hx/path.rb CHANGED
@@ -25,11 +25,6 @@ module Hx
25
25
  module Path
26
26
 
27
27
  module Selector
28
- def prefix ; "" ; end
29
- def suffix ; "" ; end
30
- def regexp ; nil ; end
31
- def remaining_suffix(prefix_consumed) ; suffix ; end
32
-
33
28
  def accept?(path)
34
29
  raise NotImplementedError, "#{self.class}#accept? not implemented"
35
30
  end
@@ -49,37 +44,25 @@ end
49
44
 
50
45
  class All
51
46
  include Selector
52
-
53
- REGEXP = Regexp.new("^.*$")
54
-
55
- def regexp ; REGEXP ; end
56
47
  def accept?(path) ; true ; end
57
48
  end
58
49
 
59
50
  ALL = All.new
60
51
 
61
- class Literal
52
+ class Pattern
62
53
  include Selector
63
54
 
64
- attr_reader :value
65
- alias prefix value
66
-
67
- def initialize(value)
68
- @value = value
69
- @regexp = nil
70
- end
71
-
72
- def remaining_suffix(prefix_consumed)
73
- @value[prefix_consumed..-1]
74
- end
75
-
76
- def regexp
77
- @regexp ||= Regexp.new("^#{Regexp.quote(@value)}$")
55
+ def initialize(tokens)
56
+ @regexp = Regexp.new("^#{tokens.map { |token|
57
+ case token
58
+ when :doublestar; '.*'
59
+ when :star; '[^/]*'
60
+ else; Regexp.quote(token)
61
+ end
62
+ }}$")
78
63
  end
79
64
 
80
- def accept?(path)
81
- @value == path
82
- end
65
+ def accept?(path) ; !!(path =~ @regexp) ; end
83
66
  end
84
67
 
85
68
  def self.parse_pattern(pattern_string)
@@ -91,78 +74,35 @@ def self.parse_pattern(pattern_string)
91
74
  else; token
92
75
  end
93
76
  end
94
- prefix = tokens.first
95
- if tokens.size == 1 and String === prefix
96
- Literal.new(prefix)
97
- else
98
- prefix = "" unless String === prefix
99
- suffix = tokens.last
100
- suffix = "" unless String === suffix
101
- regexp = Regexp.new("^#{tokens.map { |token|
102
- case token
103
- when :doublestar; '.*'
104
- when :star; '[^/]*'
105
- else; Regexp.quote(token)
106
- end
107
- }}$")
108
- Pattern.new(regexp, prefix, suffix)
109
- end
77
+ Pattern.new(tokens)
110
78
  end
111
79
 
112
80
  def self.literal(literal_string)
113
- Literal.new(literal_string)
114
- end
115
-
116
- class Pattern
117
- include Selector
118
-
119
- attr_reader :prefix
120
- attr_reader :suffix
121
- attr_reader :regexp
122
-
123
- def initialize(regexp, prefix, suffix)
124
- @regexp = regexp
125
- @prefix = prefix
126
- @suffix = suffix
127
- end
128
-
129
- def accept?(path)
130
- !!(@regexp.match(path))
131
- end
81
+ Pattern.new([literal_string])
132
82
  end
133
83
 
134
84
  module Connective
135
85
  include Selector
136
86
 
137
- attr_reader :prefix
138
- attr_reader :suffix
139
-
140
87
  def initialize(*selectors)
141
88
  @selectors = selectors
142
- prefixes = selectors.map { |s| s.prefix }
143
- prefix_length = (prefixes.first || "").length
144
- prefixes.each_cons(2) do |a, b|
145
- prefix_length.downto(0) do |length|
146
- prefix_length = length
147
- break if a[0...length] == b[0...length]
148
- end
149
- end
150
- @prefix = prefixes.first[0...prefix_length]
151
- suffixes = selectors.map { |s| s.remaining_suffix(prefix_length) }
152
- suffix_length = (suffixes.first || "").length
153
- suffixes.each_cons(2) do |a, b|
154
- suffix_length.downto(0) do |length|
155
- suffix_length = length
156
- break if a[-length..-1] == b[-length..-1]
157
- end
158
- end
159
- @suffix = suffixes.first[-suffix_length..-1]
160
89
  end
161
90
  end
162
91
 
163
92
  class Conjunction
164
93
  include Connective
165
94
 
95
+ def self.new(*selectors)
96
+ if selectors.any? { |s| All === s }
97
+ selectors.reject! { |s| All === s }
98
+ case selectors.size
99
+ when 0; return ALL
100
+ when 1; return selectors.first
101
+ end
102
+ end
103
+ super(*selectors)
104
+ end
105
+
166
106
  def accept?(path)
167
107
  @selectors.all? { |s| s.accept? path }
168
108
  end
@@ -171,24 +111,8 @@ end
171
111
  class Disjunction
172
112
  include Connective
173
113
 
174
- attr_reader :regexp
175
-
176
- def initialize(*selectors)
177
- super
178
- regexps = @selectors.map { |s| s.regexp }
179
- if regexps.all?
180
- @regexp = Regexp.union(*regexps)
181
- else
182
- @regexp = nil
183
- end
184
- end
185
-
186
114
  def accept?(path)
187
- if @regexp
188
- !!@regexp.match(path)
189
- else
190
- @selectors.any? { |s| s.accept? path }
191
- end
115
+ @selectors.any? { |s| s.accept? path }
192
116
  end
193
117
  end
194
118
 
@@ -78,13 +78,13 @@ class Application
78
78
  end
79
79
 
80
80
  if entry
81
- mime_type = entry['mime_type']
82
- unless mime_type
81
+ content_type = entry['content_type']
82
+ unless content_type
83
83
  effective_path =~ /(\.[^.]+)$/
84
- mime_type = ::Rack::Mime.mime_type($1 || '')
84
+ content_type = ::Rack::Mime.mime_type($1 || '')
85
85
  end
86
86
  content = entry['content'].to_s
87
- [200, {'Content-Type' => mime_type}, [content]]
87
+ [200, {'Content-Type' => content_type}, [content]]
88
88
  else
89
89
  message = "#{env['SCRIPT_NAME']}#{path} not found"
90
90
  [404, {'Content-Type' => "text/plain"}, [message]]
data/spec/rack_spec.rb CHANGED
@@ -30,22 +30,22 @@ describe Hx::Rack::Application do
30
30
  it "should infer content type from file extension by default" do
31
31
  cases = { "html" => "text/html",
32
32
  "jpeg" => "image/jpeg" }
33
- for extension, mime_type in cases
33
+ for extension, content_type in cases
34
34
  path = "blah.#{extension}"
35
35
  @input.add_entry(path, "")
36
36
  response = @service.get("/#{path}", :lint => true, :fatal => true)
37
37
  response.status.to_i.should == 200
38
- response['Content-Type'].should == mime_type
38
+ response['Content-Type'].should == content_type
39
39
  end
40
40
  end
41
41
 
42
42
  it "should allow entries to specify their mime type" do
43
43
  path = "blah.html"
44
- mime_type = "junk/garbage"
45
- @input.add_entry(path, "", 'mime_type' => mime_type)
44
+ content_type = "junk/garbage"
45
+ @input.add_entry(path, "", 'content_type' => content_type)
46
46
  response = @service.get("/#{path}", :lint => true, :fatal => true)
47
47
  response.status.to_i.should == 200
48
- response['Content-Type'].should == mime_type
48
+ response['Content-Type'].should == content_type
49
49
  end
50
50
 
51
51
  it "should redirect for directories with indices" do
@@ -7,72 +7,27 @@ describe Hx::Path::Pattern do
7
7
  Hx::Path::Pattern.should < Hx::Path::Selector
8
8
  end
9
9
 
10
- it "should parse pattern strings" do
11
- cases = [ { :pattern => "foo/**/bar",
12
- :prefix => "foo/",
13
- :suffix => "/bar" },
14
- { :pattern => "foo/*/bar",
15
- :prefix => "foo/",
16
- :suffix => "/bar" },
17
- { :pattern => "[blah",
18
- :prefix => "[blah",
19
- :suffix => "" },
20
- { :pattern => "hoge*",
21
- :prefix => "hoge",
22
- :suffix => "" },
23
- { :pattern => "*hoge",
24
- :prefix => "",
25
- :suffix => "hoge" } ]
26
- for test_case in cases
27
- pattern = Hx::Path.parse_pattern(test_case[:pattern])
28
- pattern.prefix.should == test_case[:prefix]
29
- pattern.suffix.should == test_case[:suffix]
30
- end
31
- end
32
-
33
- it "should accept or reject paths" do
34
- pattern = Hx::Path.parse_pattern("foo/bar")
10
+ it "should accept or reject literal paths" do
11
+ pattern = Hx::Path.literal("foo/bar")
35
12
  pattern.should accept("foo/bar")
36
13
  pattern.should_not accept("foo/baz")
37
14
  end
38
15
 
39
- it "should provide an equivalent regexp" do
40
- pattern = Hx::Path.parse_pattern("foo/bar")
41
- pattern.regexp.should_not be_nil
42
- pattern.regexp.match("foo/bar").should_not be_nil
43
- pattern.regexp.match("foo/bar/baz").should be_nil
16
+ it "should match single path components with stars" do
17
+ pattern = Hx::Path.parse_pattern("foo/*")
18
+ pattern.should_not accept("baz/eek")
19
+ pattern.should accept("foo/bar")
20
+ pattern.should_not accept("foo/bar/baz")
21
+ end
44
22
 
45
- pattern = Hx::Path.parse_pattern("foo/*/baz")
46
- pattern.regexp.should_not be_nil
47
- pattern.regexp.match("foo/baz").should be_nil
48
- pattern.regexp.match("foo/bar/baz").should_not be_nil
23
+ it "should match multiple path components with double stars" do
24
+ pattern = Hx::Path.parse_pattern("foo/**")
25
+ pattern.should_not accept("baz/eek")
26
+ pattern.should accept("foo/bar")
27
+ pattern.should accept("foo/bar/baz")
49
28
  end
50
29
  end
51
30
 
52
- PATHFILTER_PREFIX_CASES = [
53
- { :patterns => ["foo/bar", "fudge/bear"],
54
- :prefix => "f",
55
- :suffix => "ar" },
56
- { :patterns => ["foo/*/bar", "fudge/*/bear"],
57
- :prefix => "f",
58
- :suffix => "ar" },
59
- { :patterns => ["foo/bar", "fudge/*/bear"],
60
- :prefix => "f",
61
- :suffix => "ar" },
62
- { :patterns => ["bar*", "*bear"],
63
- :prefix => "",
64
- :suffix => "" },
65
- { :patterns => ["foobarbaz", "foobar*barbaz"],
66
- :prefix => "foobar",
67
- :suffix => "baz" },
68
- { :patterns => ["foobarbaz*", "foobar*barbaz"],
69
- :prefix => "foobar",
70
- :suffix => "" },
71
- { :patterns => ["*foobarbaz", "foobar*barbaz"],
72
- :prefix => "",
73
- :suffix => "barbaz" }
74
- ]
75
-
76
31
  describe "Hx::Path::Selector disjunctions" do
77
32
  it "should be possible" do
78
33
  filters = ["foo/bar", "abcdefg"].map { |p| Hx::Path.parse_pattern(p) }
@@ -87,17 +42,6 @@ describe "Hx::Path::Selector disjunctions" do
87
42
  filter.should accept("abcdefg")
88
43
  filter.should_not accept("hoge")
89
44
  end
90
-
91
- for test_case_outer in PATHFILTER_PREFIX_CASES
92
- Proc.new do |test_case|
93
- it "should produce optimal prefixes and suffixes" do
94
- filters = test_case[:patterns].map { |p| Hx::Path.parse_pattern(p) }
95
- filter = filters.inject { |a, b| a | b }
96
- filter.prefix.should == test_case[:prefix]
97
- filter.suffix.should == test_case[:suffix]
98
- end
99
- end.call(test_case_outer)
100
- end
101
45
  end
102
46
 
103
47
  describe "negated Hx::Path::Selectors" do
@@ -113,11 +57,6 @@ describe "negated Hx::Path::Selectors" do
113
57
  @pattern.should_not accept("foobar")
114
58
  @pattern.should accept("hoge")
115
59
  end
116
-
117
- it "should have empty prefix and suffix" do
118
- @pattern.prefix.should == ""
119
- @pattern.suffix.should == ""
120
- end
121
60
  end
122
61
 
123
62
  describe "Hx::Path::Selector conjunctions" do
@@ -137,14 +76,10 @@ describe "Hx::Path::Selector conjunctions" do
137
76
  filter.should_not accept("rebar")
138
77
  end
139
78
 
140
- for test_case_outer in PATHFILTER_PREFIX_CASES
141
- Proc.new do |test_case|
142
- it "should produce optimal prefixes and suffixes" do
143
- filters = test_case[:patterns].map { |p| Hx::Path.parse_pattern(p) }
144
- filter = filters.inject { |a, b| a & b }
145
- filter.prefix.should == test_case[:prefix]
146
- filter.suffix.should == test_case[:suffix]
147
- end
148
- end.call(test_case_outer)
79
+ it "should optimize use of ALL" do
80
+ filter = Hx::Path.parse_pattern("foo")
81
+ (filter & Hx::Path::ALL).should equal(filter)
82
+ (Hx::Path::ALL & filter).should equal(filter)
83
+ (Hx::Path::ALL & Hx::Path::ALL).should equal(Hx::Path::ALL)
149
84
  end
150
85
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - MenTaLguY
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-04-25 00:00:00 -04:00
12
+ date: 2010-05-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency