yast-rake 0.2.36 → 0.2.41
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/VERSION +1 -1
- data/data/index.html +27 -0
- data/data/targets.yml +17 -2
- data/lib/tasks/actions.rake +44 -0
- data/lib/tasks/container_runner.rb +80 -0
- data/lib/tasks/github_actions/github_actions.rb +33 -0
- data/lib/tasks/github_actions/github_actions/colorizer.rb +80 -0
- data/lib/tasks/github_actions/github_actions/container.rb +162 -0
- data/lib/tasks/github_actions/github_actions/job.rb +50 -0
- data/lib/tasks/github_actions/github_actions/job_runner.rb +112 -0
- data/lib/tasks/github_actions/github_actions/step.rb +60 -0
- data/lib/tasks/github_actions/github_actions/workflow.rb +53 -0
- data/lib/tasks/github_actions/tasks.rb +24 -0
- data/lib/tasks/github_actions/tasks/details.rb +50 -0
- data/lib/tasks/github_actions/tasks/list.rb +37 -0
- data/lib/tasks/github_actions/tasks/run.rb +82 -0
- data/lib/tasks/github_actions/tasks/run_all.rb +111 -0
- data/lib/tasks/pot.rake +38 -15
- data/lib/tasks/run.rake +11 -0
- data/lib/tasks/server.rake +34 -0
- data/lib/yast/index_servlet.rb +36 -0
- data/lib/yast/servers_servlet.rb +47 -0
- data/lib/yast/tarball_server.rb +109 -0
- data/lib/yast/tarball_servlet.rb +55 -0
- metadata +24 -3
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Yast rake
|
5
|
+
#
|
6
|
+
# Copyright (C) 2021 SUSE LLC
|
7
|
+
# This library is free software; you can redistribute it and/or modify
|
8
|
+
# it only under the terms of version 2.1 of the GNU Lesser General Public
|
9
|
+
# License as published by the Free Software Foundation.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
require_relative "../github_actions"
|
22
|
+
|
23
|
+
module GithubActions
|
24
|
+
module Tasks
|
25
|
+
# run all supported Github Action jobs locally
|
26
|
+
class RunAll
|
27
|
+
include Colorizer
|
28
|
+
|
29
|
+
# run all jobs one by one, continue even if a job fails,
|
30
|
+
# print the summary in the end
|
31
|
+
def run
|
32
|
+
# collect failed jobs
|
33
|
+
failed_jobs = []
|
34
|
+
workflows = Workflow.read
|
35
|
+
# custom Docker image requested?
|
36
|
+
image = custom_image(workflows)
|
37
|
+
|
38
|
+
workflows.each do |workflow|
|
39
|
+
workflow.jobs.each do |job|
|
40
|
+
# skip unsupported jobs
|
41
|
+
next unless valid_job?(job)
|
42
|
+
|
43
|
+
runner = JobRunner.new(job, image)
|
44
|
+
failed_jobs << job.name if !runner.run
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
print_result(failed_jobs)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# check if a custom image can be used for all jobs,
|
54
|
+
# if more than one Docker image is used than it's unlikely that
|
55
|
+
# a same custom image will work for all jobs, rather abort in that case
|
56
|
+
# to avoid some strange errors when using incorrect image
|
57
|
+
# @param workflows [GithubActions::Workflow] all defined workflows
|
58
|
+
# @return [String,nil] the custom Docker image name or `nil` if not specified
|
59
|
+
def custom_image(workflows)
|
60
|
+
return nil unless ENV["DOCKER_IMAGE"]
|
61
|
+
|
62
|
+
images = workflows.each_with_object([]) do |workflow, arr|
|
63
|
+
workflow.jobs.each do |job|
|
64
|
+
arr << job.container if job.container && !arr.include?(job.container)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if images.size > 1
|
69
|
+
error("More than one Docker image is used in the workflows,")
|
70
|
+
error("DOCKER_IMAGE option cannot be used.")
|
71
|
+
puts "Use DOCKER_IMAGE option for each job separately."
|
72
|
+
abort
|
73
|
+
end
|
74
|
+
|
75
|
+
ENV["DOCKER_IMAGE"]
|
76
|
+
end
|
77
|
+
|
78
|
+
# print the final result
|
79
|
+
# @param failed_jobs [Array<String>] list of failed jobs
|
80
|
+
def print_result(failed_jobs)
|
81
|
+
if failed_jobs.empty?
|
82
|
+
success("Overall result: SUCCESS")
|
83
|
+
else
|
84
|
+
error("Failed jobs: #{failed_jobs.inspect}")
|
85
|
+
error("Overall result: FAILURE!")
|
86
|
+
abort
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# check if the job is valid and can be run locally,
|
91
|
+
# if the job cannot be used it prints a warning
|
92
|
+
# @return [Boolean] `true` if the job is valid, `false` otherwise
|
93
|
+
def valid_job?(job)
|
94
|
+
unsupported = job.unsupported_steps
|
95
|
+
if !unsupported.empty?
|
96
|
+
warning("WARNING: Skipping job \"#{job.name}\", found " \
|
97
|
+
"unsupported steps: #{unsupported.inspect}")
|
98
|
+
return false
|
99
|
+
end
|
100
|
+
|
101
|
+
if job.container.nil? || job.container.empty?
|
102
|
+
warning("WARNING: Skipping job \"#{job.name}\", " \
|
103
|
+
"the Docker container in not specified")
|
104
|
+
return false
|
105
|
+
end
|
106
|
+
|
107
|
+
true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/tasks/pot.rake
CHANGED
@@ -27,19 +27,36 @@ task :pot do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
namespace :check do
|
30
|
+
|
31
|
+
def interpolation_message
|
32
|
+
<<~MSG
|
33
|
+
Note: \#{foo} substitution in translatable strings does
|
34
|
+
not work properly, use
|
35
|
+
_("foo %{bar} baz") % { :bar => bar }
|
36
|
+
or
|
37
|
+
_("foo %s baz") % bar
|
38
|
+
MSG
|
39
|
+
end
|
40
|
+
|
41
|
+
def angle_brackets_message
|
42
|
+
<<~MSG
|
43
|
+
Note: %<foo> placeholder should not be used in translatable strings
|
44
|
+
because GNU Gettext does not support any suitable language format for that,
|
45
|
+
use %{foo} instead.
|
46
|
+
MSG
|
47
|
+
end
|
48
|
+
|
30
49
|
# print failed lines and a hint to STDERR
|
31
|
-
def report_pot_errors(lines)
|
50
|
+
def report_pot_errors(lines, message)
|
51
|
+
return if lines.empty?
|
52
|
+
|
32
53
|
warn "Failed lines:"
|
33
54
|
warn "-" * 30
|
34
55
|
warn lines
|
35
56
|
warn "-" * 30
|
36
|
-
|
37
|
-
warn
|
38
|
-
|
39
|
-
warn " _(\"foo %{bar} baz\") % { :bar => bar }"
|
40
|
-
warn "or"
|
41
|
-
warn " _(\"foo %s baz\") % bar"
|
42
|
-
$stderr.puts
|
57
|
+
warn ""
|
58
|
+
warn message
|
59
|
+
warn ""
|
43
60
|
end
|
44
61
|
|
45
62
|
# remove gettext keywords and extra quotes
|
@@ -53,7 +70,9 @@ namespace :check do
|
|
53
70
|
end
|
54
71
|
|
55
72
|
desc "Check translatable strings for common mistakes"
|
56
|
-
# depends on the global "pot" task defined above
|
73
|
+
# depends on the global "pot" task defined above,
|
74
|
+
# this scans for the #{} interpolations (do not work in translations)
|
75
|
+
# and %<> (no compatible language format in Gettext)
|
57
76
|
task pot: :"rake:pot" do
|
58
77
|
Dir["*.pot"].each do |pot|
|
59
78
|
puts "Checking #{pot}..."
|
@@ -61,14 +80,18 @@ namespace :check do
|
|
61
80
|
# remove comments
|
62
81
|
lines.reject! { |line| line.match(/^#/) }
|
63
82
|
# Ruby substitution present?
|
64
|
-
lines.select
|
83
|
+
interpolations = lines.select { |line| line.include?("\#{") }
|
84
|
+
angle_brackets = lines.select { |line| line.include?("%<") }
|
85
|
+
|
86
|
+
next if interpolations.empty? && angle_brackets.empty?
|
87
|
+
|
88
|
+
clean_pot_lines(interpolations)
|
89
|
+
clean_pot_lines(angle_brackets)
|
65
90
|
|
66
|
-
|
91
|
+
report_pot_errors(interpolations, interpolation_message)
|
92
|
+
report_pot_errors(angle_brackets, angle_brackets_message)
|
67
93
|
|
68
|
-
|
69
|
-
report_pot_errors(lines)
|
70
|
-
raise "ERROR: Ruby substitution found in a translatable string"
|
71
|
-
end
|
94
|
+
raise "ERROR: Found invalid or unsupported translatable string"
|
72
95
|
end
|
73
96
|
end
|
74
97
|
end
|
data/lib/tasks/run.rake
CHANGED
@@ -18,6 +18,8 @@
|
|
18
18
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
19
|
#++
|
20
20
|
|
21
|
+
require_relative "container_runner"
|
22
|
+
|
21
23
|
def set_y2dir
|
22
24
|
dirs = Dir["**/src"]
|
23
25
|
dirs << ENV["Y2DIR"] if ENV["Y2DIR"] && !ENV["Y2DIR"].empty?
|
@@ -46,6 +48,15 @@ task :run, :client do |_t, args|
|
|
46
48
|
sh "/sbin/yast2 #{client}"
|
47
49
|
end
|
48
50
|
|
51
|
+
desc "Run given client in a Docker container"
|
52
|
+
task :"run:container", :client do |_t, args|
|
53
|
+
args.with_defaults = { client: nil }
|
54
|
+
client = args[:client]
|
55
|
+
|
56
|
+
runner = ContainerRunner.new
|
57
|
+
runner.run(client)
|
58
|
+
end
|
59
|
+
|
49
60
|
desc "Runs console with preloaded module directories"
|
50
61
|
task :console do
|
51
62
|
set_y2dir
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Yast rake
|
5
|
+
#
|
6
|
+
# Copyright (C) 2020, SUSE LLC
|
7
|
+
# This library is free software; you can redistribute it and/or modify
|
8
|
+
# it only under the terms of version 2.1 of the GNU Lesser General Public
|
9
|
+
# License as published by the Free Software Foundation.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
require_relative "../yast/tarball_server"
|
22
|
+
|
23
|
+
# Rake task for running a source code web server,
|
24
|
+
# designed for the `yupdate` script.
|
25
|
+
desc "Start an HTTP server providing dynamically generated source code tarball"
|
26
|
+
task :server, [:port] do |_task, args|
|
27
|
+
server = Yast::TarballServer.new(args[:port])
|
28
|
+
|
29
|
+
puts "Starting tarball webserver:"
|
30
|
+
server.addresses.each { |a| puts " * #{a}" }
|
31
|
+
puts
|
32
|
+
|
33
|
+
server.start
|
34
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Yast rake
|
5
|
+
#
|
6
|
+
# Copyright (C) 2020, SUSE LLC
|
7
|
+
# This library is free software; you can redistribute it and/or modify
|
8
|
+
# it only under the terms of version 2.1 of the GNU Lesser General Public
|
9
|
+
# License as published by the Free Software Foundation.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
require "webrick"
|
22
|
+
|
23
|
+
module Yast
|
24
|
+
# a webrick servlet which returns a basic HTML info about the server,
|
25
|
+
# just to avoid that nasty 404 error page when someone opens the
|
26
|
+
# server URL in a web browser
|
27
|
+
class IndexServlet < WEBrick::HTTPServlet::AbstractServlet
|
28
|
+
INDEX_FILE = File.expand_path("../../data/index.html", __dir__)
|
29
|
+
|
30
|
+
def do_GET(_request, response)
|
31
|
+
response.status = 200
|
32
|
+
response.content_type = "text/html"
|
33
|
+
response.body = File.read(INDEX_FILE)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Yast rake
|
5
|
+
#
|
6
|
+
# Copyright (C) 2020, SUSE LLC
|
7
|
+
# This library is free software; you can redistribute it and/or modify
|
8
|
+
# it only under the terms of version 2.1 of the GNU Lesser General Public
|
9
|
+
# License as published by the Free Software Foundation.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
require "json"
|
22
|
+
require "webrick"
|
23
|
+
|
24
|
+
module Yast
|
25
|
+
# a webrick servlet which lists all rake servers running on this machine
|
26
|
+
class ServersServlet < WEBrick::HTTPServlet::AbstractServlet
|
27
|
+
def do_GET(_request, response)
|
28
|
+
response.status = 200
|
29
|
+
response.content_type = "application/json"
|
30
|
+
response.body = servers.to_json
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# find the locally running "rake server" processes
|
36
|
+
def servers
|
37
|
+
output = `pgrep -a -f "rake server \\([0-9]+,.*\\)"`
|
38
|
+
output.lines.map do |l|
|
39
|
+
l.match(/rake server \(([0-9]+),(.*)\)/)
|
40
|
+
{
|
41
|
+
port: Regexp.last_match[1],
|
42
|
+
dir: Regexp.last_match[2]
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Yast rake
|
5
|
+
#
|
6
|
+
# Copyright (C) 2020, SUSE LLC
|
7
|
+
# This library is free software; you can redistribute it and/or modify
|
8
|
+
# it only under the terms of version 2.1 of the GNU Lesser General Public
|
9
|
+
# License as published by the Free Software Foundation.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
require "webrick"
|
22
|
+
require "socket"
|
23
|
+
|
24
|
+
require_relative "index_servlet"
|
25
|
+
require_relative "servers_servlet"
|
26
|
+
require_relative "tarball_servlet"
|
27
|
+
|
28
|
+
module Yast
|
29
|
+
# a webrick server which provides the source tarballs
|
30
|
+
#
|
31
|
+
# the server handles these URL paths:
|
32
|
+
# - "/archive/current.tar.gz" - the generated source code tarball
|
33
|
+
# - "/servers/index.json" - index of the tarball servers running on this machine
|
34
|
+
# - "/" - just a simple index page
|
35
|
+
#
|
36
|
+
# to stop the server press Ctrl+C
|
37
|
+
class TarballServer
|
38
|
+
# the default port number
|
39
|
+
DEFAULT_HTTP_PORT = 8000
|
40
|
+
|
41
|
+
attr_reader :port
|
42
|
+
|
43
|
+
# create all URLs valid for this machine, use all network interfaces
|
44
|
+
# (except the loop backs, the server will be used only from outside)
|
45
|
+
# @return [Array<String>] list of URLs
|
46
|
+
def addresses
|
47
|
+
# ignore the loopback addresses
|
48
|
+
hosts = Socket.ip_address_list.reject { |a| a.ipv4_loopback? || a.ipv6_loopback? }
|
49
|
+
# IPv6 addresses need to be closed in square brackets in URLs
|
50
|
+
hosts.map! { |a| a.ipv6? ? "[#{a.ip_address}]" : a.ip_address.to_s }
|
51
|
+
# include also the hostname to make it easier to write
|
52
|
+
hostname = Socket.gethostname
|
53
|
+
hosts << hostname if !hostname&.empty?
|
54
|
+
hosts.map! { |h| "http://#{h}:#{port}" }
|
55
|
+
end
|
56
|
+
|
57
|
+
# constructor
|
58
|
+
#
|
59
|
+
# @param port [Integer,nil] the port number, if nil the port will be found automatically
|
60
|
+
#
|
61
|
+
def initialize(port = nil)
|
62
|
+
@port = port || find_port
|
63
|
+
end
|
64
|
+
|
65
|
+
# start the webserver, it can be closed by pressing Ctrl+C or by sending SIGTERM signal
|
66
|
+
def start
|
67
|
+
dir = File.basename(Dir.pwd)
|
68
|
+
# change the process title so we can find the running
|
69
|
+
# servers and their ports just by simple grepping the running processes
|
70
|
+
Process.setproctitle("rake server (#{port},#{dir})")
|
71
|
+
|
72
|
+
# Use "*" to bind also the IPv6 addresses
|
73
|
+
server = WEBrick::HTTPServer.new(Port: port, BindAddress: "*")
|
74
|
+
server.mount("/archive/current.tar.gz", TarballServlet)
|
75
|
+
server.mount("/servers/index.json", ServersServlet)
|
76
|
+
server.mount("/", IndexServlet)
|
77
|
+
|
78
|
+
# stop the server when receiving a signal like Ctrl+C
|
79
|
+
# (inspired by the "un.rb" from the Ruby stdlib)
|
80
|
+
signals = ["TERM", "QUIT"]
|
81
|
+
signals.concat(["HUP", "INT"]) if $stdin.tty?
|
82
|
+
signals.each do |s|
|
83
|
+
trap(s) { server.shutdown }
|
84
|
+
end
|
85
|
+
|
86
|
+
server.start
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# is the local port already taken by some other application?
|
92
|
+
# @param port [Integer] the port number
|
93
|
+
# @return [Boolean] true if the port is taken, false otherwise
|
94
|
+
def port_taken?(port)
|
95
|
+
# open the port and close it immediately, if that succeeds
|
96
|
+
# some other application is already using it
|
97
|
+
TCPSocket.new("localhost", port).close
|
98
|
+
true
|
99
|
+
rescue Errno::ECONNREFUSED
|
100
|
+
false
|
101
|
+
end
|
102
|
+
|
103
|
+
# find a free port starting from the default port number
|
104
|
+
# @return [Integer] the free port number
|
105
|
+
def find_port
|
106
|
+
DEFAULT_HTTP_PORT.step.find { |p| !port_taken?(p) }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|