dgd-tools 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
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