dgd-tools 0.1.7 → 0.1.8
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 +4 -4
- data/Gemfile.lock +1 -1
- data/exe/dgd-manifest +72 -60
- data/exe/skotos-xml-diff +1 -0
- data/lib/dgd-tools/manifest.rb +61 -20
- data/lib/dgd-tools/skotos_xml_obj.rb +18 -5
- data/lib/dgd-tools/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d608eb777e5e4e39c2d9e08175876de2b7a47f8fc20b775692165d8c46dcd3cd
|
4
|
+
data.tar.gz: c4a833c253ac5c8c191f5d288ae30b3bcb4301371940e524ccd34ce219163f3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c107d368ef11e8742dcb024194bfb1b13ff916d1572589a0adee3ca263618e56eaed34f407f611e175e0332a7591d4ed1d0de6b2fa624c714c4680669ac84769
|
7
|
+
data.tar.gz: 66adf5b5c678361e47ae5dac4d706cabeec768de2b50ff021cb101e2ec008d6fa18a39f567e3617272250240c9c9bab32da50d423397d8ab9064ef2fb6d4f448
|
data/Gemfile.lock
CHANGED
data/exe/dgd-manifest
CHANGED
@@ -1,70 +1,82 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require "optimist"
|
3
4
|
require "dgd-tools/manifest"
|
4
5
|
|
5
|
-
|
6
|
-
ARGV.push "install"
|
7
|
-
end
|
6
|
+
SUB_COMMANDS = %w(new test install update server)
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
OPTS = Optimist::options do
|
9
|
+
version "DGD-tools version #{DGD::VERSION}"
|
10
|
+
banner <<BANNER
|
11
|
+
Use dgd.manifest to assemble your DGD application.
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
dgd
|
13
|
+
Available subcommands:
|
14
|
+
new [project_name]: create a new DGD-manifest project
|
15
|
+
test: make sure the dgd.manifest file is well-formed and usable
|
16
|
+
install: compile the DGD application to a config file and a root directory
|
17
|
+
update: copy files into generated root directory but do *not* clear 'extra' files (e.g. user data)
|
18
|
+
server: run DGD with the generated root and configuration
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
exit
|
20
|
+
Available options:
|
21
|
+
BANNER
|
22
|
+
opt :verbose, "Print verbose output where available"
|
23
|
+
stop_on SUB_COMMANDS
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
when "update"
|
55
|
-
|
56
|
-
|
26
|
+
ARGV.push("install") if ARGV.size == 0
|
27
|
+
cmd = ARGV.shift
|
28
|
+
cmd_opts = case cmd
|
29
|
+
when "test"
|
30
|
+
#Optimist::options do
|
31
|
+
# opt :harsh, "check as exactly as possible"
|
32
|
+
#end
|
33
|
+
|
34
|
+
unless File.exist?("dgd.manifest")
|
35
|
+
raise "I don't see a dgd.manifest file in this directory!"
|
36
|
+
end
|
37
|
+
puts "Running dgd.manifest installer..."
|
38
|
+
repo = DGD::Manifest::Repo.new
|
39
|
+
repo.manifest_file("dgd.manifest")
|
40
|
+
repo.precheck(".", verbose: verbose)
|
41
|
+
puts "Verified Manifest packages: this looks likely correct."
|
42
|
+
|
43
|
+
when "install"
|
44
|
+
unless File.exist?("dgd.manifest")
|
45
|
+
raise "I don't see a dgd.manifest file in this directory!"
|
46
|
+
end
|
47
|
+
puts "Running DGD Manifest installer..."
|
48
|
+
repo = DGD::Manifest::Repo.new
|
49
|
+
repo.manifest_file("dgd.manifest")
|
50
|
+
current_dir = File.expand_path(".")
|
51
|
+
repo.precheck(current_dir)
|
52
|
+
repo.assemble_app(current_dir, verbose: OPTS[:verbose])
|
53
|
+
puts "Assembled DGD application into #{current_dir}"
|
54
|
+
|
55
|
+
when "update"
|
56
|
+
unless File.exist?("dgd.manifest")
|
57
|
+
raise "I don't see a dgd.manifest file in this directory!"
|
58
|
+
end
|
59
|
+
puts "Running DGD Manifest installer..."
|
60
|
+
repo = DGD::Manifest::Repo.new
|
61
|
+
repo.manifest_file("dgd.manifest")
|
62
|
+
current_dir = File.expand_path(".")
|
63
|
+
repo.precheck(current_dir, verbose: OPTS[:verbose])
|
64
|
+
repo.update_app(current_dir, verbose: OPTS[:verbose])
|
65
|
+
puts "Updated DGD application in #{current_dir}"
|
66
|
+
|
67
|
+
when "server"
|
68
|
+
puts "Starting DGD server..."
|
69
|
+
DGD::Manifest.system_call("~/.dgd-tools/dgd/bin/dgd dgd.config")
|
70
|
+
|
71
|
+
when "new"
|
72
|
+
unless ARGV.size == 1
|
73
|
+
puts "Usage: dgd-manifest new [project name]"
|
74
|
+
Optimist::die "Must supply exactly one argument to dgd-manifest new!"
|
75
|
+
end
|
76
|
+
appdir = DGD::Manifest::AppDirectory.new(File.expand_path ARGV[0])
|
77
|
+
appdir.name = ARGV[0]
|
78
|
+
appdir.create!
|
79
|
+
|
80
|
+
else
|
81
|
+
Optimist::die "Unknown subcommand: #{cmd.inspect}"
|
57
82
|
end
|
58
|
-
puts "Running DGD Manifest installer..."
|
59
|
-
repo = DGD::Manifest::Repo.new
|
60
|
-
repo.manifest_file("dgd.manifest")
|
61
|
-
current_dir = File.expand_path(".")
|
62
|
-
repo.precheck(current_dir)
|
63
|
-
repo.update_app(current_dir)
|
64
|
-
puts "Updated DGD application in #{current_dir}"
|
65
|
-
when "server"
|
66
|
-
puts "Starting DGD server..."
|
67
|
-
DGD::Manifest.system_call("~/.dgd-tools/dgd/bin/dgd dgd.config")
|
68
|
-
else
|
69
|
-
raise "Unrecognised #{$0} command: #{ARGV[0].inspect}!"
|
70
|
-
end
|
data/exe/skotos-xml-diff
CHANGED
@@ -14,6 +14,7 @@ Usage:
|
|
14
14
|
skotos-xml-diff [options] <file_or_dir_1> <file_or_dir_2>
|
15
15
|
where [options] are:
|
16
16
|
BANNER
|
17
|
+
opt :version, "Print DGD version and exit"
|
17
18
|
opt :merry_only, "Only diff Merry scripts"
|
18
19
|
opt :ignore_whitespace, "Ignore whitespace in final diff"
|
19
20
|
opt :ignore_types, "Comma-separated list of XML node types to ignore (e.g. Combat:Base,Base:Exit)", type: :string
|
data/lib/dgd-tools/manifest.rb
CHANGED
@@ -22,7 +22,7 @@ module DGD::Manifest
|
|
22
22
|
puts "Running command: #{cmd.inspect}..."
|
23
23
|
system(cmd, out: $stdout, err: :out)
|
24
24
|
unless $?.success?
|
25
|
-
raise "Error running command: #{cmd.inspect}!"
|
25
|
+
raise "Error running command in #{Dir.pwd}: #{cmd.inspect}!"
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -64,19 +64,20 @@ module DGD::Manifest
|
|
64
64
|
raise "Already have a dgd.manifest file!" unless @no_manifest_file
|
65
65
|
|
66
66
|
@no_manifest_file = false
|
67
|
-
@manifest_file ||= AppFile.new(self, path)
|
67
|
+
@manifest_file ||= AppFile.new(self, path, shared_dir: shared_dir)
|
68
68
|
end
|
69
69
|
|
70
70
|
protected
|
71
71
|
|
72
72
|
# This includes files to assemble... But also subdirectories and commands. This format is
|
73
73
|
# unstable and ugly, and should not be exposed to outside parties who might later depend on it.
|
74
|
-
def assembly_operations(location)
|
74
|
+
def assembly_operations(location, verbose:)
|
75
75
|
operations = []
|
76
76
|
|
77
77
|
raise("No manifest file!") if @no_manifest_file
|
78
78
|
|
79
|
-
|
79
|
+
# For each spec, put its dependencies before itself in order
|
80
|
+
@manifest_file.ordered_specs.each do |spec|
|
80
81
|
spec_git_repo = spec.source
|
81
82
|
spec_git_repo.use_details(spec.source_details) # This sets things like checked-out branch
|
82
83
|
|
@@ -125,26 +126,30 @@ module DGD::Manifest
|
|
125
126
|
"#{File.expand_path(location)}/#{GENERATED_ROOT}"
|
126
127
|
end
|
127
128
|
|
128
|
-
def assemble_app(location)
|
129
|
+
def assemble_app(location, verbose:)
|
129
130
|
Dir[File.join(dgd_root(location), "*")].each { |dir| FileUtils.rm_rf dir }
|
130
131
|
|
131
|
-
write_app_files(location)
|
132
|
+
write_app_files(location, verbose: verbose)
|
132
133
|
end
|
133
134
|
|
134
|
-
def update_app(location)
|
135
|
-
write_app_files(location
|
135
|
+
def update_app(location, verbose:)
|
136
|
+
write_app_files(location, verbose: verbose)
|
136
137
|
end
|
137
138
|
|
138
139
|
protected
|
139
140
|
|
140
|
-
def write_app_files(location)
|
141
|
+
def write_app_files(location, verbose:)
|
141
142
|
Dir.chdir(location) do
|
142
143
|
write_config_file("#{location}/dgd.config")
|
143
144
|
FileUtils.mkdir_p("#{location}/state") # Statedir for statedumps, editor files, etc.
|
144
145
|
|
145
|
-
assembly_operations(location).each do |sd_hash|
|
146
|
+
assembly_operations(location, verbose: verbose).each do |sd_hash|
|
146
147
|
to_path = "#{dgd_root(location)}/#{sd_hash[:to]}"
|
147
148
|
|
149
|
+
if verbose
|
150
|
+
puts " Copy #{sd_hash[:from]} -> #{sd_hash[:to]}, files #{sd_hash[:non_dirs].join(", ")}"
|
151
|
+
end
|
152
|
+
|
148
153
|
# Make appropriate dirs, including empty ones
|
149
154
|
sd_hash[:dirs].each do |dir|
|
150
155
|
FileUtils.mkdir_p dir.sub(sd_hash[:from], to_path)
|
@@ -154,8 +159,13 @@ module DGD::Manifest
|
|
154
159
|
sd_hash[:non_dirs].each do |from_file|
|
155
160
|
to_file = from_file.sub(sd_hash[:from], "#{dgd_root(location)}/#{sd_hash[:to]}")
|
156
161
|
to_dir = File.dirname(to_file)
|
157
|
-
|
158
|
-
|
162
|
+
begin
|
163
|
+
FileUtils.mkdir_p to_dir
|
164
|
+
FileUtils.cp from_file, to_file
|
165
|
+
rescue
|
166
|
+
puts "Error when copying: #{from_file} -> #{to_file} in #{sd_hash.inspect}"
|
167
|
+
raise
|
168
|
+
end
|
159
169
|
end
|
160
170
|
end
|
161
171
|
end
|
@@ -163,8 +173,8 @@ module DGD::Manifest
|
|
163
173
|
|
164
174
|
public
|
165
175
|
|
166
|
-
def precheck(location)
|
167
|
-
all_files = assembly_operations(location).flat_map { |sd| sd[:non_dirs] }
|
176
|
+
def precheck(location, verbose:)
|
177
|
+
all_files = assembly_operations(location, verbose: verbose).flat_map { |sd| sd[:non_dirs] }
|
168
178
|
|
169
179
|
if all_files.size != all_files.uniq.size
|
170
180
|
repeated = all_files.uniq.select { |f| all_files.count(f) > 1 }
|
@@ -188,7 +198,7 @@ module DGD::Manifest
|
|
188
198
|
def initialize(repo, git_url)
|
189
199
|
@git_url = git_url
|
190
200
|
@repo = repo
|
191
|
-
local_path = git_url.tr("/\\", "_")
|
201
|
+
local_path = git_url.tr("/\\ ", "_")
|
192
202
|
@local_dir = "#{@repo.shared_dir}/git/#{local_path}"
|
193
203
|
|
194
204
|
if File.directory?(@local_dir)
|
@@ -217,15 +227,18 @@ module DGD::Manifest
|
|
217
227
|
end
|
218
228
|
end
|
219
229
|
|
230
|
+
# This class parses the DGD manifest
|
220
231
|
class AppFile
|
221
232
|
attr_reader :path
|
222
233
|
attr_reader :repo
|
223
234
|
attr_reader :specs
|
224
235
|
attr_reader :dgd_config
|
236
|
+
attr_reader :shared_dir
|
225
237
|
|
226
|
-
def initialize(repo, path)
|
238
|
+
def initialize(repo, path, shared_dir:)
|
227
239
|
@path = path
|
228
240
|
@repo = repo
|
241
|
+
@shared_dir = shared_dir
|
229
242
|
raise("No such dgd.manifest file as #{path.inspect}!") unless File.exist?(path)
|
230
243
|
contents = AppFile.parse_manifest_file(path)
|
231
244
|
|
@@ -279,6 +292,10 @@ module DGD::Manifest
|
|
279
292
|
|
280
293
|
@dgd_config = DGDRuntimeConfig.new (contents["config"] || {})
|
281
294
|
|
295
|
+
if contents["app_root"]
|
296
|
+
raise "App_root must now be inside config block!"
|
297
|
+
end
|
298
|
+
|
282
299
|
if contents["unbundled_goods"]
|
283
300
|
raise "Unbundled_goods must be an array!" unless contents["unbundled_goods"].is_a?(Array)
|
284
301
|
|
@@ -290,7 +307,10 @@ module DGD::Manifest
|
|
290
307
|
|
291
308
|
@specs += contents["goods"].map do |goods_url|
|
292
309
|
begin
|
293
|
-
|
310
|
+
text_contents = URI.open(goods_url).read
|
311
|
+
local_path = shared_dir + "/goods/" + goods_url.tr("/\\ ", "_")
|
312
|
+
File.open(local_path, "wb") { |f| f.write(text_contents) }
|
313
|
+
json_contents = JSON.parse text_contents
|
294
314
|
rescue
|
295
315
|
STDERR.puts "Error reading or parsing by URL: #{goods_url.inspect}"
|
296
316
|
raise
|
@@ -325,21 +345,42 @@ module DGD::Manifest
|
|
325
345
|
# For now, permit a single string as a dependency.
|
326
346
|
fields["dependencies"] = [ fields["dependencies"] ] if fields["dependencies"].is_a?(String)
|
327
347
|
|
348
|
+
goods_url = nil
|
328
349
|
fields["dependencies"].each do |dep|
|
329
350
|
if dep.is_a?(String)
|
330
|
-
|
351
|
+
goods_url = dep
|
331
352
|
elsif dep.is_a?(Hash)
|
332
353
|
raise "Currently only URL-based dependencies on Goods files are supported!" unless dep["url"]
|
333
|
-
|
354
|
+
goods_url = dep["url"]
|
334
355
|
else
|
335
356
|
raise "Unexpected dependency type #{dep.class} when parsing DGD Manifest specs, item: #{dep.inspect}"
|
336
357
|
end
|
358
|
+
|
359
|
+
text_contents = URI.open(goods_url).read
|
360
|
+
local_path = shared_dir + "/goods/" + goods_url.tr("/\\ ", "_")
|
361
|
+
File.open(local_path, "wb") { |f| f.write(text_contents) }
|
362
|
+
dep_fields = JSON.parse text_contents
|
363
|
+
|
364
|
+
dependencies.push unbundled_json_to_spec(dep_fields)
|
337
365
|
end
|
338
366
|
end
|
339
367
|
|
340
368
|
spec = GoodsSpec.new(@repo, name: fields["name"], source: source, source_details: source_details, paths: fields["paths"], dependencies: dependencies)
|
341
369
|
return spec
|
342
370
|
end
|
371
|
+
|
372
|
+
def ordered_specs
|
373
|
+
@specs.flat_map do |s|
|
374
|
+
deps = [s]
|
375
|
+
deps_to_add = s.dependencies
|
376
|
+
while(deps_to_add.size > 0)
|
377
|
+
next_deps = deps_to_add.flat_map { |dep| dep.dependencies }
|
378
|
+
deps = deps_to_add + deps
|
379
|
+
deps_to_add = next_deps
|
380
|
+
end
|
381
|
+
deps
|
382
|
+
end
|
383
|
+
end
|
343
384
|
end
|
344
385
|
|
345
386
|
class GoodsSpec
|
@@ -400,7 +441,7 @@ module DGD::Manifest
|
|
400
441
|
"app_root": "app",
|
401
442
|
"goods": [
|
402
443
|
"# This is an example goods file - substitute your own.",
|
403
|
-
"https://raw.githubusercontent.com/
|
444
|
+
"https://raw.githubusercontent.com/ChatTheatre/dgd-tools/main/goods/skotos_httpd.goods"
|
404
445
|
],
|
405
446
|
"unbundled_goods": [
|
406
447
|
{
|
@@ -46,11 +46,13 @@ class SkotOS::XMLObject
|
|
46
46
|
of1.close
|
47
47
|
of2.close
|
48
48
|
|
49
|
-
diff_opts = [ "
|
50
|
-
diff_opts += [ "
|
49
|
+
diff_opts = [ "c" ]
|
50
|
+
diff_opts += [ "b", "B" ] if self.ignore_whitespace
|
51
51
|
|
52
52
|
# Diff 'fails' if there's a difference between the two files.
|
53
|
-
|
53
|
+
cmd = "diff -#{diff_opts.join("")} #{of1.path} #{of2.path}"
|
54
|
+
#puts "Diff command: #{cmd}"
|
55
|
+
diff = system_call(cmd, fail_ok: true)
|
54
56
|
diff.sub!(of1.path, o1_name)
|
55
57
|
diff.sub!(of2.path, o2_name)
|
56
58
|
ensure
|
@@ -115,11 +117,16 @@ class SkotOS::XMLObject
|
|
115
117
|
end
|
116
118
|
|
117
119
|
rev = noko_single_node(doc.root, "Core:Property", attrs: { "property" => "revisions" })
|
118
|
-
rev
|
120
|
+
noko_remove(rev) if rev
|
119
121
|
|
120
122
|
list = noko_single_node(doc.root, "Core:Property", attrs: { "property" => "#list#" })
|
121
123
|
list.remove if list
|
122
124
|
|
125
|
+
properties = noko_with_name_and_attrs(doc.root, "Core:Property")
|
126
|
+
properties.each do |prop_node|
|
127
|
+
prop_node.remove if prop_node.attribute("property").value.start_with?("sys:sync")
|
128
|
+
end
|
129
|
+
|
123
130
|
if self.merry_only
|
124
131
|
# Kill off all the non-Merry nodes
|
125
132
|
noko_remove_non_merry_nodes(doc.root)
|
@@ -128,7 +135,7 @@ class SkotOS::XMLObject
|
|
128
135
|
if self.ignore_types
|
129
136
|
self.ignore_types.each do |ignored_type|
|
130
137
|
skipped = noko_with_name_and_attrs(doc.root, ignored_type)
|
131
|
-
skipped.each { |n| n
|
138
|
+
skipped.each { |n| noko_remove(n) }
|
132
139
|
end
|
133
140
|
end
|
134
141
|
|
@@ -144,6 +151,12 @@ class SkotOS::XMLObject
|
|
144
151
|
end
|
145
152
|
end
|
146
153
|
|
154
|
+
def self.noko_remove(node)
|
155
|
+
nn = node.next
|
156
|
+
nn.remove if nn.is_a?(Nokogiri::XML::Text)
|
157
|
+
node.remove
|
158
|
+
end
|
159
|
+
|
147
160
|
def self.noko_single_node(node, name, attrs: {})
|
148
161
|
choices = noko_with_name_and_attrs(node, name, attrs)
|
149
162
|
if choices.size < 1
|
data/lib/dgd-tools/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dgd-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Gibbs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|