cl-magic 0.3.9 → 1.2.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +16 -2
- data/cl-magic.gemspec +5 -0
- data/lib/cl/magic/cl +21 -14
- data/lib/cl/magic/cl-ai-chat +117 -0
- data/lib/cl/magic/cl-ai-query +116 -0
- data/lib/cl/magic/cl-ai-store-jira +158 -0
- data/lib/cl/magic/cl-auth +12 -0
- data/lib/cl/magic/cl-dk +33 -464
- data/lib/cl/magic/cl-dk-make +174 -0
- data/lib/cl/magic/cl-dk-make-world +163 -0
- data/lib/cl/magic/cl-dk-parts +253 -0
- data/lib/cl/magic/cl-dk-world +140 -0
- data/lib/cl/magic/cl-jira-fetch +15 -48
- data/lib/cl/magic/cl-jira-fetch-by-epics +112 -0
- data/lib/cl/magic/cl-jira-to-elastic +126 -0
- data/lib/cl/magic/cl-jira-to-markdown +68 -0
- data/lib/cl/magic/cl-jira-to-stats +202 -0
- data/lib/cl/magic/cl-kube-logs +3 -1
- data/lib/cl/magic/cl-poll +20 -5
- data/lib/cl/magic/common/ai_prompt.rb +169 -0
- data/lib/cl/magic/common/ai_text_splitter.rb +78 -0
- data/lib/cl/magic/common/common_options.rb +1 -1
- data/lib/cl/magic/common/elastic.rb +41 -0
- data/lib/cl/magic/common/jira.rb +173 -45
- data/lib/cl/magic/common/milvus.rb +78 -0
- data/lib/cl/magic/dk/help_printer.rb +29 -0
- data/lib/cl/magic/dk/parts_merger.rb +67 -0
- data/lib/cl/magic/dk/world_settings.rb +52 -0
- data/lib/cl/magic/dk/yaml_arg_munger.rb +107 -0
- data/lib/cl/magic/version.rb +1 -1
- metadata +77 -3
- data/lib/cl/magic/cl-jira-stats +0 -180
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Fetch jira issues, status changelogs and save them to a file
|
3
|
+
require 'optparse'
|
4
|
+
require 'optparse/subcommand'
|
5
|
+
require 'tty-command'
|
6
|
+
require 'tty-prompt'
|
7
|
+
|
8
|
+
require 'cl/magic/common/common_options.rb'
|
9
|
+
require 'cl/magic/common/logging.rb'
|
10
|
+
require 'cl/magic/common/jira.rb'
|
11
|
+
|
12
|
+
require 'net/http'
|
13
|
+
require 'json'
|
14
|
+
|
15
|
+
@logger = get_logger()
|
16
|
+
|
17
|
+
#
|
18
|
+
# Features
|
19
|
+
#
|
20
|
+
|
21
|
+
def do_work(options)
|
22
|
+
break_at_one_page = false # when developing, set this to true
|
23
|
+
jira = Jira.new options[:base_uri], options[:username], options[:token], break_at_one_page
|
24
|
+
|
25
|
+
@logger.puts ""
|
26
|
+
@logger.wait "fetch epics"
|
27
|
+
epic_ids, epics = jira.get_epic_ids(options[:project], options[:epic_wildcard])
|
28
|
+
|
29
|
+
@logger.puts ""
|
30
|
+
@logger.wait "fetch issues"
|
31
|
+
issues = jira.get_issues_by_epic_ids(options[:project], epic_ids)
|
32
|
+
|
33
|
+
@logger.puts ""
|
34
|
+
@logger.wait "fetch change logs"
|
35
|
+
issues = jira.collect_status_changelogs(jira, issues)
|
36
|
+
|
37
|
+
@logger.puts ""
|
38
|
+
@logger.wait "fetch comments"
|
39
|
+
issues = jira.collect_comments(jira, issues)
|
40
|
+
|
41
|
+
@logger.puts ""
|
42
|
+
puts issues.to_json
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Options
|
47
|
+
#
|
48
|
+
|
49
|
+
options = {}
|
50
|
+
global_banner = <<DOC
|
51
|
+
|
52
|
+
Fetch jira issues, status changelogs and save them to a file
|
53
|
+
|
54
|
+
Usage: cl jira fetch-by-epics [options]
|
55
|
+
|
56
|
+
DOC
|
57
|
+
|
58
|
+
global = OptionParser.new do |g|
|
59
|
+
g.banner = global_banner
|
60
|
+
add_help_and_verbose(g)
|
61
|
+
|
62
|
+
g.on("--base-uri URI", "base uri for jira (ex. https://company.atlassian.net)") do |v|
|
63
|
+
options[:base_uri] = v
|
64
|
+
end
|
65
|
+
|
66
|
+
g.on("-u", "--username USERNAME", "jira username") do |v|
|
67
|
+
options[:username] = v
|
68
|
+
end
|
69
|
+
|
70
|
+
g.on("-t", "--token TOKEN", "jira token (you can create one, google it)") do |v|
|
71
|
+
options[:token] = v
|
72
|
+
end
|
73
|
+
|
74
|
+
g.on("-p", "--project KEY", "jira project to fetch from") do |v|
|
75
|
+
options[:project] = v
|
76
|
+
end
|
77
|
+
|
78
|
+
g.on("-w", "--epic-wildcard TEXT", "wildcard to filter the epics by") do |v|
|
79
|
+
options[:epic_wildcard] = v
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Run
|
86
|
+
#
|
87
|
+
|
88
|
+
@working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
|
89
|
+
global.parse(ARGV)
|
90
|
+
|
91
|
+
# error on token right away
|
92
|
+
if options[:token].nil?
|
93
|
+
@logger.error "missing --token"
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
|
97
|
+
# prompt for missing options
|
98
|
+
ask_and_store_option(options, :base_uri, "base_uri: ")
|
99
|
+
ask_and_store_option(options, :username, "username: ")
|
100
|
+
ask_and_store_option(options, :project, "project: ")
|
101
|
+
ask_and_store_option(options, :epic_wildcard, "epic_wildcard: ")
|
102
|
+
|
103
|
+
# display full command
|
104
|
+
write_history("""cl jira fetch-by-epics \\
|
105
|
+
--base-uri=#{options[:base_uri]} \\
|
106
|
+
--username=#{options[:username]} \\
|
107
|
+
--project=#{options[:project]} \\
|
108
|
+
--epic-wildcard=#{options[:epic_wildcard]} \\
|
109
|
+
--token REDACTED
|
110
|
+
""")
|
111
|
+
|
112
|
+
do_work(options)
|
@@ -0,0 +1,126 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Jira fetch datafile to markdown
|
3
|
+
require 'optparse'
|
4
|
+
require 'optparse/subcommand'
|
5
|
+
require 'tty-command'
|
6
|
+
require 'tty-prompt'
|
7
|
+
require 'active_support/all'
|
8
|
+
|
9
|
+
require 'cl/magic/common/parse_and_pick.rb'
|
10
|
+
require 'cl/magic/common/common_options.rb'
|
11
|
+
require 'cl/magic/common/logging.rb'
|
12
|
+
require 'cl/magic/common/jira.rb'
|
13
|
+
|
14
|
+
require 'json'
|
15
|
+
|
16
|
+
@logger = get_logger()
|
17
|
+
|
18
|
+
|
19
|
+
def post(url, verb, data)
|
20
|
+
cmd = """
|
21
|
+
curl -X#{verb} \
|
22
|
+
#{url} \
|
23
|
+
-H 'Content-Type: application/json' \
|
24
|
+
-d '#{data.to_json}'
|
25
|
+
"""
|
26
|
+
return `#{cmd}`
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_index()
|
30
|
+
url = "#{@ELASTIC_URL}/jira"
|
31
|
+
|
32
|
+
return post(url, "PUT", {
|
33
|
+
"mappings": {
|
34
|
+
"properties": {
|
35
|
+
"text": {
|
36
|
+
"type": "text"
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
# def do_work(options, data)
|
44
|
+
# #puts create_index()
|
45
|
+
|
46
|
+
# url = "#{@ELASTIC_URL}/jira/_doc/1"
|
47
|
+
# puts post(url, "POST", {
|
48
|
+
# "text": "This is a new issue created in Jira"
|
49
|
+
# })
|
50
|
+
# end
|
51
|
+
|
52
|
+
|
53
|
+
#
|
54
|
+
# Features
|
55
|
+
#
|
56
|
+
|
57
|
+
def do_work(options)
|
58
|
+
filepath = File.join(@working_dir, options[:data_filepath])
|
59
|
+
issues = JSON.parse(File.read(filepath))
|
60
|
+
issues.each do |issue|
|
61
|
+
|
62
|
+
md = []
|
63
|
+
md << "# #{issue['key']}"
|
64
|
+
md << "project: #{issue['fields']['project']['key']}"
|
65
|
+
md << "created: #{issue['fields']['created']}"
|
66
|
+
md << "updated: #{issue['fields']['updated']}"
|
67
|
+
md << "status: #{issue['fields']['status']['statusCategory']['name']}" unless issue['fields']["status"].nil?
|
68
|
+
md << "priority: #{issue['fields']['priority']['name']}"
|
69
|
+
md << "labels: #{issue['fields']['labels'].join(',')}"
|
70
|
+
md << "issue_type: #{issue['fields']['issuetype']['name']}" unless issue['fields']["issuetype"].nil?
|
71
|
+
md << "assignee: #{issue['fields']['assignee']['displayName']}" unless issue['fields']["assignee"].nil?
|
72
|
+
md << ""
|
73
|
+
md << "## Summary:"
|
74
|
+
md << "#{issue['fields']['summary']}"
|
75
|
+
# push to elastic
|
76
|
+
|
77
|
+
md << "## Comments"
|
78
|
+
md << ""
|
79
|
+
issue["comments"].each_with_index do |comment, i|
|
80
|
+
md << "### Comment by #{comment["author"]["displayName"]} "
|
81
|
+
md << ""
|
82
|
+
md << "created: #{comment["created"]}"
|
83
|
+
md << "#{comment["body"].gsub('{noformat}', "\n```\n")}"
|
84
|
+
md << ""
|
85
|
+
end
|
86
|
+
puts md
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Options
|
92
|
+
#
|
93
|
+
|
94
|
+
options = {}
|
95
|
+
global_banner = <<DOC
|
96
|
+
|
97
|
+
Jira fetch datafile to markdown
|
98
|
+
|
99
|
+
Usage: cl jira to-markdown [options]
|
100
|
+
|
101
|
+
DOC
|
102
|
+
|
103
|
+
global = OptionParser.new do |g|
|
104
|
+
g.banner = global_banner
|
105
|
+
add_help_and_verbose(g)
|
106
|
+
|
107
|
+
g.on("-f", "--data-filepath FILEPATH", "relative path jira datafile") do |v|
|
108
|
+
options[:data_filepath] = v
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Run
|
114
|
+
#
|
115
|
+
|
116
|
+
@working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
|
117
|
+
global.parse(ARGV)
|
118
|
+
|
119
|
+
ask_and_store_option(options, :data_filepath, "data_filepath: ")
|
120
|
+
|
121
|
+
# display full command
|
122
|
+
write_history("""cl jira to-markdown \\
|
123
|
+
--data-filepath=#{options[:data_filepath]}
|
124
|
+
""")
|
125
|
+
|
126
|
+
do_work(options)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Jira fetch datafile to markdown
|
3
|
+
require 'optparse'
|
4
|
+
require 'optparse/subcommand'
|
5
|
+
require 'tty-command'
|
6
|
+
require 'tty-prompt'
|
7
|
+
require 'active_support/all'
|
8
|
+
|
9
|
+
require 'cl/magic/common/parse_and_pick.rb'
|
10
|
+
require 'cl/magic/common/common_options.rb'
|
11
|
+
require 'cl/magic/common/logging.rb'
|
12
|
+
require 'cl/magic/common/jira.rb'
|
13
|
+
|
14
|
+
require 'json'
|
15
|
+
|
16
|
+
@logger = get_logger()
|
17
|
+
|
18
|
+
#
|
19
|
+
# Features
|
20
|
+
#
|
21
|
+
|
22
|
+
def do_work(options)
|
23
|
+
filepath = File.join(@working_dir, options[:data_filepath])
|
24
|
+
issues = JSON.parse(File.read(filepath))
|
25
|
+
issues.each do |i|
|
26
|
+
issue_md, comments = Jira.jira_to_markdown(i)
|
27
|
+
puts issue_md
|
28
|
+
puts comments.map{ |o| o[1] }.join("\n")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Options
|
34
|
+
#
|
35
|
+
|
36
|
+
options = {}
|
37
|
+
global_banner = <<DOC
|
38
|
+
|
39
|
+
Jira fetch datafile to markdown
|
40
|
+
|
41
|
+
Usage: cl jira to-markdown [options]
|
42
|
+
|
43
|
+
DOC
|
44
|
+
|
45
|
+
global = OptionParser.new do |g|
|
46
|
+
g.banner = global_banner
|
47
|
+
add_help_and_verbose(g)
|
48
|
+
|
49
|
+
g.on("-f", "--data-filepath FILEPATH", "relative path jira datafile") do |v|
|
50
|
+
options[:data_filepath] = v
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Run
|
56
|
+
#
|
57
|
+
|
58
|
+
@working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
|
59
|
+
global.parse(ARGV)
|
60
|
+
|
61
|
+
ask_and_store_option(options, :data_filepath, "data_filepath: ")
|
62
|
+
|
63
|
+
# display full command
|
64
|
+
write_history("""cl jira to-markdown \\
|
65
|
+
--data-filepath=#{options[:data_filepath]}
|
66
|
+
""")
|
67
|
+
|
68
|
+
do_work(options)
|
@@ -0,0 +1,202 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Jira fetch datafile to stats
|
3
|
+
require 'optparse'
|
4
|
+
require 'optparse/subcommand'
|
5
|
+
require 'tty-command'
|
6
|
+
require 'tty-prompt'
|
7
|
+
require 'active_support/all'
|
8
|
+
|
9
|
+
require 'cl/magic/common/common_options.rb'
|
10
|
+
require 'cl/magic/common/logging.rb'
|
11
|
+
require 'cl/magic/common/jira.rb'
|
12
|
+
|
13
|
+
require 'net/http'
|
14
|
+
require 'json'
|
15
|
+
|
16
|
+
@logger = get_logger()
|
17
|
+
|
18
|
+
#
|
19
|
+
# Features
|
20
|
+
#
|
21
|
+
|
22
|
+
def get_issues_from_datafile(options)
|
23
|
+
final_issues = []
|
24
|
+
filepath = File.join(@working_dir, options[:data_filepath])
|
25
|
+
issues = JSON.parse(File.read(filepath))
|
26
|
+
|
27
|
+
@logger.info "stats for: #{options[:data_filepath]}"
|
28
|
+
issues.each do |issue|
|
29
|
+
issuetype = issue["fields"]["issuetype"]["name"]
|
30
|
+
labels = issue["fields"]["labels"]
|
31
|
+
|
32
|
+
has_excluded_labels = (labels & options[:exclude_labels]).any?
|
33
|
+
is_excluded_issuetype = options[:exclude_issuetypes].include?(issuetype.downcase)
|
34
|
+
final_issues << issue unless has_excluded_labels or is_excluded_issuetype
|
35
|
+
end
|
36
|
+
return final_issues
|
37
|
+
end
|
38
|
+
|
39
|
+
def in_range_issue_stats(issues, start_date, end_date, options)
|
40
|
+
|
41
|
+
def in_range_logs(start_date, end_date, issue)
|
42
|
+
return issue["status_changelogs"].select do |log|
|
43
|
+
(start_date..end_date).cover?(Date.parse(log["created"]))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# in-range
|
48
|
+
in_range_issues = issues.select do |issue|
|
49
|
+
|
50
|
+
# issue created date?
|
51
|
+
issue_in_range = Date.parse(issue["fields"]["created"]) < end_date
|
52
|
+
|
53
|
+
# logs created date?
|
54
|
+
logs_in_range = in_range_logs(start_date, end_date, issue).any?
|
55
|
+
|
56
|
+
# select if
|
57
|
+
(logs_in_range or issue_in_range)
|
58
|
+
end
|
59
|
+
|
60
|
+
# stat hashes
|
61
|
+
return in_range_issues.collect do |issue|
|
62
|
+
|
63
|
+
# most recent in-range log?
|
64
|
+
changelog = in_range_logs(start_date, end_date, issue)
|
65
|
+
.sort_by { |l| Date.parse(l["created"]) }.last
|
66
|
+
|
67
|
+
# yield stat hash
|
68
|
+
status = changelog ? changelog["toString"] : issue["fields"]["status"]["name"]
|
69
|
+
{
|
70
|
+
key: issue["key"],
|
71
|
+
issuetype: issue["fields"]["issuetype"]["name"],
|
72
|
+
status: status
|
73
|
+
}
|
74
|
+
end.compact
|
75
|
+
end
|
76
|
+
|
77
|
+
def print_stats(stat_hashes, start_date, end_date)
|
78
|
+
counts = {
|
79
|
+
start_date: start_date.strftime("%m-%d-%Y"),
|
80
|
+
end_date: end_date.strftime("%m-%d-%Y"),
|
81
|
+
total: 0,
|
82
|
+
total_todo: 0,
|
83
|
+
total_done: 0,
|
84
|
+
by_type: {}
|
85
|
+
}
|
86
|
+
|
87
|
+
stat_hashes.each do |stat|
|
88
|
+
issuetype = stat[:issuetype]
|
89
|
+
status = stat[:status]
|
90
|
+
|
91
|
+
# count by status
|
92
|
+
case status
|
93
|
+
when "To Do","Ready","Rework","In Progress","In QA","Ready For Code Review","In Code Review"
|
94
|
+
increment_type(counts, issuetype, :to_do)
|
95
|
+
increment(counts, :total_todo)
|
96
|
+
when "Ready to Deploy","Closed"
|
97
|
+
increment_type(counts, issuetype, :done)
|
98
|
+
increment(counts, :total_done)
|
99
|
+
else
|
100
|
+
# if status != "Won't Do"
|
101
|
+
# debugger
|
102
|
+
# end
|
103
|
+
end
|
104
|
+
|
105
|
+
# count totals
|
106
|
+
unless status=="Won't Do"
|
107
|
+
increment(counts, :total)
|
108
|
+
increment_type(counts, issuetype, :total)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
return counts
|
113
|
+
end
|
114
|
+
|
115
|
+
def oldest_issue_date(issues)
|
116
|
+
return issues.collect {|i| Date.parse(i["fields"]["created"])}.sort.first.beginning_of_day
|
117
|
+
end
|
118
|
+
|
119
|
+
def increment_type(hash, type, status_category)
|
120
|
+
type = type.downcase.underscore
|
121
|
+
hash[:by_type][type] = {} unless hash[:by_type].key?(type)
|
122
|
+
hash[:by_type][type][status_category] ||= 0
|
123
|
+
hash[:by_type][type][status_category] += 1
|
124
|
+
end
|
125
|
+
|
126
|
+
def increment(hash, key)
|
127
|
+
hash[key] ||= 0
|
128
|
+
hash[key] += 1
|
129
|
+
end
|
130
|
+
|
131
|
+
def iter_date_range(start_date)
|
132
|
+
while start_date < Date.today.end_of_week
|
133
|
+
yield start_date.beginning_of_week.beginning_of_day, start_date.end_of_week.end_of_day
|
134
|
+
start_date += 1.weeks # increment
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def do_work(options)
|
139
|
+
issues = get_issues_from_datafile(options)
|
140
|
+
oldest_date = oldest_issue_date(issues).beginning_of_week
|
141
|
+
@logger.info "starting at #{oldest_date}"
|
142
|
+
|
143
|
+
iter_date_range(oldest_date) do |start_date, end_date|
|
144
|
+
stat_hashes = in_range_issue_stats(issues, start_date, end_date, options)
|
145
|
+
counts = print_stats(stat_hashes, start_date, end_date)
|
146
|
+
puts counts # print each time range
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# Options
|
152
|
+
#
|
153
|
+
|
154
|
+
options = {
|
155
|
+
exclude_issuetypes: []
|
156
|
+
}
|
157
|
+
global_banner = <<DOC
|
158
|
+
|
159
|
+
Jira fetch datafile to stats
|
160
|
+
|
161
|
+
Usage: cl jira to-stats [options]
|
162
|
+
|
163
|
+
DOC
|
164
|
+
|
165
|
+
global = OptionParser.new do |g|
|
166
|
+
g.banner = global_banner
|
167
|
+
add_help_and_verbose(g)
|
168
|
+
|
169
|
+
g.on("-f", "--data-filepath FILEPATH", "relative path to file produced by 'cl jira fetch' command") do |v|
|
170
|
+
options[:data_filepath] = v
|
171
|
+
end
|
172
|
+
|
173
|
+
g.on("-e", "--exclude-issuetypes CSV", "comma separated list of issuetypes you want to exclude") do |v|
|
174
|
+
options[:exclude_issuetypes] = v.split(',')
|
175
|
+
options[:exclude_issuetypes] << "Won't Do"
|
176
|
+
end
|
177
|
+
|
178
|
+
g.on("-l", "--exclude-labels CSV", "comma separated list of labels that will cause a ticket to be excluded") do |v|
|
179
|
+
options[:exclude_labels] = v.split(',')
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
#
|
184
|
+
# Run
|
185
|
+
#
|
186
|
+
|
187
|
+
@working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
|
188
|
+
global.parse(ARGV)
|
189
|
+
|
190
|
+
# prompt for missing options
|
191
|
+
ask_and_store_option(options, :data_filepath, "data_filepath: ")
|
192
|
+
options[:exclude_issuetypes] = [] if options[:exclude_issuetypes].nil?
|
193
|
+
options[:exclude_labels] = [] if options[:exclude_labels].nil?
|
194
|
+
|
195
|
+
# display full command
|
196
|
+
write_history("""cl jira to-stats \\
|
197
|
+
--data-filepath=#{options[:data_filepath]} \\
|
198
|
+
--exclude-issuetypes=#{options[:exclude_issuetypes].join(',')} \\
|
199
|
+
--exclude-labels=#{options[:exclude_labels].join(',')}
|
200
|
+
""")
|
201
|
+
|
202
|
+
do_work(options)
|
data/lib/cl/magic/cl-kube-logs
CHANGED
@@ -17,8 +17,10 @@ require 'cl/magic/common/kubectl.rb'
|
|
17
17
|
# Features
|
18
18
|
#
|
19
19
|
|
20
|
+
|
20
21
|
def do_work(options, pods, containers)
|
21
|
-
|
22
|
+
container_name_regex = "^(#{containers.collect(&:first).join('|')})$"
|
23
|
+
cmd = "kubectl stern '#{pods.collect(&:first).join('|')}' --context #{options[:kube_context]} --namespace #{options[:namespace]} --container '#{container_name_regex}' --since #{options[:since]} --container-state 'running,waiting,terminated'"
|
22
24
|
cmd += " | grep #{options[:grep]}" if options[:grep]
|
23
25
|
|
24
26
|
@logger.puts
|
data/lib/cl/magic/cl-poll
CHANGED
@@ -17,10 +17,10 @@ require 'cl/magic/common/kubectl.rb'
|
|
17
17
|
# Features
|
18
18
|
#
|
19
19
|
|
20
|
-
def do_work(options)
|
20
|
+
def do_work(options, remaining_options)
|
21
21
|
while true
|
22
|
-
tty_command = TTY::Command.new(printer: :null)
|
23
|
-
out, err = tty_command.run(
|
22
|
+
tty_command = TTY::Command.new(printer: :null, pty: options[:pty])
|
23
|
+
out, err = tty_command.run("cd #{@working_dir} && #{remaining_options.join(' ')}")
|
24
24
|
puts out
|
25
25
|
puts
|
26
26
|
sleep(1)
|
@@ -31,7 +31,9 @@ end
|
|
31
31
|
# Options
|
32
32
|
#
|
33
33
|
|
34
|
-
options = {
|
34
|
+
options = {
|
35
|
+
pty: true
|
36
|
+
}
|
35
37
|
global_banner = <<DOC
|
36
38
|
|
37
39
|
A sandbox to try things
|
@@ -43,10 +45,23 @@ DOC
|
|
43
45
|
global = OptionParser.new do |g|
|
44
46
|
g.banner = global_banner
|
45
47
|
add_help_and_verbose(g)
|
48
|
+
|
49
|
+
g.on("--no-pty", "disable pseudo terminal") do |v|
|
50
|
+
options[:pty] = v
|
51
|
+
end
|
46
52
|
end
|
47
53
|
|
48
54
|
#
|
49
55
|
# Run
|
50
56
|
#
|
51
57
|
|
52
|
-
|
58
|
+
remaining_options = []
|
59
|
+
global.order! do |option|
|
60
|
+
remaining_options << option
|
61
|
+
end
|
62
|
+
|
63
|
+
global.parse(ARGV)
|
64
|
+
|
65
|
+
@working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
|
66
|
+
|
67
|
+
do_work(options, remaining_options)
|