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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b3639fa674b53796ffe654f0e7e0deb9506868eece4550b99b4f28b98940e97
4
- data.tar.gz: b0f115747b8f790ba079a9789d18e5bbe024de6e9b1c6cc1c476d21066a1b48a
3
+ metadata.gz: d608eb777e5e4e39c2d9e08175876de2b7a47f8fc20b775692165d8c46dcd3cd
4
+ data.tar.gz: c4a833c253ac5c8c191f5d288ae30b3bcb4301371940e524ccd34ce219163f3a
5
5
  SHA512:
6
- metadata.gz: c739260975e503e32a44bfeaf4775d6693e606f35a247f6d432008d0b9e813ac7b29208d1db641dee46be7aec8bbb86e92c1f8fe7e9c7b1c2aadb2ce93e4fb8e
7
- data.tar.gz: 50cc3537969a52ca379857a8936b900212e18567bdc10c1cb1152cffb7901f88db53b75a04126b8848e0edb3151d74a4514cc3fe02d7c1ae1f0ece0cbbe7d6f3
6
+ metadata.gz: c107d368ef11e8742dcb024194bfb1b13ff916d1572589a0adee3ca263618e56eaed34f407f611e175e0332a7591d4ed1d0de6b2fa624c714c4680669ac84769
7
+ data.tar.gz: 66adf5b5c678361e47ae5dac4d706cabeec768de2b50ff021cb101e2ec008d6fa18a39f567e3617272250240c9c9bab32da50d423397d8ab9064ef2fb6d4f448
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dgd-tools (0.1.7)
4
+ dgd-tools (0.1.8)
5
5
  nokogiri (~> 1.10.5)
6
6
  optimist (~> 3.0.1)
7
7
 
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
- if ARGV.size == 0
6
- ARGV.push "install"
7
- end
6
+ SUB_COMMANDS = %w(new test install update server)
8
7
 
9
- if ARGV == ["--version"]
10
- puts "dgd-tools version #{DGD::VERSION}"
11
- exit
12
- end
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
- if ARGV.size == 1 && ["-h", "--help"].include?(ARGV[0])
15
- puts <<HELP_INFO
16
- dgd-manifest commands:
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
- new [project_name]: create a new DGD-manifest project
19
- test: make sure the dgd.manifest file is well-formed and usable
20
- install: compile the DGD application to a config file and a root directory
21
- HELP_INFO
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
- case ARGV[0]
26
- when "new"
27
- unless ARGV.size == 2
28
- puts "Usage: dgd-manifest new [project name]"
29
- raise "Must supply exactly one argument to dgd-manifest new!"
30
- end
31
- appdir = DGD::Manifest::AppDirectory.new(File.expand_path ARGV[1])
32
- appdir.name = ARGV[1]
33
- appdir.create!
34
- when "test"
35
- unless File.exist?("dgd.manifest")
36
- raise "I don't see a dgd.manifest file in this directory!"
37
- end
38
- puts "Running dgd.manifest installer..."
39
- repo = DGD::Manifest::Repo.new
40
- repo.manifest_file("dgd.manifest")
41
- repo.precheck(".")
42
- puts "Verified Manifest packages: this looks likely correct."
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)
53
- puts "Assembled DGD application into #{current_dir}"
54
- when "update"
55
- unless File.exist?("dgd.manifest")
56
- raise "I don't see a dgd.manifest file in this directory!"
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
@@ -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
- @manifest_file.specs.each do |spec|
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) # TODO: maybe check files dates? Some way to do update-only
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
- FileUtils.mkdir_p to_dir
158
- FileUtils.cp from_file, to_file
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
- json_contents = JSON.parse(URI.open(goods_url).read)
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
- dependencies.push "url" => dep
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
- dependencies.push dep
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/noahgibbs/dgd-tools/main/goods/skotos_httpd.goods"
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 = [ "-c" ]
50
- diff_opts += [ "-w", "-B" ] if self.ignore_whitespace
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
- diff = system_call("diff #{diff_opts.join(" ")} #{of1.path} #{of2.path}", fail_ok: true)
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.remove if 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.remove }
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
@@ -1,3 +1,3 @@
1
1
  module DGD
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
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.7
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-03 00:00:00.000000000 Z
11
+ date: 2021-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri