dgd-tools 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2637c36239c1aabf37dbac03f0404cab8bb2ea493753bebc2710d44e03f78e11
4
+ data.tar.gz: f544c13905cceb2c080385edc9122a4b89905700ac8195b97410ae58d829e5b6
5
+ SHA512:
6
+ metadata.gz: ce3e707b25251764367464866d71c64ece85e69cb8c39d2589d3342f263f9ba3c98270d3f130c05b481fac04d0c06e613d9992b87ab54bf99851e3fcd98ebc58
7
+ data.tar.gz: 41acb15b29ca4667590ca59cace0a5563f1129845d205c32dbe662f6222aad9c174a09548e98f0e0b450c63b3e073cb5baa614eddbe390ab9e4084f1a8ca9e7d
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.gem
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.0
6
+ before_install: gem install bundler -v 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dgd-tools.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "minitest", "~> 5.0"
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dgd-tools (0.1.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.14.2)
10
+ rake (12.3.3)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ dgd-tools!
17
+ minitest (~> 5.0)
18
+ rake (~> 12.0)
19
+
20
+ BUNDLED WITH
21
+ 2.1.2
@@ -0,0 +1,95 @@
1
+ # DGD Tools
2
+
3
+ DGD Tools is a repository of Ruby tools designed to make the DGD interpreter easier to use. DGD started as an interpreter for a dialect of LPC, the C-like language of LPMuds. It has drifted over the years into a powerful general-purpose dynamic language.
4
+
5
+ DGD Tools requires Ruby. It comes preinstalled on recent Mac computers, or you can install it yourself on Linux. On Windows, if you're not using WSL or similar, you're going to have a less-than-optimal experience.
6
+
7
+ ## DGD Manifest
8
+
9
+ DGD Manifest is an experimental library system for [DGD](https://github.com/dworkin/LPC). I don't actually know of a second attempt to set up a library system for it. DGD Manifest is inspired loosely by RubyGems and the Ruby [Bundler](https://bundler.io).
10
+
11
+ DGD Manifest refers to its libraries as Goods. The file dgd.manifest, if it's present in your application's directory, specifies where and how to find its various libraries. By running "dgd-manifest install", you can install those various files into a complete application.
12
+
13
+ DGD Manifest is a simple initial library system. I'm sure I'll figure more out as I go along, and I'm sure it'll need changes. But you have to start somewhere!
14
+
15
+ This work has grown out of [SkotOS and ChatTheatre](https://github.com/ChatTheatre) tasks.
16
+
17
+ ## Installation
18
+
19
+ You would normally install DGDTools directly: `gem install dgd-tools`.
20
+
21
+ It's possible to add it to a Ruby's application's Gemfile. Ordinarily you wouldn't.
22
+
23
+ ## Usage
24
+
25
+ If you have a DGD application that uses DGD Manifest, run `dgd-manifest install` to download its dependencies and create a fully-assembled DGD directory for it. You can also `dgd-manifest test` to make sure its dependencies are downloaded and satisfied without building an application directory.
26
+
27
+ That fully-assembled DGD directory is named ".root". To run your dgd server, type "dgd-manifest server".
28
+
29
+ ## Using DGD Manifest with your DGD Application
30
+
31
+ Your app will need a dgd.manifest file, which is a lot like NPM's package.json file.
32
+
33
+ Here's an example:
34
+
35
+ ```
36
+ {
37
+ "name": "eOS",
38
+ "version": "1.0.0",
39
+ "description": "A game platform from the folks at ChatTheatre",
40
+ "app_root": "root",
41
+ "goods": [
42
+ "https://raw.githubusercontent.com/noahgibbs/dgd-tools/main/goods/skotos_httpd.goods"
43
+ ],
44
+ "unbundled_goods": [
45
+ {
46
+ "name": "kernellib",
47
+ "git": {
48
+ "url": "https://github.com/dworkin/cloud-server.git",
49
+ "branch": "master"
50
+ },
51
+ "paths": {
52
+ "src/doc/kernel": "doc/kernel",
53
+ "src/include/kernel": "include/kernel",
54
+ "src/kernel": "kernel"
55
+ }
56
+ }
57
+ ]
58
+ }
59
+ ```
60
+
61
+ DGD Manifest needs a .goods file for each of your dependencies - or it needs the equivalent of that .goods file, in the form of unbundled_goods. That one line in "goods" is basically the same information in unbundled_goods, just stored at a URL that DGD Manifest can download for you.
62
+
63
+ A Manifest-enabled DGD codebase can provide Goods files directly and you can use them by their URLs. A non-Manifest codebase may require you to create your own .goods files, or use them directly and unbundled in the dgd.manifest file for your app.
64
+
65
+ ## Creating the Goods
66
+
67
+ To create a new Manifest-usable library, you'll want to create a Goods file for it.
68
+
69
+ Here's what those look like:
70
+
71
+ ```
72
+ {
73
+ "name": "SkotOS HTTPD",
74
+ "git": {
75
+ "url": "https://github.com/ChatTheatre/SkotOS.git"
76
+ },
77
+ "paths": {
78
+ "skoot/usr/HTTP": "usr/HTTP"
79
+ }
80
+ }
81
+ ```
82
+
83
+ ## Development
84
+
85
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
86
+
87
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
88
+
89
+ ## Contributing
90
+
91
+ Bug reports and pull requests are welcome on GitHub at https://github.com/noahgibbs/dgd-tools.
92
+
93
+ ## License
94
+
95
+ The gem is available as open source under the terms of the AGPL.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dgd-tools/manifest"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,26 @@
1
+ require_relative 'lib/dgd-tools/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "dgd-tools"
5
+ spec.version = DGD::VERSION
6
+ spec.authors = ["Noah Gibbs"]
7
+ spec.email = ["the.codefolio.guy@gmail.com"]
8
+
9
+ spec.summary = %q{dgd-tools supplies DGD tools -- like the DGD Manifest library system -- via a Ruby gem.}
10
+ spec.description = %q{dgd-tools supplies DGD Manifest and eventually perhaps other tools. DGD Manifest is an experimental DGD library and packaging system.}
11
+ spec.homepage = "https://github.com/noahgibbs/dgd-tools"
12
+ spec.license = "AGPL"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+
15
+ spec.metadata["homepage_uri"] = spec.homepage
16
+ spec.metadata["source_code_uri"] = spec.homepage
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ end
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "dgd-tools/manifest"
4
+
5
+ if ARGV.size == 0
6
+ ARGV.push "install"
7
+ end
8
+
9
+ case ARGV[0]
10
+ when "test"
11
+ unless File.exist?("dgd.manifest")
12
+ raise "I don't see a dgd.manifest file in this directory!"
13
+ end
14
+ puts "Running dgd.manifest installer..."
15
+ repo = DGD::Manifest::Repo.new
16
+ repo.manifest_file("dgd.manifest")
17
+ puts "Verified Manifest packages: this looks likely correct."
18
+ when "install"
19
+ unless File.exist?("dgd.manifest")
20
+ raise "I don't see a dgd.manifest file in this directory!"
21
+ end
22
+ puts "Running DGD Manifest installer..."
23
+ repo = DGD::Manifest::Repo.new
24
+ repo.manifest_file("dgd.manifest")
25
+ repo.assemble_app(".")
26
+ when "server"
27
+ puts "Starting DGD server... (not yet)"
28
+ else
29
+ raise "Unrecognised #{$0} command: #{ARGV[0].inspect}!"
30
+ end
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "SkotOS HTTPD",
3
+ "git": {
4
+ "url": "https://github.com/ChatTheatre/SkotOS.git",
5
+ "branch": "master"
6
+ },
7
+ "paths": {
8
+ "skoot/usr/HTTP": "usr/HTTP"
9
+ }
10
+ }
@@ -0,0 +1,276 @@
1
+ require "dgd-tools/version"
2
+
3
+ require "json"
4
+ require "open-uri"
5
+ require "fileutils"
6
+
7
+ module DGD; end
8
+
9
+ module DGD::Manifest
10
+ DGD_BUILD_COMMAND = %(make DEFINES='-DUINDEX_TYPE="unsigned int" -DUINDEX_MAX=UINT_MAX -DEINDEX_TYPE="unsigned short" -DEINDEX_MAX=USHRT_MAX -DSSIZET_TYPE="unsigned int" -DSSIZET_MAX=1048576' install
11
+ )
12
+ KERNEL_PATHS = ["include/kernel", "kernel"]
13
+ DEFAULT_KERNELLIB_URL = "https://github.com/ChatTheatre/kernellib"
14
+
15
+ GENERATED_ROOT = ".root"
16
+
17
+ def self.system_call(cmd)
18
+ puts "Running command: #{cmd.inspect}..."
19
+ system(cmd, out: $stdout, err: :out)
20
+ unless $?.success?
21
+ raise "Error running command: #{cmd.inspect}!"
22
+ end
23
+ end
24
+
25
+ # This is a repo of everything DGD Manifest saves between runs.
26
+ # It includes downloaded Git repos, Goods files and more.
27
+ class Repo
28
+ attr_reader :manifest_dir
29
+
30
+ def initialize
31
+ @home = ENV["HOME"]
32
+ @manifest_dir = "#{@home}/.dgd-tools"
33
+ Dir.mkdir(@manifest_dir) unless File.directory?(@manifest_dir)
34
+ ["git", "goods"].each do |subdir|
35
+ full_subdir = "#{@manifest_dir}/#{subdir}"
36
+ Dir.mkdir(full_subdir) unless File.directory?(full_subdir)
37
+ end
38
+
39
+ unless File.exist?("#{@manifest_dir}/dgd/bin/dgd")
40
+ dgd_dir = "#{@manifest_dir}/dgd"
41
+ if File.directory?(dgd_dir)
42
+ # Not clear to me what to do here...
43
+ else
44
+ DGD::Manifest.system_call("git clone https://github.com/ChatTheatre/dgd.git #{dgd_dir}")
45
+ Dir.chdir("#{@manifest_dir}/dgd/src") do
46
+ DGD::Manifest.system_call(DGD_BUILD_COMMAND)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def git_repo(git_url)
53
+ @git_repos ||= {}
54
+ @git_repos[git_url] ||= GitRepo.new(self, git_url)
55
+ end
56
+
57
+ def manifest_file(path)
58
+ raise "Already have a dgd.manifest file!" if @manifest_file
59
+
60
+ @manifest_file ||= AppFile.new(self, path)
61
+ end
62
+
63
+ def assemble_app(location)
64
+ dgd_root = "#{File.expand_path(location)}/#{GENERATED_ROOT}"
65
+ app_path = "#{File.expand_path(location)}/#{@manifest_file.app_root}"
66
+ FileUtils.rm_rf(dgd_root)
67
+ FileUtils.cp_r(app_path, dgd_root)
68
+
69
+ write_config_file("#{location}/dgd.config")
70
+ specs = @manifest_file.specs
71
+
72
+ specs.each do |spec|
73
+ git_repo = spec.source
74
+ git_repo.use_details(spec.source_details)
75
+
76
+ spec.paths.each do |from, to|
77
+ from_path = "#{git_repo.local_dir}/#{from}"
78
+ to_path = "#{dgd_root}/#{to}"
79
+ to_dir = to_path.split("/")[0..-2].join("/")
80
+ FileUtils.mkdir_p to_dir
81
+ STDERR.puts "COPYING #{from_path.inspect} #{to_path.inspect}"
82
+ FileUtils.cp_r(from_path, to_path)
83
+ end
84
+ end
85
+ end
86
+
87
+ def write_config_file(path)
88
+ File.open(path, "wb") do |f|
89
+ f.write <<CONTENTS
90
+ /* These are SkotOS limits. They are enormous. They should
91
+ be configurable but they are not yet. */
92
+ telnet_port = ([
93
+ "*":50100 /* telnet port number */
94
+ ]);
95
+ binary_port = ([
96
+ "*":50110, /* Failsafe */
97
+ ]); /* binary ports */
98
+ directory = "./#{GENERATED_ROOT}";
99
+
100
+ users = 100; /* max # of users */
101
+ editors = 40; /* max # of editor sessions */
102
+ ed_tmpfile = "../state/ed"; /* proto editor tmpfile */
103
+ swap_file = "../state/swap"; /* swap file */
104
+ swap_size = 1048576; /* # sectors in swap file */
105
+ sector_size = 512; /* swap sector size */
106
+ swap_fragment = 4096; /* fragment to swap out */
107
+ static_chunk = 64512; /* static memory chunk */
108
+ dynamic_chunk = 261120; /* dynamic memory chunk */
109
+ dump_file = "../state/dump"; /* dump file */
110
+ dump_interval = 3600; /* dump interval */
111
+
112
+ typechecking = 2; /* highest level of typechecking */
113
+ include_file = "/include/std.h"; /* standard include file */
114
+ include_dirs = ({ "/include", "~/include" }); /* directories to search */
115
+ auto_object = "/kernel/lib/auto"; /* auto inherited object */
116
+ driver_object = "/kernel/sys/driver"; /* driver object */
117
+ create = "_F_create"; /* name of create function */
118
+
119
+ array_size = 16384; /* max array size */
120
+ objects = 262144; /* max # of objects */
121
+ call_outs = 16384; /* max # of call_outs */
122
+ CONTENTS
123
+ end
124
+ end
125
+ end
126
+
127
+ # This is a Git repo managed by dgd-tools.
128
+ # It can be a source for a GoodsSpec
129
+ class GitRepo
130
+ attr_reader :local_dir
131
+ attr_reader :git_url
132
+
133
+ def initialize(repo, git_url)
134
+ @git_url = git_url
135
+ @repo = repo
136
+ local_path = git_url.tr("/\\", "_")
137
+ @local_dir = "#{@repo.manifest_dir}/git/#{local_path}"
138
+
139
+ if File.directory?(@local_dir)
140
+ Dir.chdir(@local_dir) do
141
+ DGD::Manifest.system_call("git checkout #{default_branch} && git pull")
142
+ end
143
+ else
144
+ DGD::Manifest.system_call("git clone #{@git_url} #{@local_dir}")
145
+ end
146
+ end
147
+
148
+ def default_branch
149
+ return @default_branch if @default_branch
150
+ output = `git rev-parse --abbrev-ref origin/HEAD`.chomp
151
+ @default_branch = output.gsub(/^origin\//, "")
152
+ end
153
+
154
+ def use_details(details)
155
+ if details["branch"]
156
+ Dir.chdir(@local_dir) do
157
+ DGD::Manifest.system_call("git checkout #{details["branch"]}")
158
+ end
159
+ else
160
+ Dir.chdir(@local_dir) do
161
+ DGD::Manifest.system_call("git checkout #{default_branch}")
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ class AppFile
168
+ attr_reader :path
169
+ attr_reader :repo
170
+ attr_reader :specs
171
+ attr_reader :app_root
172
+
173
+ def initialize(repo, path)
174
+ @path = path
175
+ @repo = repo
176
+ raise("No such dgd.manifest file as #{path.inspect}!") unless File.exist?(path)
177
+ contents = JSON.load(File.read(path))
178
+
179
+ read_manifest_file(contents)
180
+
181
+ @app_root = contents["app_root"] || "app"
182
+
183
+ output_paths = @specs.flat_map { |s| s.paths.values }
184
+ unless output_paths == output_paths.uniq
185
+ repeated_paths = output_paths.select { |p| output_paths.count(p) > 1 }
186
+ raise "Repeated (conflicting?) paths in dgd.manifest! #{repeated_paths.inspect}"
187
+ end
188
+
189
+ # Make sure the dgd.manifest file overrides either no kernel paths or both/all
190
+ if KERNEL_PATHS.any? { |kp| output_paths.include?(kp) }
191
+ unless KERNEL_PATHS.all? { |kp| output_paths.include?(kp) }
192
+ raise "dgd.manifest file #{path.inspect} includes some Kernel Library paths but not all! All needed: #{KERNEL_PATHS}!"
193
+ end
194
+ puts "This dgd.manifest file overrides the Kernel Library with its own."
195
+ else
196
+ puts "This dgd.manifest needs the default Kernel Library."
197
+ # This app has specified no kernellib paths -- add them
198
+ git_repo = @repo.git_repo(DEFAULT_KERNELLIB_URL)
199
+ kl_paths = { "src/kernel" => "/kernel", "src/include/kernel" => "/include/kernel", "src/doc/kernel" => "/doc/kernel" }
200
+ klib_spec = GoodsSpec.new @repo, name: "default Kernel Library",
201
+ source: git_repo, paths: kl_paths
202
+ specs.push klib_spec
203
+ end
204
+
205
+ nil
206
+ end
207
+
208
+ def read_manifest_file(contents)
209
+ raise "Expected a top-level JSON object in dgd.manifest!" unless contents.is_a?(Hash)
210
+
211
+ @specs = []
212
+
213
+ if contents["unbundled_goods"]
214
+ raise "Unbundled_goods must be an array!" unless contents["unbundled_goods"].is_a?(Array)
215
+
216
+ @specs += contents["unbundled_goods"].map { |item| unbundled_json_to_spec(item) }
217
+ end
218
+
219
+ if contents["goods"]
220
+ raise "Goods must be an array!" unless contents["goods"].is_a?(Array)
221
+
222
+ @specs += contents["goods"].map do |goods_url|
223
+ begin
224
+ json_contents = JSON.parse(URI.open(goods_url).read)
225
+ rescue
226
+ STDERR.puts "Error reading or parsing by URL: #{goods_url.inspect}"
227
+ raise
228
+ end
229
+ unbundled_json_to_spec(json_contents)
230
+ end
231
+ end
232
+ end
233
+
234
+ def unbundled_json_to_spec(fields)
235
+ source = nil
236
+ source_details = nil
237
+ if fields["git"]
238
+ raise "A git source requires a git url: #{fields.inspect}!" unless fields["git"]["url"]
239
+ source = @repo.git_repo(fields["git"]["url"])
240
+ source_details = fields["git"] # May contain branch info, etc.
241
+ else
242
+ raise "DGD Manifest currently requires a Git-based source!"
243
+ end
244
+
245
+ unless fields["paths"].all? { |k, v| k.is_a?(String) && v.is_a?(String) }
246
+ raise "Paths in Goods files must map strings to strings! #{fields["paths"].inspect}"
247
+ end
248
+
249
+ spec = GoodsSpec.new(@repo, name: fields["name"], source: source, source_details: source_details, paths: fields["paths"])
250
+ return spec
251
+ end
252
+ end
253
+
254
+ class GoodsSpec
255
+ attr_reader :repo
256
+ attr_reader :name
257
+ attr_reader :source
258
+ attr_reader :source_details
259
+ attr_reader :paths
260
+
261
+ def initialize(repo, name:, source:, source_details: {}, paths:)
262
+ @repo = repo
263
+ @name = name
264
+ @source = source
265
+ @source_details = source_details
266
+
267
+ cleaned_paths = {}
268
+ paths.each do |k, v|
269
+ # Remove leading and trailing slashes
270
+ cleaned_paths[k.gsub(/^\//, "").chomp("/")] = v.gsub(/^\//, "").chomp("/")
271
+ end
272
+
273
+ @paths = cleaned_paths
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,3 @@
1
+ module DGD
2
+ VERSION = "0.1.1"
3
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dgd-tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Noah Gibbs
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-10-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: dgd-tools supplies DGD Manifest and eventually perhaps other tools. DGD
14
+ Manifest is an experimental DGD library and packaging system.
15
+ email:
16
+ - the.codefolio.guy@gmail.com
17
+ executables:
18
+ - dgd-manifest
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - ".gitignore"
23
+ - ".travis.yml"
24
+ - Gemfile
25
+ - Gemfile.lock
26
+ - README.md
27
+ - Rakefile
28
+ - bin/console
29
+ - bin/setup
30
+ - dgd-tools.gemspec
31
+ - exe/dgd-manifest
32
+ - goods/skotos_httpd.goods
33
+ - lib/dgd-tools/manifest.rb
34
+ - lib/dgd-tools/version.rb
35
+ homepage: https://github.com/noahgibbs/dgd-tools
36
+ licenses:
37
+ - AGPL
38
+ metadata:
39
+ homepage_uri: https://github.com/noahgibbs/dgd-tools
40
+ source_code_uri: https://github.com/noahgibbs/dgd-tools
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 2.3.0
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubygems_version: 3.1.2
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: dgd-tools supplies DGD tools -- like the DGD Manifest library system -- via
60
+ a Ruby gem.
61
+ test_files: []