sumire 24.03.30 → 24.04.03

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/exe/sumire +56 -28
  3. data/lib/sumire/version.rb +25 -1
  4. data/lib/sumire.rb +55 -13
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c16de0e198ae8999524f348b21c2795b12fbaadb35d889b4396e8ac7b3741ee9
4
- data.tar.gz: fac8e873d7eca4cbbbcb79533befddd719f34708b43ecce6390f28498b361764
3
+ metadata.gz: 163fa9383b3591e43b8f8d3cb814bd7b44c2037ffce0c92c49be26c1c4dbf238
4
+ data.tar.gz: 737005aa5b6552b7734294c754f4b68284ae77ddc296194d9f7f20cc2fab2fa9
5
5
  SHA512:
6
- metadata.gz: e324b6edcef778c876ab4e9575bdca84828cac1fdd8a5c71aebf00cada46b00eca81f4f659430f8d732eda1e1d604da8a0a0bcdbc803daedb6ce309c9da9bacc
7
- data.tar.gz: 8fff912fd5b8f2f9bc30533de3db975d4488eadb48b3b27f07af12135a49854df125b272e6b06ff6012982d5b3d1aee157038d496b39ec27fb314d571e08ade2
6
+ metadata.gz: e3baf3169714078dbbec1955c6daa676c47e62817f860db115ccf31d2333780eea5fac79459eb841af67ebb488c2d22462ca2bdf93dda542a4fa51eb95a9517d
7
+ data.tar.gz: 5a914c0381618108d77c6c3e575debc97c9d8a09c72a75b372a965032b2ed6eeb0662995872d60b0072d307c50f5de502fa8d4694b1ed238d7dbc529ac71c6f3
data/exe/sumire CHANGED
@@ -5,6 +5,8 @@ require "sumire"
5
5
  require "listen"
6
6
  require "optparse"
7
7
  require "sys/proctable"
8
+ require "securerandom"
9
+ require "fileutils"
8
10
 
9
11
  @i18n = {
10
12
  "en": {
@@ -17,7 +19,11 @@ require "sys/proctable"
17
19
  "EOR": "\e[31;1m■ End of record\e[0m",
18
20
  "specify_dir": "Specify the directory",
19
21
  "no_directory": "\e[31mDirectory does not exist\e[0m",
20
- "save_to": "Save to: "
22
+ "save_to": "Save to: ",
23
+ "version_info": "Display version information",
24
+ "arg_command": "Run the command rather than an interactive shell",
25
+ "license_info": "Displays license information",
26
+ "legacy": "Enable legacy mode"
21
27
  },
22
28
  "ja": {
23
29
  "arg_less_one": "引数の個数は 1 個以下でなければなりません",
@@ -29,7 +35,11 @@ require "sys/proctable"
29
35
  "EOR": "\e[31;1m■ 記録を終了します\e[0m",
30
36
  "specify_dir": "ディレクトリを指定します",
31
37
  "no_directory": "\e[31mディレクトリが存在しません\e[0m",
32
- "save_to": "保存先: "
38
+ "save_to": "保存先: ",
39
+ "version_info": "バージョン情報を表示します",
40
+ "arg_command": "コマンドではなくシェルを実行します",
41
+ "license_info": "ソフトウェアのライセンス情報を表示します",
42
+ "legacy": "レガシーモードを有効にします"
33
43
  }
34
44
  }
35
45
 
@@ -39,57 +49,75 @@ def comment(tag)
39
49
  @i18n[lang][tag]
40
50
  end
41
51
 
42
- def main(**kwargs) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
52
+ # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity, Lint/MissingCopEnableDirective
53
+ def main(**kwargs)
43
54
  dir = kwargs[:directory]
44
55
  dir = "." if dir.nil? || dir.empty?
45
56
  dir = dir.sub(%r{/\z}, "")
46
57
 
47
- processes = Sys::ProcTable.ps
48
- processes.each do |process|
49
- next unless process.cmdline.match(/^script/)
58
+ command = kwargs[:command]
59
+ command = command ? " -c \"#{command}\"" : ""
50
60
 
51
- warn("#{comment(:exist_process)}\n\n")
52
- warn("\e[32mkill #{process.pid}\e[0m")
53
- exit(false)
54
- end
61
+ verbose = kwargs[:verbose] || false
62
+ legacy = kwargs[:legacy] || false
55
63
 
64
+ dst = "#{dir}/#{Time.now.strftime("%Y%m%d_%H%M%S")}.log"
65
+ dst = File.expand_path(dst)
56
66
  print(comment(:save_to))
57
- puts("#{dir}/#{Time.now.strftime("%Y%m%d_%H%M%S")}.log")
67
+ puts(dst)
58
68
  puts(comment(:start_recording))
59
- system("sumire -m #{dir}& script -f")
69
+
70
+ tmp = "/tmp/sumire/#{SecureRandom.uuid}/typescript"
71
+ tmp = Pathname(Dir.pwd).join("typescript").to_path if verbose
72
+ FileUtils.mkdir_p(Pathname(tmp).dirname.to_path)
73
+ thread = Thread.new do
74
+ Sumire::Sumire.exec(destination: dst, target: tmp, verbose: verbose, legacy: legacy)
75
+ end
76
+ thread.join if verbose
77
+
78
+ script_cmd = "script -q -f #{tmp}#{command}"
79
+ system(script_cmd) unless verbose
80
+
60
81
  puts(comment(:EOR))
61
82
  end
62
83
 
63
84
  opt = OptionParser.new
85
+ verbose = false
86
+ legacy = false
87
+ dir = "."
88
+ cmd = nil
64
89
 
65
- opt.on("-v", "--verbose", comment(:output_log)) do |_v|
66
- Sumire::Sumire.exec(verbose: true)
90
+ opt.on("-V", "--version", comment(:version_info)) do |_v|
91
+ puts("#{File.basename($PROGRAM_NAME)} (#{Sumire::VERSION})")
67
92
  exit(true)
68
93
  end
69
94
 
70
- opt.on("-m [Directory]", "--monitor", comment(:save_log)) do |dir|
71
- Sumire::Sumire.exec(directory: dir)
95
+ opt.on("--license", comment(:license_info)) do |_v|
96
+ puts(Sumire::COPYRIGHT)
72
97
  exit(true)
73
98
  end
74
99
 
75
- opt.on("-d [Directory]", "--directory [Directory]", comment(:specify_dir)) do |dir|
76
- if dir.nil?
77
- dir = ""
78
- elsif !Dir.exist?(dir)
79
- warn(comment(:no_directory))
80
- exit(false)
81
- end
82
- main(directory: dir)
83
- exit(true)
100
+ opt.on("-v", "--verbose", comment(:output_log)) do |v|
101
+ verbose = v
84
102
  end
85
103
 
86
- opt.on("") do |_v|
87
- main
88
- exit(true)
104
+ opt.on("-c [Command]", "--command", comment(:arg_command)) do |command|
105
+ cmd = command
106
+ end
107
+
108
+ opt.on("-d [Directory]", "--directory", comment(:specify_dir)) do |directory|
109
+ dir = directory
110
+ end
111
+
112
+ opt.on("-l", "--legacy", comment(:legacy)) do |_v|
113
+ legacy = true
89
114
  end
90
115
 
91
116
  begin
92
117
  opt.parse!(ARGV)
93
118
  rescue OptionParser::InvalidOption
94
119
  warn(comment(:option_not_appropriate))
120
+ exit(false)
95
121
  end
122
+
123
+ main(directory: dir, verbose: verbose, command: cmd, legacy: legacy)
@@ -1,5 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sumire
4
- VERSION = "24.03.30"
4
+ VERSION = "24.04.03"
5
+
6
+ COPYRIGHT = <<~COPYRIGHT_TEXT
7
+ The MIT License (MIT)
8
+
9
+ Copyright (c) 2024 MURATA Mitsuharu
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in
19
+ all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
+ THE SOFTWARE.
28
+ COPYRIGHT_TEXT
5
29
  end
data/lib/sumire.rb CHANGED
@@ -2,30 +2,68 @@
2
2
 
3
3
  require_relative "sumire/version"
4
4
  require "ansi2txt"
5
+ require "fileutils"
5
6
 
6
7
  module Sumire
7
8
  class Error < StandardError; end
8
9
 
9
10
  class Sumire # rubocop:disable Style/Documentation
10
- class << self
11
- attr_accessor :directory
11
+ def self.remove_cr(text) # rubocop:disable Metrics/MethodLength
12
+ chars = text.bytes
13
+ remove_cr_chars = [0] * chars.length
14
+ idx = 0
15
+ chars.map do |chr|
16
+ if chr.eql?(8)
17
+ idx -= 1
18
+ next
19
+ end
20
+
21
+ if chr.eql?(13)
22
+ idx = 0
23
+ next
24
+ end
25
+ remove_cr_chars[idx] = chr
26
+ idx += 1
27
+ end
28
+ remove_cr_chars.filter { |e| e != 0 }.pack("C*")
29
+ end
30
+
31
+ def self.remove_crs(text, mode: false) # rubocop:disable Metrics/MethodLength
32
+ if mode
33
+ begin
34
+ text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "")
35
+ text = text.encode!("UTF-8", "UTF-16")
36
+ text = text.gsub(/\r+/, "\r").gsub(/\r+\n\r+/, "\n").gsub("\r", "\n") if mode
37
+ rescue StandardError
38
+ nil
39
+ end
40
+ return text
41
+ end
42
+
43
+ text.split("\n").map { |e| remove_cr(e) }.join("\n")
12
44
  end
13
45
 
14
46
  # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity, Lint/MissingCopEnableDirective
15
47
  def self.exec(**kwargs)
16
- directory = kwargs[:directory]
17
- directory = "." if directory.nil?
48
+ legacy = kwargs[:legacy] || false
49
+ destination = kwargs[:destination]
50
+ if destination.nil?
51
+ uuid = SecureRandom.uuid
52
+ FileUtils.mkdir_p("/tmp/sumire/#{uuid}")
53
+ destination = "/tmp/sumire/#{uuid}/typescript"
54
+ end
18
55
  target = kwargs[:target]
19
56
  target = "typescript" if target.nil?
20
57
  verbose = kwargs[:verbose] || false
21
58
  old_lines = 0
22
59
  list = []
23
60
  old_text = ""
24
- start_time = Time.now.strftime("%Y%m%d_%H%M%S")
61
+
62
+ listen_dir = File.dirname(target)
25
63
 
26
64
  # rubocop:disable Metrics/BlockLength
27
- listener = Listen.to(".") do |modified, _added, _removed|
28
- if modified.map { |file| File.basename(file) }.include?(target)
65
+ listener = Listen.to(listen_dir) do |modified, _added, _removed|
66
+ if modified.include?(target)
29
67
  input = File.open(target)
30
68
 
31
69
  # txt: string
@@ -33,16 +71,22 @@ module Sumire
33
71
 
34
72
  # Add target text
35
73
  add_line_txt = txt[old_text.size...-1]
74
+ add_line_txt = remove_crs(add_line_txt, mode: legacy)
36
75
 
37
76
  regex = /Script\sdone\son\s\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\+\d{2}:\d{2}\s\[COMMAND_EXIT_CODE="\d+"\]/
38
- exit if !add_line_txt.nil? && add_line_txt.match(regex)
77
+ begin
78
+ match = add_line_txt.encode("utf-8", "utf-8").match(regex)
79
+ exit if !add_line_txt.nil? && match
80
+ rescue ArgumentError
81
+ nil
82
+ end
39
83
  next if add_line_txt.nil?
40
84
 
41
- add_line = add_line_txt.gsub("\n\r", "\n").lines.map(&:chomp).map do |line|
85
+ add_line = add_line_txt.lines.map(&:chomp).map do |line|
42
86
  time = Time.now.strftime("%Y-%m-%d %H:%M:%S")
43
87
  "[#{time}] #{line}"
44
88
  end
45
- add_line_color = add_line_txt.gsub("\n\r", "\n").lines.map(&:chomp).map do |line|
89
+ add_line_color = add_line_txt.lines.map(&:chomp).map do |line|
46
90
  time = Time.now.strftime("%Y-%m-%d %H:%M:%S")
47
91
  "\e[32m[#{time}]\e[0m #{line}"
48
92
  end
@@ -54,7 +98,7 @@ module Sumire
54
98
  if old_lines < new_lines
55
99
  add_line.each do |line|
56
100
  list.append(line)
57
- File.open("#{directory}/#{start_time}.log", "a") do |f|
101
+ File.open(destination, "a") do |f|
58
102
  f.puts(line)
59
103
  end
60
104
  end
@@ -64,10 +108,8 @@ module Sumire
64
108
  puts(line)
65
109
  end
66
110
  end
67
-
68
111
  old_text = txt
69
112
  end
70
-
71
113
  old_lines = new_lines
72
114
  end
73
115
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sumire
3
3
  version: !ruby/object:Gem::Version
4
- version: 24.03.30
4
+ version: 24.04.03
5
5
  platform: ruby
6
6
  authors:
7
7
  - MURATA Mitsuharu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-30 00:00:00.000000000 Z
11
+ date: 2024-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ansi2txt