machine_tag 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +89 -0
- data/Rakefile +8 -0
- data/lib/machine_tag.rb +26 -0
- data/lib/machine_tag/set.rb +113 -0
- data/lib/machine_tag/tag.rb +112 -0
- data/lib/machine_tag/version.rb +30 -0
- data/machine_tag.gemspec +27 -0
- data/spec/machine_tag_set_spec.rb +71 -0
- data/spec/machine_tag_spec.rb +7 -0
- data/spec/machine_tag_tag_spec.rb +57 -0
- data/spec/spec_helper.rb +2 -0
- metadata +163 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Douglas Thrift
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# MachineTag
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/machine_tag.png)](http://badge.fury.io/rb/machine_tag)
|
4
|
+
[![Build Status](https://travis-ci.org/douglaswth/machine_tag.png?branch=master)](https://travis-ci.org/douglaswth/machine_tag)
|
5
|
+
[![Dependency Status](https://gemnasium.com/douglaswth/machine_tag.png)](https://gemnasium.com/douglaswth/machine_tag)
|
6
|
+
|
7
|
+
MachineTag is a Ruby library for using machine tags like those used on [Flickr] and [RightScale].
|
8
|
+
|
9
|
+
[Flickr]: http://www.flickr.com/help/tags/#613430
|
10
|
+
[RightScale]: http://support.rightscale.com/12-Guides/RightScale_101/06-Advanced_Concepts/Tagging
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'machine_tag'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install machine_tag
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
MachineTag provides two classes for dealing with machine tags and tags in general: `MachineTag::Tag`
|
29
|
+
and `MachineTag::Set`:
|
30
|
+
|
31
|
+
### MachineTag::Tag
|
32
|
+
|
33
|
+
The MachineTag::Tag class represents a tag which can either be a machine tag or a plain tag. It
|
34
|
+
inherits from [String] so it can be used in the same ways.
|
35
|
+
|
36
|
+
[String]: http://ruby-doc.org/core-1.9.3/String.html
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
plain_tag = MachineTag::Tag.new('geotagged')
|
40
|
+
|
41
|
+
plain_tag == 'geotagged' # => true
|
42
|
+
plain_tag.machine_tag? # => false
|
43
|
+
|
44
|
+
machine_tag = MachineTag::Tag.new('geo:lat=34.4348067')
|
45
|
+
|
46
|
+
machine_tag == 'geo:lat=34.4348067' # => true
|
47
|
+
machine_tag.machine_tag? # => true
|
48
|
+
machine_tag.namespace # => "geo"
|
49
|
+
machine_tag.predicate # => "lat"
|
50
|
+
machine_tag.namespace_and_predicate # => "geo:lat"
|
51
|
+
machine_tag.value.to_f # => 34.4348067
|
52
|
+
|
53
|
+
machine_tag = MachineTag::Tag.machine_tag('geo', 'lon', -119.8016962)
|
54
|
+
|
55
|
+
machine_tag == 'geo:lon=-119.8016962' # => true
|
56
|
+
machine_tag.machine_tag? # => true
|
57
|
+
```
|
58
|
+
|
59
|
+
### MachineTag::Set
|
60
|
+
|
61
|
+
The `MachineTag::Set` class represents a set of tags and provides a way of looking them up by
|
62
|
+
namespace or by namespace and predicate. It inherits from the [Set] so it can be used in the same
|
63
|
+
ways. If `String` objects are passed into it they will automatically be converted to
|
64
|
+
`MachineTag::Tag` objects.
|
65
|
+
|
66
|
+
[Set]: http://ruby-doc.org/stdlib-1.9.3/libdoc/set/rdoc/Set.html
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
tags = MachineTag::Set['geotagged', 'geo:lat=34.4348067', 'geo:lon=-119.8016962']
|
70
|
+
|
71
|
+
tags.include?('geotagged') # => true
|
72
|
+
tags.plain_tags # => #<Set: {"geotagged"}>
|
73
|
+
tags.machine_tags # => #<Set: {"geo:lat=34.4348067", "geo:lon=-119.8016962"}>
|
74
|
+
tags['geo'] # => #<Set: {"geo:lat=34.4348067", "geo:lon=-119.8016962"}>
|
75
|
+
tags['geo:lat'] # => #<Set: {"geo:lat=34.4348067"}>
|
76
|
+
tags['geo', 'lon'] # => #<Set: {"geo:lon=-119.8016962"}>
|
77
|
+
```
|
78
|
+
|
79
|
+
More information can be found in the [documentation].
|
80
|
+
|
81
|
+
[documentation]: http://rubydoc.info/gems/machine_tag/frame
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/machine_tag.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
require "machine_tag/version"
|
25
|
+
require "machine_tag/tag"
|
26
|
+
require "machine_tag/set"
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
require 'set'
|
25
|
+
|
26
|
+
module MachineTag
|
27
|
+
# Set of tags which can be machine tags.
|
28
|
+
#
|
29
|
+
class Set < ::Set
|
30
|
+
# The tags in the set which are not machine tags
|
31
|
+
#
|
32
|
+
# @return [::Set<Tag>] the tags in the set which are not machine tags
|
33
|
+
#
|
34
|
+
attr_reader :plain_tags
|
35
|
+
|
36
|
+
# The tags in the set which are machine tags
|
37
|
+
#
|
38
|
+
# @return [::Set<Tag>] the tags in the set which are machine tags
|
39
|
+
#
|
40
|
+
attr_reader :machine_tags
|
41
|
+
|
42
|
+
# Creates a set of tags which can be machine tags. If String objects are passed in they will be
|
43
|
+
# converted to {Tag}.
|
44
|
+
#
|
45
|
+
# @param enum [Enumerable<Tag, String>, nil] the enumerable object of tags
|
46
|
+
# @param block [Proc] the optional block to preprocess elements before inserting them
|
47
|
+
#
|
48
|
+
def initialize(enum = nil, &block)
|
49
|
+
@plain_tags = ::Set.new
|
50
|
+
@machine_tags = ::Set.new
|
51
|
+
@tags_by_namespace = {}
|
52
|
+
@tags_by_namespace_and_predicate = {}
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
# Adds a tag to the set of tags. If a String object is passed in it will be converted to {Tag}.
|
57
|
+
#
|
58
|
+
# @param tag [Tag, String] the tag or string to add
|
59
|
+
#
|
60
|
+
# @return [Set] the tag set
|
61
|
+
#
|
62
|
+
def add(tag)
|
63
|
+
tag = Tag.new(tag) unless tag.is_a? Tag
|
64
|
+
super(tag)
|
65
|
+
|
66
|
+
if tag.machine_tag?
|
67
|
+
@machine_tags << tag
|
68
|
+
@tags_by_namespace[tag.namespace] ||= ::Set.new
|
69
|
+
@tags_by_namespace[tag.namespace] << tag
|
70
|
+
@tags_by_namespace_and_predicate[tag.namespace_and_predicate] ||= ::Set.new
|
71
|
+
@tags_by_namespace_and_predicate[tag.namespace_and_predicate] << tag
|
72
|
+
else
|
73
|
+
@plain_tags << tag
|
74
|
+
end
|
75
|
+
|
76
|
+
self
|
77
|
+
end
|
78
|
+
alias_method :<<, :add
|
79
|
+
|
80
|
+
# Retrieves machine tags in the Set with a matching namespace or namespace and predicate.
|
81
|
+
#
|
82
|
+
# @example
|
83
|
+
# tags = MachineTag::Set['a:b=x', 'a:b=y', 'a:c=z']
|
84
|
+
# tags['a'] # => #<Set: {"a:b=x", "a:b=y", "a:c=z"}>
|
85
|
+
# tags['a', 'b'] # => #<Set: {"a:b=x", "a:b=y"}>
|
86
|
+
# tags['a:c'] # => #<Set: {"a:c=z"}>
|
87
|
+
#
|
88
|
+
# @param namespace_or_namespace_and_predicate [String] the namespace to retrieve or the namespace
|
89
|
+
# and predicate to retreive combined in a string separated by +':'+
|
90
|
+
# @param predicate [String, nil] the predicate to retreive
|
91
|
+
#
|
92
|
+
# @return [::Set<Tag>] the machines tags that have the given namespace or namespace and predicate
|
93
|
+
#
|
94
|
+
def [](namespace_or_namespace_and_predicate, predicate = nil)
|
95
|
+
if namespace_or_namespace_and_predicate =~ /^#{PREFIX}$/
|
96
|
+
namespace = namespace_or_namespace_and_predicate
|
97
|
+
|
98
|
+
unless predicate
|
99
|
+
@tags_by_namespace[namespace]
|
100
|
+
else
|
101
|
+
raise ArgumentError, "Invalid machine tag predicate: #{predicate.inspect}" unless predicate =~ /^#{PREFIX}$/
|
102
|
+
@tags_by_namespace_and_predicate["#{namespace}:#{predicate}"]
|
103
|
+
end
|
104
|
+
elsif namespace_or_namespace_and_predicate =~ /^#{NAMESPACE_AND_PREDICATE}$/
|
105
|
+
namespace_and_predicate = namespace_or_namespace_and_predicate
|
106
|
+
raise ArgumentError, "Separate predicate passed with namespace and predicate: #{namespace_and_predicate.inspect}, #{predicate.inspect}" if predicate
|
107
|
+
@tags_by_namespace_and_predicate[namespace_and_predicate]
|
108
|
+
else
|
109
|
+
raise ArgumentError, "Invalid machine tag namespace and/or predicate: #{namespace_or_namespace_and_predicate.inspect}, #{predicate.inspect}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
module MachineTag
|
25
|
+
# The regular expression for matching the individual namespace and predicate portions of a machine tag
|
26
|
+
#
|
27
|
+
# @return [Regexp] the regular expression for matching the individual namespace and predicate
|
28
|
+
# portions of a machine tag
|
29
|
+
#
|
30
|
+
PREFIX = /[a-z][a-z0-9_]*/i
|
31
|
+
|
32
|
+
# The regular expression for matching the namespace and predicate portion of a machine tag
|
33
|
+
#
|
34
|
+
# @return [Regexp] the regular expression for matching the namespace and predicate portion of a machine tag
|
35
|
+
#
|
36
|
+
NAMESPACE_AND_PREDICATE = /(?<namespace>#{PREFIX}):(?<predicate>#{PREFIX})/
|
37
|
+
|
38
|
+
# The regular expression for matching a machine tag
|
39
|
+
#
|
40
|
+
# @return [Regexp] the regular expression for matching a machine tag
|
41
|
+
#
|
42
|
+
MACHINE_TAG = /^(?<namespace_and_predicate>#{NAMESPACE_AND_PREDICATE})=(?<value>.*)$/
|
43
|
+
|
44
|
+
# A tag which can be a machine tag.
|
45
|
+
#
|
46
|
+
class Tag < String
|
47
|
+
# The namespace portion of the machine tag, +nil+ if the tag is not a machine tag
|
48
|
+
#
|
49
|
+
# @return [String, nil] the namespace portion of the machine tag, +nil+ if the tag is not a machine tag
|
50
|
+
#
|
51
|
+
attr_reader :namespace
|
52
|
+
|
53
|
+
# The predicate portion of the machine tag, +nil+ if the tag is not a machine tag
|
54
|
+
#
|
55
|
+
# @return [String, nil] the predicate portion of the machine tag, +nil+ if the tag is not a machine tag
|
56
|
+
#
|
57
|
+
attr_reader :predicate
|
58
|
+
|
59
|
+
# The namespace and predicate portion of the machine tag, +nil+ if the tag is not a machine tag
|
60
|
+
#
|
61
|
+
# @return [String, nil] the namespace and predicate portion of the machine tag, +nil+ if the tag
|
62
|
+
# is not a machine tag
|
63
|
+
#
|
64
|
+
attr_reader :namespace_and_predicate
|
65
|
+
|
66
|
+
# The value portion of the machine tag, +nil+ if the tag is not a machine tag
|
67
|
+
#
|
68
|
+
# @return [String, nil] the value portion of the machine tag is not a machine tag
|
69
|
+
#
|
70
|
+
attr_reader :value
|
71
|
+
|
72
|
+
# Creates a tag object which can be a machine tag.
|
73
|
+
#
|
74
|
+
# @param str [String] the tag string
|
75
|
+
#
|
76
|
+
def initialize(str)
|
77
|
+
super
|
78
|
+
if match = self.match(MACHINE_TAG)
|
79
|
+
@namespace_and_predicate = match[:namespace_and_predicate]
|
80
|
+
@namespace = match[:namespace]
|
81
|
+
@predicate = match[:predicate]
|
82
|
+
@value = match[:value]
|
83
|
+
@value = $1 if @value =~ /^"(.*)"$/
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Creates a machine tag from a given namespace, predicate, and value.
|
88
|
+
#
|
89
|
+
# @param namespace [String] the namespace
|
90
|
+
# @param predicate [String] the predicate
|
91
|
+
# @param value [String, #to_s] the value
|
92
|
+
#
|
93
|
+
# @return [Tag] the machine tag
|
94
|
+
#
|
95
|
+
# @raise [ArgumentError] if the +namespace+ or +predicate+ are not in the correct format
|
96
|
+
#
|
97
|
+
def self.machine_tag(namespace, predicate, value)
|
98
|
+
raise ArgumentError, "Invalid machine tag namespace: #{namespace.inspect}" unless namespace =~ /^#{PREFIX}$/
|
99
|
+
raise ArgumentError, "Invalid machine tag predicate: #{predicate.inspect}" unless predicate =~ /^#{PREFIX}$/
|
100
|
+
|
101
|
+
new("#{namespace}:#{predicate}=#{value}")
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns whether this tag is a machine tag or not.
|
105
|
+
#
|
106
|
+
# @return [Boolean] +true+ if this tag is a machine tag, otherwise +false+
|
107
|
+
#
|
108
|
+
def machine_tag?
|
109
|
+
!!namespace
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
# Library for using Machine Tags.
|
25
|
+
#
|
26
|
+
module MachineTag
|
27
|
+
# The version of this library.
|
28
|
+
#
|
29
|
+
VERSION = "1.0.0"
|
30
|
+
end
|
data/machine_tag.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'machine_tag/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "machine_tag"
|
8
|
+
spec.version = MachineTag::VERSION
|
9
|
+
spec.authors = ["Douglas Thrift"]
|
10
|
+
spec.email = ["douglas@douglasthrift.net"]
|
11
|
+
spec.description = %q{A Ruby library for using machine tags like those used on Flickr and RightScale}
|
12
|
+
spec.summary = %q{Library for using machine tags}
|
13
|
+
spec.homepage = "https://github.com/douglaswth/machine_tag"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rdoc"
|
24
|
+
spec.add_development_dependency "redcarpet"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "yard", "~> 0.8.7.2"
|
27
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MachineTag::Set do
|
4
|
+
it 'should create sets with plain tags' do
|
5
|
+
tags = MachineTag::Set['a', 'b', 'c']
|
6
|
+
tags.should eq Set['a', 'b', 'c']
|
7
|
+
tags.plain_tags.should eq Set['a', 'b', 'c']
|
8
|
+
tags.machine_tags.should be_empty
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should create sets with machine tags' do
|
12
|
+
tags = MachineTag::Set['a:b=x', 'a:b=y', 'a:c=z', 'd:e=f']
|
13
|
+
tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z', 'd:e=f']
|
14
|
+
tags.plain_tags.should be_empty
|
15
|
+
tags.machine_tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z', 'd:e=f']
|
16
|
+
tags['a'].should eq Set['a:b=x', 'a:b=y', 'a:c=z']
|
17
|
+
tags['a:b'].should eq Set['a:b=x', 'a:b=y']
|
18
|
+
tags['a', 'c'].should eq Set['a:c=z']
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should create sets with mixed plain and machine tags' do
|
22
|
+
tags = MachineTag::Set['a:b=x', 'a:b=y', 'a:c=z', 'd', 'e', 'f']
|
23
|
+
tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z', 'd', 'e', 'f']
|
24
|
+
tags.plain_tags.should eq Set['d', 'e', 'f']
|
25
|
+
tags.machine_tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z']
|
26
|
+
tags['a'].should eq Set['a:b=x', 'a:b=y', 'a:c=z']
|
27
|
+
tags['a:b'].should eq Set['a:b=x', 'a:b=y']
|
28
|
+
tags['a', 'c'].should eq Set['a:c=z']
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#add' do
|
32
|
+
let(:tags) { MachineTag::Set.new }
|
33
|
+
|
34
|
+
it 'should add strings' do
|
35
|
+
tags << 'a'
|
36
|
+
tags.first.should be_an_instance_of(MachineTag::Tag)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should add tags' do
|
40
|
+
tag = MachineTag::Tag.new('a')
|
41
|
+
tags << tag
|
42
|
+
tags.first.should be(tag)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#[]' do
|
47
|
+
let(:tags) { MachineTag::Set.new }
|
48
|
+
|
49
|
+
it 'should not retrieve with an invalid predicate' do
|
50
|
+
expect do
|
51
|
+
tags['a', '!']
|
52
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag predicate: "!"')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not retrieve with a combined namespace and predicate and a predicate' do
|
56
|
+
expect do
|
57
|
+
tags['a:b', 'c']
|
58
|
+
end.to raise_error(ArgumentError, 'Separate predicate passed with namespace and predicate: "a:b", "c"')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should not retreive with an invalid namespace and/or predicate' do
|
62
|
+
expect do
|
63
|
+
tags['!']
|
64
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag namespace and/or predicate: "!", nil')
|
65
|
+
|
66
|
+
expect do
|
67
|
+
tags['a:!']
|
68
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag namespace and/or predicate: "a:!", nil')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MachineTag::Tag do
|
4
|
+
it 'should create plain tags' do
|
5
|
+
tag = MachineTag::Tag.new('a')
|
6
|
+
tag.should eq 'a'
|
7
|
+
tag.namespace.should be_nil
|
8
|
+
tag.predicate.should be_nil
|
9
|
+
tag.namespace_and_predicate.should be_nil
|
10
|
+
tag.value.should be_nil
|
11
|
+
tag.machine_tag?.should be_false
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should create machine tags' do
|
15
|
+
tag = MachineTag::Tag.new('a:b=c')
|
16
|
+
tag.should eq 'a:b=c'
|
17
|
+
tag.namespace.should eq 'a'
|
18
|
+
tag.predicate.should eq 'b'
|
19
|
+
tag.namespace_and_predicate.should eq 'a:b'
|
20
|
+
tag.value.should eq 'c'
|
21
|
+
tag.machine_tag?.should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should handle a machine tag with a quoted value' do
|
25
|
+
tag = MachineTag::Tag.new('a:b="c d"')
|
26
|
+
tag.should eq 'a:b="c d"'
|
27
|
+
tag.namespace.should eq 'a'
|
28
|
+
tag.predicate.should eq 'b'
|
29
|
+
tag.namespace_and_predicate.should eq 'a:b'
|
30
|
+
tag.value.should eq 'c d'
|
31
|
+
tag.machine_tag?.should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '::machine_tag' do
|
35
|
+
it 'should create machine tags' do
|
36
|
+
tag = MachineTag::Tag.machine_tag('a', 'b', 'c')
|
37
|
+
tag.should eq 'a:b=c'
|
38
|
+
tag.namespace.should eq 'a'
|
39
|
+
tag.predicate.should eq 'b'
|
40
|
+
tag.namespace_and_predicate.should eq 'a:b'
|
41
|
+
tag.value.should eq 'c'
|
42
|
+
tag.machine_tag?.should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should not create machine tags with invalid namespaces' do
|
46
|
+
expect do
|
47
|
+
MachineTag::Tag.machine_tag('!', 'b', 'c')
|
48
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag namespace: "!"')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should not create machine tags with invalid predicates' do
|
52
|
+
expect do
|
53
|
+
MachineTag::Tag.machine_tag('a', '!', 'c')
|
54
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag predicate: "!"')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: machine_tag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Douglas Thrift
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rdoc
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: redcarpet
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: yard
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.8.7.2
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.8.7.2
|
110
|
+
description: A Ruby library for using machine tags like those used on Flickr and RightScale
|
111
|
+
email:
|
112
|
+
- douglas@douglasthrift.net
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- .gitignore
|
118
|
+
- .rspec
|
119
|
+
- .travis.yml
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- lib/machine_tag.rb
|
125
|
+
- lib/machine_tag/set.rb
|
126
|
+
- lib/machine_tag/tag.rb
|
127
|
+
- lib/machine_tag/version.rb
|
128
|
+
- machine_tag.gemspec
|
129
|
+
- spec/machine_tag_set_spec.rb
|
130
|
+
- spec/machine_tag_spec.rb
|
131
|
+
- spec/machine_tag_tag_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
homepage: https://github.com/douglaswth/machine_tag
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ! '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 1.8.23
|
155
|
+
signing_key:
|
156
|
+
specification_version: 3
|
157
|
+
summary: Library for using machine tags
|
158
|
+
test_files:
|
159
|
+
- spec/machine_tag_set_spec.rb
|
160
|
+
- spec/machine_tag_spec.rb
|
161
|
+
- spec/machine_tag_tag_spec.rb
|
162
|
+
- spec/spec_helper.rb
|
163
|
+
has_rdoc:
|