dorian 2.2.3 → 2.4.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/dorian/bin.rb +258 -5
  4. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 948edb30a0207ae5c1485b8cd59921bab25ab3568164762e2247a9e4cc0394fe
4
- data.tar.gz: c9d46e2f11ff5ce4fb8e7b8a8635f561c5438203e6e8f0cd43e917d1953b6431
3
+ metadata.gz: a0a6f772eca1bab50085d4218db923c9cbb075d199f916b3466b3ef2b3ebcf73
4
+ data.tar.gz: cf651f86c12d4be9321eabd66ce6688c8e9080633c218e05b92ace51159a7002
5
5
  SHA512:
6
- metadata.gz: ff2cee995ee593f169af281234d3d90c136ca31490c6235f37ca1f888519fd169812f1f65d4f2e1d250ffe0718737ba402acd653a5bf6b37791577dd648e029f
7
- data.tar.gz: bfee9345075abe23c4ae2bb508591bc20e78866f01a9e4fbc0255b26af483d671dd6683e7991e8849a689be43b0db604e4744d8d864218d80a01c6dc21782ee5
6
+ metadata.gz: ad150cb4d72cc18cc629bf5a4c4bf5348f89d057b2bdb50cb458bd85a53aadd5bbdfe6e8e3f5861fe754eb81a16d3753c81b6e622d5d63ef4034d25cd6004a76
7
+ data.tar.gz: 7a1d457ad1490a568bfd7627d7d6281057c00c2efc1720cdce96c41b0941290b50fd40ec2cc01c855e5003ab9d89dcf0640674d41c411aa8d049a8f03ac698e6
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.3
1
+ 2.4.0
data/lib/dorian/bin.rb CHANGED
@@ -39,7 +39,8 @@ class Dorian
39
39
  default: true
40
40
  },
41
41
  fast: {
42
- alias: :f
42
+ alias: :f,
43
+ default: true
43
44
  },
44
45
  input: {
45
46
  type: :string,
@@ -50,7 +51,8 @@ class Dorian
50
51
  alias: :o
51
52
  },
52
53
  parallel: {
53
- alias: :p
54
+ alias: :p,
55
+ default: true
54
56
  },
55
57
  parallel_type: {
56
58
  alias: :pt,
@@ -85,7 +87,9 @@ class Dorian
85
87
  alias: :d
86
88
  },
87
89
  progress: :boolean,
88
- headers: :boolean,
90
+ headers: {
91
+ default: true
92
+ },
89
93
  progress_format: {
90
94
  alias: :pf,
91
95
  type: :string
@@ -94,6 +98,7 @@ class Dorian
94
98
  default: true
95
99
  },
96
100
  io: :string,
101
+ self: :boolean,
97
102
  version: {
98
103
  alias: :v
99
104
  },
@@ -177,6 +182,30 @@ class Dorian
177
182
  arguments.delete("commit")
178
183
  @command = :commit
179
184
  command_commit
185
+ when :compare
186
+ arguments.delete("compare")
187
+ @command = :compare
188
+ command_compare
189
+ when :dir
190
+ arguments.delete("dir")
191
+ @command = :dir
192
+ command_dir
193
+ when :submodules
194
+ arguments.delete("submodules")
195
+ @command = :submodules
196
+ command_submodules
197
+ when :dot
198
+ arguments.delete("dot")
199
+ @command = :dot
200
+ command_dot
201
+ when :eval
202
+ arguments.delete("eval")
203
+ @command = :eval
204
+ command_eval
205
+ when :ls
206
+ arguments.delete("ls")
207
+ @command = :ls
208
+ command_ls
180
209
  else
181
210
  arguments.delete("read")
182
211
  @command = :read
@@ -188,6 +217,10 @@ class Dorian
188
217
  parsed.files
189
218
  end
190
219
 
220
+ def command_eval
221
+ each(everything) { |thing| outputs(evaluates(ruby: thing).returned) }
222
+ end
223
+
191
224
  def command_chat
192
225
  puts completion(
193
226
  token: token(".chat"),
@@ -237,6 +270,100 @@ class Dorian
237
270
  read_stdin_files + stdin_arguments + read_files + arguments
238
271
  end
239
272
 
273
+ def command_dir
274
+ puts(
275
+ Git
276
+ .open(".")
277
+ .ls_files
278
+ .map(&:first)
279
+ .map { |path| path.split("/").first }
280
+ .select { |path| Dir.exist?(path) }
281
+ .reject { |path| path.start_with?(".") }
282
+ .sort
283
+ .uniq
284
+ )
285
+
286
+ puts "." if self?
287
+ end
288
+
289
+ def command_ls
290
+ puts(
291
+ Git
292
+ .open(".")
293
+ .ls_files
294
+ .map(&:first)
295
+ .map { |path| path.split("/").first }
296
+ .reject { |path| path.start_with?(".") }
297
+ .select { |path| match_filetypes?(path) }
298
+ .sort
299
+ .uniq
300
+ )
301
+
302
+ puts "." if self?
303
+ end
304
+
305
+ def command_submodules
306
+ puts(
307
+ File
308
+ .read(".gitmodules")
309
+ .lines
310
+ .grep(/path = /)
311
+ .map { |path| path.split("=").last.strip }
312
+ )
313
+
314
+ puts "." if self?
315
+ end
316
+
317
+ def command_dot
318
+ dir = files.first || arguments.first || "."
319
+
320
+ ignore_file = File.expand_path("#{dir.chomp("/")}/.dotignore")
321
+ ignore_content = File.exist?(ignore_file) ? File.read(ignore_file) : ""
322
+ ignore_patterns =
323
+ ignore_content
324
+ .lines
325
+ .map(&:strip)
326
+ .reject { |line| line.empty? || line.start_with?("#") }
327
+ .map { |pattern| Regexp.new("\\A#{pattern}\\z") }
328
+
329
+ Git
330
+ .open(dir)
331
+ .ls_files
332
+ .map(&:first)
333
+ .each do |file|
334
+ next if ignore_patterns.any? { |pattern| pattern.match?(file) }
335
+
336
+ homefile = "#{Dir.home}/#{file}"
337
+ dotfile = File.expand_path("#{dir.chomp("/")}/#{file}")
338
+ File.delete(homefile) if File.exist?(homefile) || File.symlink?(homefile)
339
+ FileUtils.mkdir_p(File.dirname(homefile))
340
+ FileUtils.ln_s(dotfile, homefile, verbose: true)
341
+ end
342
+ end
343
+
344
+ def self?
345
+ !!options.self
346
+ end
347
+
348
+ def command_compare
349
+ file_1, file_2 = files
350
+ key_1, key_2 = arguments
351
+ read_1, read_2 =
352
+ files.map.with_index do |file, index|
353
+ read = reads(File.read(file))
354
+
355
+ if arguments[index] && read.from_deep_struct.key?(arguments[index])
356
+ read[arguments[index]]
357
+ elsif arguments[index]
358
+ nil
359
+ else
360
+ read
361
+ end
362
+ end
363
+
364
+ compare(read_1, read_2, file_1:, file_2:)
365
+ end
366
+
240
367
  def command_each
241
368
  each(everything) do |input|
242
369
  each(lines(reads(input)), progress: true) { |line| evaluates(it: line) }
@@ -260,7 +387,9 @@ class Dorian
260
387
  end
261
388
 
262
389
  def command_all
263
- each(everything, progress: true) { |input| evaluates(it: lines(reads(input))) }
390
+ each(everything, progress: true) do |input|
391
+ evaluates(it: lines(reads(input)))
392
+ end
264
393
  end
265
394
 
266
395
  def command_append
@@ -340,7 +469,7 @@ class Dorian
340
469
  def outputs(content, file: nil)
341
470
  if write? && file
342
471
  File.write(file, to_output(content))
343
- else
472
+ elsif !content.nil?
344
473
  puts to_output(content)
345
474
  end
346
475
  end
@@ -746,6 +875,57 @@ class Dorian
746
875
  http.request(request).body
747
876
  end
748
877
 
878
+ def compare(content_1, content_2, file_1:, file_2:, path: ".")
879
+ content_1 = content_1.from_deep_struct
880
+ content_2 = content_2.from_deep_struct
881
+
882
+ if content_1.is_a?(Hash) && content_2.is_a?(Hash)
883
+ (content_1.keys + content_2.keys).uniq.each do |key|
884
+ new_path = path == "." ? "#{path}#{key}" : "#{path}.#{key}"
885
+
886
+ if content_1[key] && !content_2[key]
887
+ warn "#{new_path} present in #{file_1} but not in #{file_2}"
888
+ next
889
+ elsif !content_1[key] && content_2[key]
890
+ warn "#{new_path} present in #{file_2} but not in #{file_1}"
891
+ next
892
+ end
893
+
894
+ compare(
895
+ content_1[key],
896
+ content_2[key],
897
+ path: new_path,
898
+ file_1:,
899
+ file_2:
900
+ )
901
+ end
902
+ elsif content_1.is_a?(Array) && content_2.is_a?(Array)
903
+ (0...([content_1.size, content_2.size].max)).each do |index|
904
+ new_path = "#{path}[#{index}]"
905
+ if content_1[index] && !content_2[index]
906
+ warn "#{new_path} present in #{file_1} but not in #{file_2}"
907
+ next
908
+ elsif !content_1[index] && content_2[index]
909
+ warn "#{new_path} present in #{file_2} but not in #{file_1}"
910
+ next
911
+ end
912
+
913
+ compare(
914
+ content_1[index],
915
+ content_2[index],
916
+ path: new_path,
917
+ file_1:,
918
+ file_2:
919
+ )
920
+ end
921
+ elsif content_1.class != content_2.class
922
+ warn(
923
+ "#{path} has #{content_1.class} for #{file_1} " \
924
+ "and #{content_2.class} for #{file_2}"
925
+ )
926
+ end
927
+ end
928
+
749
929
  def short(string)
750
930
  string[0..5000]
751
931
  end
@@ -754,6 +934,79 @@ class Dorian
754
934
  Tiktoken.encoding_for_model("gpt-4o")
755
935
  end
756
936
 
937
+ def match_filetypes?(path)
938
+ return true unless arguments.any?
939
+ return true unless arguments.intersect?(["rb", "ruby"])
940
+
941
+ ruby_extensions = %w[
942
+ .rb
943
+ .arb
944
+ .axlsx
945
+ .builder
946
+ .fcgi
947
+ .gemfile
948
+ .gemspec
949
+ .god
950
+ .jb
951
+ .jbuilder
952
+ .mspec
953
+ .opal
954
+ .pluginspec
955
+ .podspec
956
+ .rabl
957
+ .rake
958
+ .rbuild
959
+ .rbw
960
+ .rbx
961
+ .ru
962
+ .ruby
963
+ .schema
964
+ .spec
965
+ .thor
966
+ .watchr
967
+ ]
968
+
969
+ ruby_filenames = %w[
970
+ .irbrc
971
+ .pryrc
972
+ .simplecov
973
+ Appraisals
974
+ Berksfile
975
+ Brewfile
976
+ Buildfile
977
+ Capfile
978
+ Cheffile
979
+ Dangerfile
980
+ Deliverfile
981
+ Fastfile
982
+ Gemfile
983
+ Guardfile
984
+ Jarfile
985
+ Mavenfile
986
+ Podfile
987
+ Puppetfile
988
+ Rakefile
989
+ rakefile
990
+ Schemafile
991
+ Snapfile
992
+ Steepfile
993
+ Thorfile
994
+ Vagabondfile
995
+ Vagrantfile
996
+ buildfile
997
+ ]
998
+
999
+ return false if Dir.exist?(path)
1000
+ return true if ruby_filenames.include?(path)
1001
+ return true if ruby_extensions.include?(File.extname(path))
1002
+ return false unless File.exist?(path)
1003
+
1004
+ first_line =
1005
+ File.open(path, &:gets).to_s.encode("UTF-8", invalid: :replace)
1006
+
1007
+ /\A#!.*ruby\z/.match?(first_line)
1008
+ end
1009
+
757
1010
  def evaluates(
758
1011
  ruby: @ruby,
759
1012
  it: nil,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dorian
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dorian Marié
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-05 00:00:00.000000000 Z
11
+ date: 2024-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: csv
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: ostruct
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: parallel
113
127
  requirement: !ruby/object:Gem::Requirement