diff --git a/.gitignore b/.gitignore
index b251085..eaea6ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
/bin/
+/ci/
/include/
/lib/
/src/
diff --git a/bin/rbpkg b/bin/rbpkg
index 260ff70..5731ded 100755
--- a/bin/rbpkg
+++ b/bin/rbpkg
@@ -114,7 +114,7 @@ begin
rbpkg
Rbpkg::Log.ok_all
rescue => error
- verbose(-1, "#{error.class.name}: #{error.message}")
verbose(-1, error.backtrace.reverse.join("\n"))
- Rbpkg::Log.ko_all
+ verbose(-1, "#{error.class.name}: #{error.message}")
+ exit 1
end
diff --git a/bin/rbpkg_ci b/bin/rbpkg_ci
old mode 100644
new mode 100755
index 99a17c3..bdd2b3a
--- a/bin/rbpkg_ci
+++ b/bin/rbpkg_ci
@@ -1,6 +1,5 @@
#!/usr/bin/env ruby
-load "#{File.dirname(File.dirname(__FILE__))}/lib/rbpkg/log.rb"
-load "#{File.dirname(File.dirname(__FILE__))}/lib/rbpkg/ci.rb"
+load "#{File.dirname(File.dirname(__FILE__))}/lib/rbpkg.rb"
$ARGS = ARGV
@@ -11,23 +10,23 @@ def shift
arg
end
-verbose = 2 # print command output
+verbose_level = 2 # print command output
case $ARGS[0]
when "-v"
- verbose = 3 # print all messages
+ verbose_level = 3 # print all messages
shift
when "-q"
- verbose = 1 # print commands
+ verbose_level = 1 # print commands
shift
when "-qq"
- verbose = 0 # print nothing
+ verbose_level = 0 # print nothing
shift
end
-Rbpkg.init("rbpkg_ci", verbose)
+Rbpkg.init("rbpkg_ci", verbose_level)
def usage()
- STDERR.puts "Usage: #{File.basename($0)} REPO ..."
+ STDERR.puts "Usage: #{File.basename($0)} REPO BRANCH COMMIT"
exit 1
end
@@ -38,10 +37,18 @@ def rbpkg_ci
when "--help"
usage
end
- Rbpkg.CI.tag
- $ARGS.each do |name|
- Rbpkg.Repos.repo(name).ci
- end
+ repo = shift
+ branch = shift
+ commit = shift
+ usage unless $ARGS == []
+ Rbpkg::Repos.repo(repo).ci(branch, commit)
end
-rbpkg_ci
+begin
+ rbpkg_ci
+ Rbpkg::Log.ok_all
+rescue => error
+ verbose(-1, error.backtrace.reverse.join("\n"))
+ verbose(-1, "#{error.class.name}: #{error.message}")
+ exit 1
+end
diff --git a/lib/rbpkg.rb b/lib/rbpkg.rb
index 9499b8c..8c47031 100644
--- a/lib/rbpkg.rb
+++ b/lib/rbpkg.rb
@@ -31,6 +31,10 @@ module Rbpkg
end
end
+ def self.ci_dir
+ "#{dir}/ci"
+ end
+
def self.clean_all(repos)
repos.each do |name|
Repos.repo(name).clean_all()
diff --git a/lib/rbpkg/log.rb b/lib/rbpkg/log.rb
index 727c887..fda3a6a 100644
--- a/lib/rbpkg/log.rb
+++ b/lib/rbpkg/log.rb
@@ -1,87 +1,129 @@
+require 'base64'
+
module Rbpkg
- module Log
+ class Log
+ attr_reader :name, :path, :path_html
+ attr_accessor :status
- def self.add(name)
- raise "already logging to #{name.inspect}" if @@logs.include?(name)
- raise "log file exists: #{name.inspect}" if File.exist?(path(name))
- @@logs << name
- verbose(3, "Logging to #{path(name)}")
- end
-
- def self.ansi_to_html(string)
- substitution = {
- "&" => "&",
- "<" => "<",
- ">" => ">",
- "\33[0;31m" => "<span style=\"color: red;\">",
- "\33[0;34m" => "<span style=\"color: blue;\">",
- "\33[0;35m" => "<span style=\"color: purple;\">",
- "\33[0m" => "</span>"
- }
- s = string.clone
- substitution.each do |k, v|
- s.gsub!(k, v)
+ def initialize(name)
+ @name = name
+ @path = "#{Rbpkg.log_dir}/#{name}_#{Rbpkg.date}_#{$$}.log"
+ @path_html = "#{path}.html"
+ @status = :running
+ raise "log file exists: #{@path.inspect}" if File.exist?(@path)
+ raise "log file exists: #{@path_html.inspect}" if File.exist?(@path_html)
+ end
+
+ def img
+ path = "#{File.dirname(File.dirname(File.dirname(__FILE__)))}/share/icon/64x64/status_#{status}.png"
+ file = File.read(path)
+ base64 = Base64.encode64(file)
+ "data:image/png;base64,#{base64}"
+ end
+
+ def put_layout
+ tmp = path_html + '.tmp'
+ log = File.read(path)
+ html = <<EOF
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8"/>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+ <title>#{path.to_html}</title>
+ <link rel="stylesheet" href="/_assets/app.css">
+ <script defer type="text/javascript" src="/_assets/app.js"></script>
+ <link rel="icon" type="image/png" sizes="64x64" href="${IMG}">
+ </head>
+ <body>
+ <div class="ci-header">
+ <a href="./"><i class="fas fa-asterisk"></i> All logs</a>
+ </div>
+ <h1>
+ <img src="#{img}" class="status-#{status.to_s.to_html}"/>
+ #{path.to_html}
+ </h1>
+ <pre><code>#{log.ansi_to_html}</code></pre>
+ </body>
+</html>
+EOF
+ File.write(tmp, html)
+ verbose(3, "Writing #{path_html}")
+ FileUtils.mv(tmp, path_html)
+ end
+
+ def puts(string)
+ File.open(path, "a") do |output|
+ output.puts string
end
- s
+ end
+
+ def self.add(name)
+ raise "already logging to #{name.inspect}" if @@log[name]
+ log = new(name)
+ @@log[name] = log
+ verbose(3, "Logging to #{log.path}")
end
def self.init(name)
@@name = name
- @@logs = []
+ @@log = {}
add(name)
at_exit { ko_all }
end
def self.ko(name)
- puts_by_name(name, status_message_ko)
- remove(name)
+ log = remove(name)
+ log.status = :ko
+ log.puts(status_message_ko)
+ log.put_layout
end
def self.ko_all
- if @@logs != []
+ if @@log != {}
+ @@log.each do |name, log|
+ log.status = :ko
+ end
verbose(-1, status_message_ko)
- @@logs = []
+ remove_all
end
end
def self.ok(name)
- puts_by_name(name, status_message_ok)
- remove(name)
+ log = remove(name)
+ log.status = :ok
+ log.puts(status_message_ok)
+ log.put_layout
end
def self.ok_all
- if @@logs != []
+ if @@log != []
+ @@log.each do |name, log|
+ log.status = :ok
+ end
verbose(3, status_message_ok)
- @@logs = []
+ remove_all
end
end
- def self.path(name)
- "#{Rbpkg.log_dir}/#{name}_#{Rbpkg.date}_#{$$}.log"
- end
-
- def self.path_html(name)
- "#{path(name)}.html"
- end
-
def self.puts(string)
- @@logs.each do |name|
- puts_by_name(name, string)
+ @@log.each do |name, log|
+ log.puts(string)
end
end
- def self.puts_by_name(name, string)
- File.open(path(name), "a") do |output|
- output.puts string
- end
- File.open(path_html(name), "a") do |output|
- output.puts ansi_to_html(string)
- end
+ def self.remove(name)
+ log = @@log[name]
+ raise "not logging to #{name.inspect}" unless log
+ @@log.delete(name)
+ log
end
- def self.remove(name)
- raise "not logging to #{name.inspect}" unless @@logs.include?(name)
- @@logs.delete(name)
+ def self.remove_all
+ logs = @@log
+ @@log = {}
+ logs
end
def self.status_message(status)
@@ -95,5 +137,34 @@ module Rbpkg
def self.status_message_ok
status_message("OK")
end
+ end
end
+
+class String
+ def ansi_to_html
+ substitution = {
+ "\33[0;31m" => "<span style=\"color: red;\">",
+ "\33[0;34m" => "<span style=\"color: blue;\">",
+ "\33[0;35m" => "<span style=\"color: purple;\">",
+ "\33[0m" => "</span>"
+ }
+ s = to_html
+ substitution.each do |k, v|
+ s.gsub!(k, v)
+ end
+ s
+ end
+
+ def to_html
+ substitution = {
+ "&" => "&",
+ "<" => "<",
+ ">" => ">"
+ }
+ s = clone
+ substitution.each do |k, v|
+ s.gsub!(k, v)
+ end
+ s
+ end
end
diff --git a/lib/rbpkg/repo.rb b/lib/rbpkg/repo.rb
index ddcd125..a18e29a 100644
--- a/lib/rbpkg/repo.rb
+++ b/lib/rbpkg/repo.rb
@@ -32,13 +32,47 @@ class Rbpkg::Repo
end
def checkout(branch)
- verbose 3, "repo(#{name.inspect}).checkout"
+ verbose(3, "repo(#{name.inspect}).checkout")
sh_branch=sh_quote(branch)
cmd! "cd #{sh_quote(src_dir!)} && git fetch #{sh_quote(remote)} #{sh_branch} && git checkout #{sh_branch} -- && git submodule update"
end
+ def ci(ref, commit)
+ verbose(3, "repo(#{name.inspect}).ci(#{commit.inspect})")
+ Rbpkg::Log.add(ci_log_name_ref(ref))
+ Rbpkg::Log.add(ci_log_name_commit(commit))
+ sh_name = sh_quote(name)
+ sh_profile = sh_quote(ci_dir + '/etc/profile')
+ if File.directory?(ci_dir)
+ Rbpkg::Log.add("rbpkg_ci.#{name}.upgrade")
+ if cmd ". #{sh_profile} && rbpkg checkout #{sh_quote(commit)} #{sh_name} && rbpkg upgrade #{sh_name}"
+ Rbpkg::Log.ok("rbpkg_ci.#{name}.upgrade")
+ else
+ Rbpkg::Log.ko("rbpkg_ci.#{name}.upgrade")
+ end
+ end
+ Rbpkg::Log.add("rbpkg_ci.#{name}.install")
+ cmd! "rbpkg_bootstrap -f #{sh_quote(ci_dir)}"
+ cmd! ". #{sh_profile} && rbpkg clone #{sh_name} && rbpkg checkout #{sh_quote(commit)} #{sh_name} && rbpkg install #{sh_name}"
+ Rbpkg::Log.ok("rbpkg_ci.#{name}.install")
+ Rbpkg::Log.ok(ci_log_name_commit(commit))
+ Rbpkg::Log.ok(ci_log_name_ref(ref))
+ end
+
+ def ci_dir
+ @ci_dir || @ci_dir = "#{Rbpkg.ci_dir}/#{name}"
+ end
+
+ def ci_log_name_commit(commit)
+ "rbpkg_ci.#{name}.commit_#{commit}"
+ end
+
+ def ci_log_name_ref(ref)
+ "rbpkg_ci.#{name}.ref_#{ref}"
+ end
+
def clean_all
- verbose 3, "repo(#{name.inspect}).clean_all"
+ verbose(3, "repo(#{name.inspect}).clean_all")
clean_fake
clean_build
clean_configure
@@ -331,6 +365,11 @@ class Rbpkg::Repo
cmd! "cd #{sh_quote(src_dir!)} && git pull && git submodule update"
end
+ def pull_possible?
+ File.directory?(src_dir) &&
+ system("git -C #{sh_quote(src_dir)} symbolic-ref HEAD >/dev/null 2>&1")
+ end
+
@required_by = nil
def required_by
@required_by || @required_by =
@@ -430,7 +469,7 @@ class Rbpkg::Repo
def upgrade
verbose 3, "repo(#{name.inspect}).upgrade"
- pull
+ pull if pull_possible?
return if installed_version == version
package
uninstall
diff --git a/share/icon/64x64/ci.png b/share/icon/64x64/ci.png
new file mode 100644
index 0000000..9b8a020
Binary files /dev/null and b/share/icon/64x64/ci.png differ
diff --git a/share/icon/64x64/status_ko.png b/share/icon/64x64/status_ko.png
new file mode 100644
index 0000000..a0d60d3
Binary files /dev/null and b/share/icon/64x64/status_ko.png differ
diff --git a/share/icon/64x64/status_ok.png b/share/icon/64x64/status_ok.png
new file mode 100644
index 0000000..a189b4c
Binary files /dev/null and b/share/icon/64x64/status_ok.png differ
diff --git a/share/icon/64x64/status_running.png b/share/icon/64x64/status_running.png
new file mode 100644
index 0000000..6f4e27e
Binary files /dev/null and b/share/icon/64x64/status_running.png differ
diff --git a/share/icon/64x64/status_unknown.png b/share/icon/64x64/status_unknown.png
new file mode 100644
index 0000000..62703fe
Binary files /dev/null and b/share/icon/64x64/status_unknown.png differ