swhid 0.1.0 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36bebc03a91e8eecaa94a9dacb8496ab76fd8b2f2d4858b6088288a3b1195cbd
4
- data.tar.gz: 71f64f03c285c8f445b5e5e74938d7d08141e91bc0cc914506fcdfb6dd970448
3
+ metadata.gz: 78a2795583924a21b4aae1a173e528af68805dd89ad44e6c3db32b534ca55653
4
+ data.tar.gz: 1a65c99bade2ae1c4f00c69d2b49a31708da9fc8f15ee5c63d7d9806c876b7e5
5
5
  SHA512:
6
- metadata.gz: 1aa17852be20170334a2d45cc7affc4d133e08eba03289a1e2269d0d0faec60b5367ed81396336ac4f26ea8d781bbb2bdf2cb60fac0db8f2ee0ff6f494ab30ed
7
- data.tar.gz: 9fed39916ba99f2c3fa44c26fb266b7e465138c80aa200f368c6c89cc57c00b91c9753975688ff292ad47c30f2fa9c13c395526f439fb87c388253e2bd7c65a5
6
+ metadata.gz: e9d04af133af2dca2b749ce7259a792dbed4622b7bfc587cc08be99d87e109d50be5926e0db2b653b3da7d0e74454fac3e4a9709b12fcd9306f4be20583eab97
7
+ data.tar.gz: 24affb1c2fa578ab1211b54540a3d2a51497e583b70804cf837c8999a2c8beb3c3546af6f0de35fe2743e26918fc775baf9f6ec0e75fad0d2d116b10730a412b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.1] - 2025-11-09
4
+
5
+ - Package manager tests for PyPI, RubyGems, Maven, Cargo, and NPM artifacts (content and extracted directories)
6
+ - Filesystem directory SWHID computation helper
7
+
8
+ ## [0.2.0] - 2025-11-09
9
+
10
+ - Full implementation of all SWHID object types (content, directory, revision, release, snapshot)
11
+ - Cross-implementation validation against Python swh-model library
12
+ - CLI tool with JSON output support
13
+ - Performance benchmarks
14
+ - Bug fixes for directory permissions and revision timestamp handling
15
+
3
16
  ## [0.1.0] - 2025-11-09
4
17
 
5
18
  - Initial release
data/README.md CHANGED
@@ -234,8 +234,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
234
234
 
235
235
  ## Contributing
236
236
 
237
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/swhid. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/swhid/blob/main/CODE_OF_CONDUCT.md).
237
+ Bug reports and pull requests are welcome on GitHub at https://github.com/andrew/swhid. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/andrew/swhid/blob/main/CODE_OF_CONDUCT.md).
238
238
 
239
239
  ## Code of Conduct
240
240
 
241
- Everyone interacting in the Swhid project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/swhid/blob/main/CODE_OF_CONDUCT.md).
241
+ Everyone interacting in the Swhid project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/andrew/swhid/blob/main/CODE_OF_CONDUCT.md).
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "swhid"
6
+ require "benchmark"
7
+
8
+ puts "SWHID Performance Benchmarks"
9
+ puts "=" * 60
10
+ puts
11
+
12
+ # Benchmark content hashing
13
+ puts "Content (blob) hashing:"
14
+ content_small = "Hello, World!"
15
+ content_medium = "x" * 10_000
16
+ content_large = "x" * 1_000_000
17
+
18
+ Benchmark.bm(30) do |x|
19
+ x.report("Small content (13 bytes):") do
20
+ 10_000.times { Swhid.from_content(content_small) }
21
+ end
22
+
23
+ x.report("Medium content (10 KB):") do
24
+ 1_000.times { Swhid.from_content(content_medium) }
25
+ end
26
+
27
+ x.report("Large content (1 MB):") do
28
+ 100.times { Swhid.from_content(content_large) }
29
+ end
30
+ end
31
+
32
+ puts
33
+ puts "=" * 60
34
+ puts
35
+
36
+ # Benchmark directory hashing
37
+ puts "Directory (tree) hashing:"
38
+
39
+ entries_small = [
40
+ { name: "README.md", type: :file, target: "94a9ed024d3859793618152ea559a168bbcbb5e2" }
41
+ ]
42
+
43
+ entries_medium = 10.times.map do |i|
44
+ { name: "file#{i}.txt", type: :file, target: "94a9ed024d3859793618152ea559a168bbcbb5e2" }
45
+ end
46
+
47
+ entries_large = 100.times.map do |i|
48
+ { name: "file#{i}.txt", type: :file, target: "94a9ed024d3859793618152ea559a168bbcbb5e2" }
49
+ end
50
+
51
+ Benchmark.bm(30) do |x|
52
+ x.report("Small directory (1 entry):") do
53
+ 10_000.times { Swhid.from_directory(entries_small) }
54
+ end
55
+
56
+ x.report("Medium directory (10 entries):") do
57
+ 5_000.times { Swhid.from_directory(entries_medium) }
58
+ end
59
+
60
+ x.report("Large directory (100 entries):") do
61
+ 1_000.times { Swhid.from_directory(entries_large) }
62
+ end
63
+ end
64
+
65
+ puts
66
+ puts "=" * 60
67
+ puts
68
+
69
+ # Benchmark revision hashing
70
+ puts "Revision (commit) hashing:"
71
+
72
+ revision_metadata = {
73
+ directory: "4b825dc642cb6eb9a060e54bf8d69288fbee4904",
74
+ author: "John Doe <john@example.com>",
75
+ author_timestamp: 1234567890,
76
+ committer: "Jane Smith <jane@example.com>",
77
+ committer_timestamp: 1234567890,
78
+ message: "Initial commit"
79
+ }
80
+
81
+ Benchmark.bm(30) do |x|
82
+ x.report("Revision (simple):") do
83
+ 10_000.times { Swhid.from_revision(revision_metadata) }
84
+ end
85
+
86
+ x.report("Revision (with parents):") do
87
+ 10_000.times do
88
+ Swhid.from_revision(revision_metadata.merge(
89
+ parents: ["94a9ed024d3859793618152ea559a168bbcbb5e2"]
90
+ ))
91
+ end
92
+ end
93
+ end
94
+
95
+ puts
96
+ puts "=" * 60
97
+ puts
98
+
99
+ # Benchmark SWHID parsing
100
+ puts "SWHID parsing:"
101
+
102
+ swhid_simple = "swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2"
103
+ swhid_with_qualifiers = "swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2;origin=https://github.com/example/repo;lines=1-10"
104
+
105
+ Benchmark.bm(30) do |x|
106
+ x.report("Parse simple SWHID:") do
107
+ 10_000.times { Swhid.parse(swhid_simple) }
108
+ end
109
+
110
+ x.report("Parse SWHID with qualifiers:") do
111
+ 10_000.times { Swhid.parse(swhid_with_qualifiers) }
112
+ end
113
+ end
114
+
115
+ puts
116
+ puts "=" * 60
117
+ puts "Benchmark complete!"
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/sha1"
4
+ require "find"
5
+
6
+ module Swhid
7
+ module FromFilesystem
8
+ def self.from_directory_path(path)
9
+ raise ArgumentError, "Path does not exist: #{path}" unless File.exist?(path)
10
+ raise ArgumentError, "Path is not a directory: #{path}" unless File.directory?(path)
11
+
12
+ entries = build_entries(path)
13
+ Swhid.from_directory(entries)
14
+ end
15
+
16
+ def self.build_entries(dir_path)
17
+ entries = []
18
+
19
+ Dir.foreach(dir_path) do |name|
20
+ next if name == "." || name == ".."
21
+ next if name == ".git"
22
+
23
+ full_path = File.join(dir_path, name)
24
+ stat = File.lstat(full_path)
25
+
26
+ entry = if File.symlink?(full_path)
27
+ target_content = File.readlink(full_path)
28
+ target_hash = Swhid.from_content(target_content).object_hash
29
+ { name: name, type: :symlink, target: target_hash }
30
+ elsif stat.directory?
31
+ target_swhid = from_directory_path(full_path)
32
+ { name: name, type: :dir, target: target_swhid.object_hash }
33
+ elsif stat.executable?
34
+ content = File.binread(full_path)
35
+ target_hash = Swhid.from_content(content).object_hash
36
+ { name: name, type: :exec, target: target_hash }
37
+ else
38
+ content = File.binread(full_path)
39
+ target_hash = Swhid.from_content(content).object_hash
40
+ { name: name, type: :file, target: target_hash }
41
+ end
42
+
43
+ entries << entry
44
+ end
45
+
46
+ entries
47
+ end
48
+ end
49
+ end
@@ -18,13 +18,15 @@ module Swhid
18
18
  def default_perms
19
19
  case type
20
20
  when :dir
21
- "040000"
21
+ "40000"
22
22
  when :file
23
23
  "100644"
24
24
  when :exec
25
25
  "100755"
26
26
  when :symlink
27
27
  "120000"
28
+ when :rev
29
+ "160000"
28
30
  else
29
31
  raise ValidationError, "Unknown entry type: #{type}"
30
32
  end
data/lib/swhid/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Swhid
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.1"
5
5
  end
data/lib/swhid.rb CHANGED
@@ -7,6 +7,7 @@ require_relative "swhid/objects/directory"
7
7
  require_relative "swhid/objects/revision"
8
8
  require_relative "swhid/objects/release"
9
9
  require_relative "swhid/objects/snapshot"
10
+ require_relative "swhid/from_filesystem"
10
11
 
11
12
  module Swhid
12
13
  class Error < StandardError; end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swhid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nesbitt
@@ -23,8 +23,10 @@ files:
23
23
  - CODE_OF_CONDUCT.md
24
24
  - README.md
25
25
  - Rakefile
26
+ - benchmark/benchmark.rb
26
27
  - exe/swhid
27
28
  - lib/swhid.rb
29
+ - lib/swhid/from_filesystem.rb
28
30
  - lib/swhid/identifier.rb
29
31
  - lib/swhid/objects/content.rb
30
32
  - lib/swhid/objects/directory.rb