ffi-xattr 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 03fc82a1353a14b6b48327682f8efb5327f8d4a6
4
- data.tar.gz: dd6a2abd62dd605cb0aae1cb65551e69f4c2d00f
2
+ SHA256:
3
+ metadata.gz: 4e89f2e515824d33bf4cfe74b95eea1526e35092c669bb5f4280c8d4c86071d4
4
+ data.tar.gz: 3369d3f39135d5176d1b24077eb380ff5140aa78498ccbd9f0b0291d2c36484c
5
5
  SHA512:
6
- metadata.gz: f9cc1cbaab866ac3a6d89d7066b8621ba66eb36ac45032df2a59b0c92a7d57fc297d3db3ed02bed7d41c05aa00520690f84d182979feca7ec881f5eb0ad7200c
7
- data.tar.gz: 73dc271860f7c541aac07195bdfe4cc3746bee9fa0755917967fe899f90ff91934b2f915230446f19bcbd947bda236a37cf372fb6aeb89d0d84840d02e68b244
6
+ metadata.gz: ea47fac5b6f82cf0c065724f3283bb72fe81f0636eb9613be1e7f89f42066e52cc038a8fa2d00ee12b8faa88f74dbb830f795eea1144ec7943f18bb40c134ef1
7
+ data.tar.gz: fd88cae5f42ca84e36214b76c82afedfd367c5e60e3767d786221ec62dbf95d9c9ea6ccf4e395ea55a2be9a66524bc015edad49b744505d7dcfca239b720145a
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  /doc/
6
+ vendor
data/README.md CHANGED
@@ -3,9 +3,6 @@ ffi-xattr
3
3
 
4
4
  Ruby library to manage extended file attributes.
5
5
 
6
- [![Build Status](https://secure.travis-ci.org/jarib/ffi-xattr.png)](http://travis-ci.org/jarib/ffi-xattr)
7
-
8
-
9
6
  Example
10
7
  -------
11
8
 
@@ -16,7 +16,7 @@ class Xattr # :nodoc: all
16
16
  end
17
17
 
18
18
  def check(int)
19
- raise SystemCallError.new(*last) if int != 0
19
+ raise SystemCallError.new(*last) if int < 0
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,9 @@
1
+ require 'ffi-xattr'
2
+
3
+ class File
4
+
5
+ # Returns an Xattr object for the named file (see Xattr).
6
+ def self.xattr(file_name)
7
+ Xattr.new(file_name)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'ffi-xattr/extensions/file'
2
+
3
+ class Pathname
4
+ # Returns an Xattr object.
5
+ # See File.xattr.
6
+ def xattr
7
+ File.xattr(self)
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ require 'ffi-xattr/extensions/file'
2
+ require 'ffi-xattr/extensions/pathname'
3
+
@@ -0,0 +1,62 @@
1
+ class Xattr # :nodoc: all
2
+ module Lib
3
+ extend FFI::Library
4
+
5
+ ffi_lib "c"
6
+
7
+ EXTATTR_NAMESPACE_USER = 1
8
+
9
+ attach_function :extattr_list_file, [:string, :int, :pointer, :size_t], :ssize_t
10
+ attach_function :extattr_set_file, [:string, :int, :string, :pointer, :size_t], :ssize_t
11
+ attach_function :extattr_get_file, [:string, :int, :string, :pointer, :size_t], :ssize_t
12
+ attach_function :extattr_delete_file, [:string, :int, :string], :ssize_t
13
+
14
+ attach_function :extattr_list_link, [:string, :int, :pointer, :size_t], :ssize_t
15
+ attach_function :extattr_set_link, [:string, :int, :string, :pointer, :size_t], :ssize_t
16
+ attach_function :extattr_get_link, [:string, :int, :string, :pointer, :size_t], :ssize_t
17
+ attach_function :extattr_delete_link, [:string, :int, :string], :ssize_t
18
+
19
+ class << self
20
+ def list(path, no_follow)
21
+ method = no_follow ? :extattr_list_link : :extattr_list_file
22
+ size = send(method, path, EXTATTR_NAMESPACE_USER, nil, 0)
23
+ res_ptr = FFI::MemoryPointer.new(:pointer, size)
24
+ send(method, path, EXTATTR_NAMESPACE_USER, res_ptr, size)
25
+
26
+ res = []
27
+ bytes = res_ptr.read_string(size).bytes
28
+ until bytes.empty?
29
+ size = bytes.shift
30
+ res << bytes.shift(size).map(&:chr).join
31
+ end
32
+
33
+ res
34
+ end
35
+
36
+ def get(path, no_follow, key)
37
+ method = no_follow ? :extattr_get_link : :extattr_get_file
38
+ size = send(method, path, EXTATTR_NAMESPACE_USER, key, nil, 0)
39
+ return unless size > 0
40
+
41
+ str_ptr = FFI::MemoryPointer.new(:char, size)
42
+ send(method, path, EXTATTR_NAMESPACE_USER, key, str_ptr, size)
43
+
44
+ str_ptr.read_string(size)
45
+ end
46
+
47
+ def set(path, no_follow, key, value)
48
+ method = no_follow ? :extattr_set_link : :extattr_set_file
49
+ #require 'byebug'
50
+ #byebug
51
+
52
+ Error.check send(method, path, EXTATTR_NAMESPACE_USER, key, value, value.bytesize)
53
+ end
54
+
55
+ def remove(path, no_follow, key)
56
+ method = no_follow ? :extattr_delete_link : :extattr_delete_file
57
+ Error.check send(method, path, EXTATTR_NAMESPACE_USER, key)
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -1,3 +1,3 @@
1
1
  class Xattr
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/ffi-xattr.rb CHANGED
@@ -5,6 +5,8 @@ require 'ffi-xattr/error'
5
5
  case RUBY_PLATFORM
6
6
  when /linux/
7
7
  require 'ffi-xattr/linux_lib'
8
+ when /freebsd/
9
+ require 'ffi-xattr/freebsd_lib'
8
10
  when /darwin|bsd/
9
11
  require 'ffi-xattr/darwin_lib'
10
12
  when /mingw/
@@ -19,8 +21,16 @@ class Xattr
19
21
  # Create a new Xattr instance with path.
20
22
  # Use <tt>:no_follow => true</tt> in options to work on symlink itself instead of following it.
21
23
  def initialize(path, options = {})
22
- raise Errno::ENOENT, path unless File.exist?(path)
23
- @path = path.to_str
24
+ @path =
25
+ if path.respond_to?(:to_path)
26
+ path.to_path
27
+ elsif path.respond_to?(:to_str)
28
+ path.to_str
29
+ else
30
+ path
31
+ end
32
+ raise Errno::ENOENT, @path unless File.exist?(@path)
33
+
24
34
  @no_follow = !!options[:no_follow]
25
35
  end
26
36
 
@@ -54,11 +64,17 @@ class Xattr
54
64
  end
55
65
 
56
66
  # Returns hash of extended attributes
57
- def as_json(*args)
67
+
68
+ def to_hash
58
69
  res = {}
59
70
  each { |k,v| res[k] = v }
60
71
 
61
72
  res
62
73
  end
63
74
 
75
+ alias_method :to_h, :to_hash
76
+
77
+ def as_json(*args)
78
+ to_hash
79
+ end
64
80
  end
@@ -0,0 +1,35 @@
1
+ require 'ffi-xattr/extensions'
2
+
3
+ describe "Xattr extensions" do
4
+ let(:path) { "test.txt" }
5
+ let(:xattr) { Xattr.new(path) }
6
+
7
+ before { File.open(path, "w") { |io| io << "some content" } }
8
+ after { File.delete(path) }
9
+
10
+ describe "File.xattr" do
11
+ it "should return an Xattr for the supplied path" do
12
+ x = File.xattr(path)
13
+
14
+ x.should be_kind_of(Xattr)
15
+
16
+ #and operate on the real path
17
+ x["user.file"] = "foo"
18
+ Xattr.new(path)["user.file"].should == "foo"
19
+ end
20
+ end
21
+
22
+ describe "Pathname#xattr" do
23
+ it "should return an Xattr for the underlying path" do
24
+ p = Pathname.new(path)
25
+ x = p.xattr
26
+
27
+ x.should be_kind_of(Xattr)
28
+
29
+ #and operate on the real path
30
+ x["user.path"] = "foo"
31
+ Xattr.new(path)["user.path"].should == "foo"
32
+ end
33
+ end
34
+
35
+ end
data/spec/xattr_spec.rb CHANGED
@@ -57,7 +57,7 @@ describe Xattr do
57
57
  value.should == "world"
58
58
  end
59
59
 
60
- called.should be_true
60
+ called.should == true
61
61
  end
62
62
 
63
63
  it "is Enumerable" do
@@ -67,11 +67,13 @@ describe Xattr do
67
67
  xattr.to_a.should == [['user.foo', 'bar']]
68
68
  end
69
69
 
70
- it "returns a Hash for #as_json" do
70
+ it "returns a Hash for #to_hash, #to_h, #as_json" do
71
71
  xattr['user.foo'] = 'bar'
72
72
  xattr['user.bar'] = 'baz'
73
73
 
74
- xattr.as_json.should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
74
+ xattr.to_hash.should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
75
+ xattr.to_h.should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
76
+ xattr.as_json(foo: 1).should == {'user.foo' => 'bar', 'user.bar' => 'baz'}
75
77
  end
76
78
 
77
79
  it "raises Errno::ENOENT if the file doesn't exist" do
@@ -82,20 +84,22 @@ describe Xattr do
82
84
  lambda{ Xattr.new(1) }.should raise_error(TypeError)
83
85
  end
84
86
 
85
- class SuperPath
86
- def initialize(path)
87
- @path = path
88
- end
87
+ it "should work with object that can be converted to string" do
88
+ super_path = double("super_path")
89
+ super_path.should_receive(:to_str).and_return(path)
89
90
 
90
- def to_str
91
- @path.dup
92
- end
91
+ Xattr.new(super_path).set('user.foo', 'bar')
92
+
93
+ Xattr.new(path).get('user.foo').should == 'bar'
93
94
  end
94
95
 
95
- it "should work with object that can be directly converted to string" do
96
- super_path = SuperPath.new(path)
97
- Xattr.new(super_path).set('user.foo', 'bar')
98
- Xattr.new(super_path).get('user.foo').should == 'bar'
96
+ it "should work with object that can be coerced to string with #to_path" do
97
+ to_path_obj = double("to_path")
98
+ to_path_obj.should_receive(:to_path).and_return(path)
99
+
100
+ Xattr.new(to_path_obj).set('user.to_path', 'bar')
101
+
102
+ Xattr.new(path).get('user.to_path').should == 'bar'
99
103
  end
100
104
 
101
105
  describe "respecting :no_follow option" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-xattr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jari Bakken
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-30 00:00:00.000000000 Z
11
+ date: 2022-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -69,9 +69,14 @@ files:
69
69
  - lib/ffi-xattr.rb
70
70
  - lib/ffi-xattr/darwin_lib.rb
71
71
  - lib/ffi-xattr/error.rb
72
+ - lib/ffi-xattr/extensions.rb
73
+ - lib/ffi-xattr/extensions/file.rb
74
+ - lib/ffi-xattr/extensions/pathname.rb
75
+ - lib/ffi-xattr/freebsd_lib.rb
72
76
  - lib/ffi-xattr/linux_lib.rb
73
77
  - lib/ffi-xattr/version.rb
74
78
  - lib/ffi-xattr/windows_lib.rb
79
+ - spec/extensions_spec.rb
75
80
  - spec/xattr_spec.rb
76
81
  homepage: http://github.com/jarib/ffi-xattr
77
82
  licenses: []
@@ -91,11 +96,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
96
  - !ruby/object:Gem::Version
92
97
  version: '0'
93
98
  requirements: []
94
- rubyforge_project: ffi-xattr
95
- rubygems_version: 2.2.0
99
+ rubygems_version: 3.0.3.1
96
100
  signing_key:
97
101
  specification_version: 4
98
102
  summary: Manipulate extended file attributes
99
103
  test_files:
104
+ - spec/extensions_spec.rb
100
105
  - spec/xattr_spec.rb
101
- has_rdoc: