soup 0.9.13 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -21,7 +21,7 @@ spec = Gem::Specification.new do |s|
21
21
 
22
22
  # Change these as appropriate
23
23
  s.name = "soup"
24
- s.version = "0.9.13"
24
+ s.version = "1.0.0"
25
25
  s.summary = "A super-simple data store"
26
26
  s.author = "James Adam"
27
27
  s.email = "james@lazyatom.com"
@@ -32,7 +32,7 @@ class Soup
32
32
 
33
33
  # Get the soup ready!
34
34
  def initialize(backend=nil)
35
- @backend = backend || Soup::Backends::YAMLBackend.new
35
+ @backend = backend || Soup::Backends::FileBackend.new
36
36
  @backend.prepare
37
37
  end
38
38
 
@@ -10,5 +10,6 @@ class Soup
10
10
  autoload :YAMLBackend, 'soup/backends/yaml_backend'
11
11
  autoload :MultiSoup, 'soup/backends/multi_soup'
12
12
  autoload :ReadOnly, 'soup/backends/read_only'
13
+ autoload :FileBackend, 'soup/backends/file_backend'
13
14
  end
14
15
  end
@@ -0,0 +1,66 @@
1
+ class Soup
2
+ module Backends
3
+ class FileBackend < Base
4
+ def initialize(path="soup")
5
+ @base_path = path
6
+ end
7
+
8
+ def prepare
9
+ FileUtils.mkdir_p(@base_path)
10
+ end
11
+
12
+ def names
13
+ Dir[path_for("*")].map { |s| File.basename(s, ".snip") }
14
+ end
15
+
16
+ def load_snip(name)
17
+ path = path_for(name)
18
+ if File.exist?(path)
19
+ file = File.new(path)
20
+ data = file.read
21
+ default_attributes = {:name => name, :updated_at => file.mtime}
22
+ if attribute_start = data.index("\n:")
23
+ content = data[0, attribute_start].strip
24
+ attributes = default_attributes.merge(YAML.load(data[attribute_start, data.length]).merge(:content => content))
25
+ else
26
+ attributes = default_attributes.merge(:content => data)
27
+ end
28
+ Snip.new(attributes, self)
29
+ else
30
+ nil
31
+ end
32
+ end
33
+
34
+ def save_snip(attributes)
35
+ File.open(path_for(attributes[:name]), 'w') do |f|
36
+ attributes_without_content = attributes.dup
37
+ f.write attributes_without_content.delete(:content)
38
+ f.write attributes_without_content.to_yaml.gsub(/^---\s/, "\n") if attributes_without_content.any?
39
+ end
40
+ Snip.new(attributes, self)
41
+ end
42
+
43
+ def destroy(name)
44
+ path = path_for(name)
45
+ if File.exist?(path)
46
+ File.delete(path)
47
+ true
48
+ else
49
+ nil
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def path_for(name)
56
+ File.join(@base_path, name + ".snip")
57
+ end
58
+
59
+ def all_snips
60
+ Dir[path_for("*")].map do |key|
61
+ load_snip(File.basename(key, ".snip"))
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,59 @@
1
+ require "test_helper"
2
+ require "ftools"
3
+
4
+ class FileBackendTest < Test::Unit::TestCase
5
+ context "The file-based backend" do
6
+ setup do
7
+ @base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
8
+ @soup = Soup.new(Soup::Backends::FileBackend.new(@base_path))
9
+ end
10
+
11
+ should "parse attributes from lines starting with colon" do
12
+ write_snip "snip", %{
13
+ Here is the content
14
+ of the snip
15
+
16
+ :name: thing
17
+ :render_as: Markdown
18
+ :multi_line_attribute: |
19
+ stuff
20
+ things
21
+ :blah: yes
22
+ }
23
+
24
+ snip = @soup["snip"]
25
+ assert_equal "Here is the content\nof the snip", snip.content
26
+ assert_equal "thing", snip.name
27
+ end
28
+
29
+ should "write a snip in the simple format" do
30
+ @soup << {:content => "Here is the content", :name => "dave"}
31
+
32
+ assert_equal %{Here is the content\n\n:name: dave\n}, File.read(path_for("dave"))
33
+ end
34
+
35
+ should "take name from filename if not supplied" do
36
+ write_snip "blahface", "The snip content"
37
+ assert_equal "blahface", @soup["blahface"].name
38
+ end
39
+
40
+ should "take updated_at from file timestamps if not supplied" do
41
+ write_snip "snip", "whatever"
42
+ updated = Time.parse("2010-11-04 14:56")
43
+ File.utime(updated, updated, path_for("snip"))
44
+
45
+ snip = @soup["snip"]
46
+ assert_equal updated, snip.updated_at
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def path_for(name)
53
+ File.join(@base_path, name + ".snip")
54
+ end
55
+
56
+ def write_snip(name, content)
57
+ File.open(path_for(name), "w") { |f| f.write content.strip }
58
+ end
59
+ end
@@ -5,7 +5,7 @@ class MultiSoupBackendTest < Test::Unit::TestCase
5
5
  setup do
6
6
  @base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
7
7
  @basic_soup_backend_one = Soup::Backends::YAMLBackend.new(File.join(@base_path, "soup_one"))
8
- @basic_soup_backend_two = Soup::Backends::YAMLBackend.new(File.join(@base_path, "soup_two"))
8
+ @basic_soup_backend_two = Soup::Backends::FileBackend.new(File.join(@base_path, "soup_two"))
9
9
  @soup_one = Soup.new(@basic_soup_backend_one)
10
10
  @soup_two = Soup.new(@basic_soup_backend_two)
11
11
  multi_soup_backend = Soup::Backends::MultiSoup.new(@basic_soup_backend_one, @basic_soup_backend_two)
@@ -6,6 +6,7 @@ class SoupTest < Test::Unit::TestCase
6
6
  base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
7
7
  backends = [
8
8
  yaml_backend = Soup::Backends::YAMLBackend.new(base_path),
9
+ file_backend = Soup::Backends::FileBackend.new(base_path),
9
10
  Soup::Backends::MultiSoup.new(yaml_backend)
10
11
  ]
11
12
  backends.each do |backend|
metadata CHANGED
@@ -3,10 +3,10 @@ name: soup
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
- - 9
8
- - 13
9
- version: 0.9.13
8
+ - 0
9
+ version: 1.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - James Adam
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-14 00:00:00 +01:00
17
+ date: 2010-08-08 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -41,10 +41,12 @@ files:
41
41
  - Manifest
42
42
  - Rakefile
43
43
  - README
44
+ - test/file_backend_test.rb
44
45
  - test/multi_soup_backend_test.rb
45
46
  - test/soup_test.rb
46
47
  - test/test_helper.rb
47
48
  - lib/soup/backends/base.rb
49
+ - lib/soup/backends/file_backend.rb
48
50
  - lib/soup/backends/multi_soup.rb
49
51
  - lib/soup/backends/read_only.rb
50
52
  - lib/soup/backends/yaml_backend.rb