assayo 0.1.5 → 0.1.6
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/ruby/assayo +116 -52
- 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: 66a62a3ea793b569e22233d954bff82aeade815dff55b6d3dc5fc4cd568ab92c
|
|
4
|
+
data.tar.gz: '0786a08326588fc58537055525d145d00cf67ca31c5c8fb52e65f6882c83b9aa'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6845051e391bbf1ff04a5ad2d32907f09ebdd016433f38f6640d16c1d1d675f1ea52904c6a67e6e6d5ba7dd45eee035f2552110ae93c668bf3603e333104a208
|
|
7
|
+
data.tar.gz: 5be0facf3b010a88b93c31d6fd95646170a43315272dba80ed36f82c7711063f4006ee8d04cfa9dc365843bea5c1be0e098c4e2b6a6bd18da3d6ab7dd81d6834
|
data/ruby/assayo
CHANGED
|
@@ -1,61 +1,125 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if ARGV.include?('--no-file')
|
|
6
|
-
$raw = ""
|
|
7
|
-
end
|
|
8
|
-
return "git --no-pager log #{$raw} --oneline --all --reverse --date=iso-strict --pretty=format:\"%ad>%aN>%aE>%s\""
|
|
9
|
-
end
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'etc'
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
end
|
|
7
|
+
module Assayo
|
|
8
|
+
module LoggerMixin
|
|
9
|
+
private
|
|
16
10
|
|
|
17
|
-
def
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
end
|
|
11
|
+
def debug_enabled?
|
|
12
|
+
ARGV.include?('--debug')
|
|
13
|
+
end
|
|
22
14
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# folder, when user run library
|
|
29
|
-
$DIST_DIR = 'assayo'
|
|
30
|
-
$DIST_PATH = Dir.pwd
|
|
31
|
-
|
|
32
|
-
# 1. Copy folder ./assayo from package to ./assayo in project
|
|
33
|
-
$source = File.join($SOURCE_PATH, $SOURCE_DIR)
|
|
34
|
-
$target = File.join($DIST_PATH, $DIST_DIR)
|
|
35
|
-
$copy_cmd = "cp -r #{$source} #{$target}"
|
|
36
|
-
begin
|
|
37
|
-
system($copy_cmd) or raise $copy_cmd
|
|
38
|
-
rescue => e
|
|
39
|
-
puts "Assayo: cant copy files: #{e.message}"
|
|
15
|
+
def debug(message)
|
|
16
|
+
return unless debug_enabled?
|
|
17
|
+
warn "[Assayo][DEBUG] #{message}"
|
|
18
|
+
end
|
|
40
19
|
end
|
|
41
|
-
show_message("directory with HTML report was be created")
|
|
42
|
-
|
|
43
|
-
# Run "git log" and save output in file ./assayo/log.txt
|
|
44
|
-
show_message("reading git log was be started")
|
|
45
|
-
$fileName = File.join(Dir.pwd, $DIST_DIR, "log.txt")
|
|
46
|
-
$save_log_cmd = get_save_log_command()
|
|
47
|
-
begin
|
|
48
|
-
system($save_log_cmd, { out: $fileName }) or raise $save_log_cmd
|
|
49
|
-
rescue => e
|
|
50
|
-
puts "Assayo: cant create log file: #{e.message}"
|
|
51
|
-
end
|
|
52
|
-
show_message("the file with git log was be saved")
|
|
53
20
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
21
|
+
class Reporter
|
|
22
|
+
LIB_SOURCE_RELATIVE = '../assayo'.freeze
|
|
23
|
+
DIST_DIR_NAME = 'assayo'.freeze
|
|
24
|
+
TEMP_LOG_FILENAME = 'log.txt'.freeze
|
|
25
|
+
|
|
26
|
+
include LoggerMixin
|
|
27
|
+
|
|
28
|
+
GIT_FORMAT = '%ad>%aN>%aE>%s'.freeze
|
|
29
|
+
DANGEROUS_CHARS = /[\\`$%\x00-\x1f\x7f]/.freeze
|
|
30
|
+
|
|
31
|
+
def initialize
|
|
32
|
+
@script_dir = File.expand_path(__dir__)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Точка входа
|
|
36
|
+
def run
|
|
37
|
+
copy_library_files
|
|
38
|
+
generate_git_log
|
|
39
|
+
assemble_final_payload
|
|
40
|
+
debug("Report generation finished successfully.")
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
abort "Assayo: Fatal error — #{e.class}: #{e.message}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def source_path
|
|
48
|
+
@source_path ||= File.expand_path(LIB_SOURCE_RELATIVE, @script_dir)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def dist_path
|
|
52
|
+
@dist_path ||= File.join(Dir.pwd, DIST_DIR_NAME)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def log_file_path
|
|
56
|
+
@log_file_path ||= File.join(dist_path, TEMP_LOG_FILENAME)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Копирование ассетов отчета
|
|
60
|
+
def copy_library_files
|
|
61
|
+
raise "Source directory not found at '#{source_path}'" unless Dir.exist?(source_path)
|
|
62
|
+
|
|
63
|
+
FileUtils.mkdir_p(dist_path) unless Dir.exist?(dist_path)
|
|
64
|
+
debug("Copying assets from '#{source_path}' to '#{dist_path}'")
|
|
65
|
+
FileUtils.cp_r("#{source_path}/.", dist_path, remove_destination: true)
|
|
66
|
+
rescue SystemCallError => e
|
|
67
|
+
raise IOError, "Failed to copy library files: #{e.message}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def generate_git_log
|
|
71
|
+
cmd = build_git_command
|
|
72
|
+
debug("Spawning process: #{cmd.shelljoin}")
|
|
73
|
+
|
|
74
|
+
begin
|
|
75
|
+
File.open(log_file_path, 'w') do |file|
|
|
76
|
+
Open3.popen2e(*cmd) do |stdin, stdout_err, wait_thr|
|
|
77
|
+
stdin.close
|
|
78
|
+
stdout_err.each_line { |line| file.write(line) }
|
|
79
|
+
|
|
80
|
+
exit_status = wait_thr.value
|
|
81
|
+
unless exit_status.success?
|
|
82
|
+
raise RuntimeError, "Git exited with code #{exit_status.exitstatus}"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
debug("Raw git log streamed to '#{log_file_path}'")
|
|
87
|
+
rescue Errno::ENOENT
|
|
88
|
+
raise "Executable 'git' not found in PATH."
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def build_git_command
|
|
93
|
+
base_args = %w[git --no-pager log --oneline --all --reverse --date=iso-strict]
|
|
94
|
+
base_args << '--raw' << '--numstat' unless ARGV.include?('--no-file')
|
|
95
|
+
base_args.concat(%W[--pretty=format:#{GIT_FORMAT}])
|
|
96
|
+
base_args
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def assemble_final_payload
|
|
100
|
+
debug('Assembling final payload...')
|
|
101
|
+
|
|
102
|
+
output_lines = +'R(f`'
|
|
103
|
+
File.foreach(log_file_path, encoding: 'UTF-8') do |line|
|
|
104
|
+
sanitized = line.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
|
|
105
|
+
.gsub(DANGEROUS_CHARS, '')
|
|
106
|
+
.chomp
|
|
107
|
+
next if sanitized.empty?
|
|
108
|
+
|
|
109
|
+
output_lines << sanitized << "\n"
|
|
110
|
+
end
|
|
111
|
+
output_lines.chomp! # Убираем лишний перевод строки перед закрывающим тегом
|
|
112
|
+
output_lines << '`)'
|
|
113
|
+
|
|
114
|
+
File.binwrite(log_file_path, output_lines)
|
|
115
|
+
debug('Final payload assembled and written.')
|
|
116
|
+
rescue SystemCallError => e
|
|
117
|
+
raise IOError, "Failed during assembly or write of final payload: #{e.message}"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
59
120
|
end
|
|
60
121
|
|
|
61
|
-
|
|
122
|
+
if __FILE__ == $PROGRAM_NAME
|
|
123
|
+
reporter = Assayo::Reporter.new
|
|
124
|
+
reporter.run
|
|
125
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: assayo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aleksei Bakhirev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: ruby
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Visualization and analysis you git log. Creates HTML report about commits
|
|
14
14
|
statistics, employees and company. Also it parse git log and give a achievements
|