schepherd 0.1.0

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/bin/schepherd ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/schepherd"
5
+
6
+ begin
7
+ binary = Schepherd.executable
8
+ # The [command, argv0] form never goes through a shell, which a single
9
+ # string would when schepherd runs without arguments.
10
+ exec([binary, binary], *ARGV)
11
+ rescue Schepherd::Error => e
12
+ warn e.message
13
+ exit 1
14
+ rescue SystemCallError => e
15
+ warn "schepherd: cannot start #{binary}: #{e.message}"
16
+ exit 1
17
+ end
data/lib/schepherd.rb ADDED
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbconfig"
4
+
5
+ # Schepherd delivers pinned JSON Schemas from an OCI catalog to verified local
6
+ # files. This gem ships the native schepherd binary of every supported
7
+ # platform under libexec/; the schepherd executable runs the one built for the
8
+ # running system.
9
+ module Schepherd
10
+ # Names the environment variable that holds the absolute path of a
11
+ # schepherd binary to run instead of the bundled one, for systems without a
12
+ # prebuilt binary.
13
+ BINARY_OVERRIDE = "SCHEPHERD_BINARY"
14
+
15
+ # The os-cpu pairs of libexec/schepherd-<os>-<cpu>. The same table exists in
16
+ # tools/release/internal/wrappers, which packs the gem; a Go test keeps the two
17
+ # identical.
18
+ TARGETS = [
19
+ %w[darwin arm64],
20
+ %w[darwin x64],
21
+ %w[linux arm64],
22
+ %w[linux x64],
23
+ %w[windows arm64],
24
+ %w[windows x64],
25
+ ].freeze
26
+
27
+ # Raised when there is no binary to run.
28
+ class Error < StandardError; end
29
+
30
+ module_function
31
+
32
+ # Returns the absolute path of the binary to run: the SCHEPHERD_BINARY
33
+ # override, or the bundled binary of the platform.
34
+ def executable(env: ENV, platform: Gem::Platform.local, host: RbConfig::CONFIG,
35
+ root: File.expand_path("..", __dir__))
36
+ override = binary_override(env)
37
+ return override if override
38
+
39
+ pair = target(platform, host)
40
+ raise Error, unsupported_message(platform) unless TARGETS.include?(pair)
41
+
42
+ os, cpu = pair
43
+ path = File.join(root, "libexec", "schepherd-#{os}-#{cpu}", os == "windows" ? "schepherd.exe" : "schepherd")
44
+ return path if File.file?(path)
45
+
46
+ raise Error, "schepherd: the binary #{path} for #{os}-#{cpu} is missing from the gem. " \
47
+ "Reinstall it with `gem install schepherd`, or set #{BINARY_OVERRIDE} to the absolute path " \
48
+ "of a schepherd binary."
49
+ end
50
+
51
+ # Returns the [os, cpu] pair of the bundled binary for a platform, or nil.
52
+ # JRuby reports the platform universal-java, so the host OS and CPU of
53
+ # RbConfig answer what Gem::Platform cannot.
54
+ def target(platform = Gem::Platform.local, host = RbConfig::CONFIG)
55
+ os = os_name(platform.os) || os_name(host["host_os"])
56
+ cpu = cpu_name(platform.cpu) || cpu_name(host["host_cpu"])
57
+ [os, cpu] if os && cpu
58
+ end
59
+
60
+ def os_name(os)
61
+ case os.to_s
62
+ when /\Alinux/ then "linux"
63
+ when /\Adarwin/ then "darwin"
64
+ when /\A(?:mingw|mswin|windows)/ then "windows"
65
+ end
66
+ end
67
+
68
+ # Apple silicon Rubies may report arm64e, and the system Ruby of macOS a
69
+ # universal.<cpu> CPU.
70
+ def cpu_name(cpu)
71
+ case cpu.to_s.sub(/\Auniversal\./, "")
72
+ when /\Aarm64/, "aarch64" then "arm64"
73
+ when "x86_64", "x64", "amd64" then "x64"
74
+ end
75
+ end
76
+
77
+ # Returns the validated SCHEPHERD_BINARY path, or nil when it is unset or
78
+ # empty.
79
+ def binary_override(env = ENV)
80
+ value = env[BINARY_OVERRIDE]
81
+ return nil if value.nil? || value.empty?
82
+
83
+ unless File.absolute_path?(value)
84
+ raise Error, "schepherd: #{BINARY_OVERRIDE} must be an absolute path to the schepherd binary, got #{value.inspect}"
85
+ end
86
+ return value if File.file?(value)
87
+
88
+ raise Error, "schepherd: #{BINARY_OVERRIDE} points to #{value.inspect}, which is not a regular file"
89
+ end
90
+
91
+ def unsupported_message(platform)
92
+ supported = TARGETS.map { |os, cpu| "#{os}-#{cpu}" }.join(", ")
93
+ "schepherd: no prebuilt binary for #{platform}. Supported platforms: #{supported}. " \
94
+ "Set #{BINARY_OVERRIDE} to the absolute path of a schepherd binary built for this system."
95
+ end
96
+ private_class_method :unsupported_message
97
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schepherd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ovineko
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2026-09-29 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Schepherd resolves a JSON Schema from a pinned OCI catalog, verifies
13
+ it by digest and hands the local file to the validator you already use. The gem
14
+ ships the native schepherd binary for Linux, macOS and Windows on x64 and arm64.
15
+ executables:
16
+ - schepherd
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE
21
+ - README.md
22
+ - THIRD_PARTY_LICENSES.txt
23
+ - bin/schepherd
24
+ - lib/schepherd.rb
25
+ - libexec/schepherd-darwin-arm64/schepherd
26
+ - libexec/schepherd-darwin-x64/schepherd
27
+ - libexec/schepherd-linux-arm64/schepherd
28
+ - libexec/schepherd-linux-x64/schepherd
29
+ - libexec/schepherd-windows-arm64/schepherd.exe
30
+ - libexec/schepherd-windows-x64/schepherd.exe
31
+ homepage: https://schepherd.ovineko.com
32
+ licenses:
33
+ - MIT
34
+ metadata:
35
+ allowed_push_host: https://rubygems.org
36
+ bug_tracker_uri: https://github.com/ovineko/schepherd/issues
37
+ changelog_uri: https://github.com/ovineko/schepherd/releases
38
+ documentation_uri: https://schepherd.ovineko.com
39
+ rubygems_mfa_required: 'true'
40
+ source_code_uri: https://github.com/ovineko/schepherd
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '2.7'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubygems_version: 4.0.20
56
+ specification_version: 4
57
+ summary: Delivers pinned JSON Schemas from an OCI catalog to verified local files
58
+ test_files: []