]> git.99rst.org Git - irssi-scripts.irssi.org.git/commitdiff
Add travis testing to Irssi scripts.
authorAilin Nemui <redacted>
Mon, 16 Jun 2014 02:11:29 +0000 (04:11 +0200)
committerAilin Nemui <redacted>
Tue, 24 Jun 2014 16:28:59 +0000 (18:28 +0200)
14 files changed:
.travis.yml [new file with mode: 0644]
README.markdown
_testing/README.markdown [new file with mode: 0644]
_testing/_get_files_arr.zsh [new file with mode: 0644]
_testing/_irssi_test.pl [new file with mode: 0644]
_testing/config.yml [new file with mode: 0644]
_testing/report-test.zsh [new file with mode: 0755]
_testing/run-test.zsh [new file with mode: 0755]
_testing/travis/_get_files_arr.zsh [new file with mode: 0644]
_testing/travis/autoinstall-perl-prereqs.zsh [new file with mode: 0755]
_testing/travis/extract-artefacts.zsh [new file with mode: 0755]
_testing/travis/load-old-artefacts.zsh [new file with mode: 0755]
_testing/travis/show-failures.zsh [new file with mode: 0755]
_testing/travis/update-scripts-yaml.pl [new file with mode: 0644]

diff --git a/.travis.yml b/.travis.yml
new file mode 100644 (file)
index 0000000..64d0fcb
--- /dev/null
@@ -0,0 +1,52 @@
+language: c
+before_install:
+- sudo apt-get update -qq
+- sudo apt-get build-dep -qq irssi libperl-prereqscanner-perl libperl-critic-perl
+  cpanminus
+- sudo apt-get install -qq lynx zsh apt-file libyaml-tiny-perl libtest-most-perl libgetopt-long-descriptive-perl
+  libwww-perl liblog-log4perl-perl libdatetime-perl libmodule-runtime-perl libparams-classify-perl
+  libtime-duration-parse-perl
+- perl -V
+- wget -qO- https://raw.githubusercontent.com/miyagawa/cpanminus/master/cpanm | sudo
+  perl - App::cpanminus
+- sudo cpanm -q --skip-satisfied Perl::Critic Perl::PrereqScanner PPIx::XPath
+- git clone -q git://github.com/irssi/irssi irssi-head
+- pushd irssi-head
+- ./autogen.sh --with-perl=module 2>/dev/null | tail -n 17
+- make >/dev/null 2>&1
+- sudo make install >/dev/null
+- popd
+- sudo apt-get install -qq `perl -MYAML::Tiny=LoadFile -e'print qq{@{LoadFile(+shift)->{additional_system_deps}}}'
+  _testing/config.yml`
+- |
+  if [ $TRAVIS_PULL_REQUEST = false ] && [ $USE_ARTEFACTS_CACHE = yes ] && [ $EXTRACT_TEST_ARTEFACTS = yes ]; then
+    ./_testing/travis/load-old-artefacts.zsh
+  fi
+- ./_testing/travis/autoinstall-perl-prereqs.zsh
+install:
+- true
+before_script:
+- ./_testing/run-test.zsh
+- |
+  if [ $TRAVIS_PULL_REQUEST != false ]; then
+    git diff --stat $TRAVIS_BRANCH
+  fi
+script:
+- ./_testing/report-test.zsh
+after_script:
+- ./_testing/travis/show-failures.zsh
+- |
+  if [ $TRAVIS_PULL_REQUEST = false ] && $TRAVIS_SECURE_ENV_VARS; then
+    perl ./_testing/travis/update-scripts-yaml.pl
+  fi
+- |
+  if [ $TRAVIS_PULL_REQUEST = false ] && $TRAVIS_SECURE_ENV_VARS && [ $EXTRACT_TEST_ARTEFACTS = yes ]; then
+    ./_testing/travis/extract-artefacts.zsh
+  fi
+branches:
+  only:
+  - gh-pages
+env:
+  global:
+  - USE_ARTEFACTS_CACHE=yes
+  - EXTRACT_TEST_ARTEFACTS=yes
index 2785b50b49f0e472a3b274c430746b2a558e3f67..cdb3dfd530d34e25bf5f0c7c2a2e55628d8b6576 100644 (file)
@@ -3,6 +3,8 @@
 This repository contains scripts available at
 [scripts.irssi.org](http://scripts.irssi.org).
 
+[![Build Status](https://travis-ci.org/irssi/scripts.irssi.org.svg?branch=gh-pages)](https://travis-ci.org/irssi/scripts.irssi.org)
+
 ### Contributing
 
 To add or modify a script do the following:
diff --git a/_testing/README.markdown b/_testing/README.markdown
new file mode 100644 (file)
index 0000000..0a5b751
--- /dev/null
@@ -0,0 +1,44 @@
+Irssi Scripts Testing
+---------------------
+
+Here, combined with the .travis.yml in root, are the files to do some
+test reports on Irssi scripts.
+
+Main test runner is run-test.zsh. These tests are done:
+* Try to load the script in irssi
+* Check perlcritic report
+
+Evaluation of test success is done in report-test.zsh. Currently the
+following criteria lead to fail:
+* Script doesn't compile/load
+* Script doesn't use strict; or uses two-arg "open"
+* Script doesn't define %IRSSI and $VERSION
+
+The output table is as follows:
+- LOAD:  did the script compile/load successfully?
+- HDR:   was %IRSSI and $VERSION given?
+- CRIT:  did it use strict; and three-arg "open"?
+- SCORE: the cumulated perlcritic score, high score *might* be an
+         indication of bad code style, but this should be read with
+         extreme care
+- PASS:  did it pass the test as by the criteria defined above?
+
+Detailed perlcitic report and Irssi log can be viewed from
+show-failures.zsh output. It also includes the extracted .yml
+definition *if* the script compiled cleanly. This can be used as a
+guidance for reviewers, but a lot of perl "critic" is stupid and a
+style question only.
+
+Errors and warnings visible in the Irssi log can serve as further
+pointers to both authors and reviewers.
+
+The following keys are recognised in config.yml:
+
+* additional_system_deps: - list of ubuntu packages to install via
+                            apt-get
+* cpan:
+  * broken_tests: - modules where to skip tests, that would otherwise
+                    hang Travis
+  * broken_modules: - modules to never auto-install, for example
+                      because they hang Travis
+* whitelist: - list of scripts that are allowed to fail
diff --git a/_testing/_get_files_arr.zsh b/_testing/_get_files_arr.zsh
new file mode 100644 (file)
index 0000000..6c8670e
--- /dev/null
@@ -0,0 +1,6 @@
+if [[ $TRAVIS == true ]] {
+    . ./_testing/travis/_get_files_arr.zsh
+} \
+else {
+    filelist=($@)
+}
diff --git a/_testing/_irssi_test.pl b/_testing/_irssi_test.pl
new file mode 100644 (file)
index 0000000..1da8f59
--- /dev/null
@@ -0,0 +1,78 @@
+use strict;
+use warnings;
+
+BEGIN {
+    *CORE::GLOBAL::exit = sub (;$) {
+       require Carp;
+       Carp::croak("script tried to call exit @_");
+    };
+}
+
+my $CURRENT_SCRIPT = $ENV{CURRENT_SCRIPT};
+my $PWD = $ENV{PWD};
+my $SWD = "$PWD/../..";
+Irssi::command('^window log on');
+Irssi::command("script load $CURRENT_SCRIPT");
+Irssi::command('^window log off');
+
+my ($package) = grep { !/^_/ } keys %Irssi::Script::;
+
+require YAML::Tiny;
+require Module::CoreList;
+require CPAN::Meta::Requirements;
+require Perl::PrereqScanner;
+my $prereq_results = Perl::PrereqScanner->new->scan_file("$SWD/scripts/$CURRENT_SCRIPT.pl");
+my @modules = grep {
+    $_ ne 'perl' &&
+       $_ ne 'Irssi' && $_ ne 'Irssi::UI' && $_ ne 'Irssi::TextUI' && $_ ne 'Irssi::Irc'
+       && !Module::CoreList->first_release($_)
+} sort keys %{ $prereq_results->as_string_hash };
+
+my (%info, $version);
+unless (defined $package) {
+    my %fail = (failed => 1, name => $CURRENT_SCRIPT);
+    $fail{modules} = \@modules if @modules;
+    { open my $ef, '>:utf8', "failed.yml";
+      print $ef YAML::Tiny::Dump([\%fail]); }
+    # Grep for the code instead
+    require PPI;
+    require PPIx::XPath;
+    require Tree::XPathEngine;
+    my $xp = Tree::XPathEngine->new;
+    my $doc = PPI::Document->new("$SWD/scripts/$CURRENT_SCRIPT.pl");
+    my ($version_code) = $xp->findnodes(q{//*[./Token-Symbol[1] = "$VERSION" and ./Token-Operator = "="]}, $doc);
+    my ($irssi_code)   = $xp->findnodes(q{//*[./Token-Symbol[1] = "%IRSSI" and ./Token-Operator = "="]}, $doc);
+    $version = eval "no strict; package DUMMY; undef; $version_code";
+    %info    = eval "no strict; package DUMMY; (); $irssi_code";
+}
+else {
+    %info = do { no strict 'refs'; %{"Irssi::Script::${package}IRSSI"} };
+    $version = do { no strict 'refs'; ${"Irssi::Script::${package}VERSION"} };
+}
+delete $info{''};
+for my $rb (keys %info) {
+    delete $info{$rb} if $rb =~ /\(0x[[:xdigit:]]+\)$/;
+    delete $info{$rb} unless defined $info{$rb};
+}
+
+if (!%info || !defined $info{name}) {
+    open my $ef, '>>', "perlcritic.log";
+    print $ef 'No %IRSSI header in script or name not given. (Severity: 6)', "\n";
+    $info{name} //= $CURRENT_SCRIPT;
+}
+if (!defined $version) {
+    open my $ef, '>>', "perlcritic.log";
+    print $ef 'Missing $VERSION in script. (Severity: 6)', "\n";
+}
+else {
+    $info{version} = $version;
+}
+chomp(my $loginfo = `git log 2d0759e6... -1 --format=%ai -- "$SWD/scripts/$CURRENT_SCRIPT.pl"`);
+if ($loginfo) {
+    my ($date, $time) = split ' ', $loginfo;
+    $info{modified} = "$date $time";
+}
+$info{modules} = \@modules if @modules;
+$info{default_package} = $package =~ s/::$//r if $package;
+{ open my $ef, '>:utf8', "info.yml";
+  print $ef YAML::Tiny::Dump([\%info]); }
diff --git a/_testing/config.yml b/_testing/config.yml
new file mode 100644 (file)
index 0000000..e5118c4
--- /dev/null
@@ -0,0 +1,205 @@
+---
+additional_system_deps:
+  - libconfig-simple-perl
+  - libyaml-perl
+  - libcrypt-ssleay-perl
+  - libclass-inspector-perl
+  - libsoap-lite-perl
+  - libipc-run3-perl
+  - libprobe-perl-perl
+  - libtest-script-perl
+  - libtext-glob-perl
+  - libterm-readline-perl-perl
+cpan:
+  broken_tests:
+    - Geo::Weather
+    - Net::Google
+# This is a whitelist of scripts who are currently allowed to fail
+# testing. They should be fixed and then removed from the whitelist.
+whitelist:
+  - act_fifo
+  - act
+  - aidle
+  - amaroknp
+  - apm
+  - armeija
+  - autoaway
+  - autolimit
+  - autoopper
+  - auto_whois
+  - autowhois
+  - autowhois_simple
+  - away2web
+  - away
+  - awayproxy
+  - babelirc
+  - bandwidth
+  - beep_beep
+  - beep
+  - bitlbee_join_notice
+  - bitlbee_join_notice-pre-3.0
+  - blowjob
+  - buf
+  - centericq
+  - cgrep
+  - chanshare
+  - clones
+  - colorkick
+  - connectcmd
+  - cron
+  - dau
+  - dcc_ip
+  - dccmove
+  - dccself
+  - dccstat
+  - deliciousurl
+  - df
+  - dictcomplete
+  - dnsspam
+  - doc
+  - emaildb1.0
+  - email_privmsgs
+  - eng_no_translate_dpryo
+  - exec_clean
+  - extaway
+  - fakectcp
+  - file
+  - findbot
+  - find
+  - fleech
+  - friends_peder
+  - friends_shasta
+  - fserve
+  - getop
+  - gimmie
+  - gsi
+  - hddtemp
+  - hilightwin
+  - hipchat_complete
+  - hitcount
+  - hlbot
+  - hl
+  - hostname
+  - ignore_log
+  - ignoreoc
+  - iMPD
+  - intjoin
+  - irc_chess
+  - irccomplete
+  - ircgallery
+  - ircgmessagenotify
+  - irssiBlaster
+  - irssiq
+  - isdn
+  - ixmmsa
+  - kblamehost
+  - keepnick
+  - kicks
+  - kill_fake_gets
+  - kills
+  - l33tmusic
+  - lastfm
+  - lastspoke
+  - licq
+  - linkchan
+  - listen
+  - loadavg
+  - localize
+  - log2ansi
+  - logcompress
+  - ls
+  - lwho
+  - mailcheck_imap
+  - mailcheck_mbox_flux
+  - mailcheck_pop3_kimmo
+  - mail
+  - mangle
+  - mass_hilight_blocker
+  - mkshorterlink
+  - monitor
+  - mpg123
+  - my_beep
+  - mysqlurllogger
+  - nact
+  - newsline
+  - nickban
+  - nickcolor
+  - nicklist
+  - nickserv
+  - nm
+  - noisyquery
+  - notes
+  - noticemove
+  - ogg123
+  - oidenty
+  - 'on'
+  - opnotice
+  - orphamp
+  - osd
+  - page-c0ffee
+  - page_reeler
+  - pager
+  - paste-derwan
+  - paste_kimmoke
+  - pggb_sound
+  - query
+  - queryresume
+  - quitmsg
+  - quitrand
+  - quizgr
+  - quizmaster-fr
+  - quizmaster
+  - quiz
+  - randaway
+  - randname
+  - redirect
+  - relm
+  - remote
+  - reorder
+  - scriptassist
+  - scripthelp
+  - scroller
+  - servercomplete
+  - seti
+  - shorturl
+  - showhilight
+  - sms
+  - stocks
+  - sysinfo270-irssi
+  - sysinfo277-irssi
+  - sysinfo_dg
+  - sysinfo_juerd
+  - sysinfoplus
+  - talk
+  - thistory
+  - timezones
+  - title
+  - topicsed
+  - trackbar
+  - tracknick
+  - translit
+  - tvmusor
+  - twprompt
+  - twsocials
+  - twtopic
+  - u
+  - uptime
+  - urlfeed
+  - urlgrab
+  - url_log
+  - urlplot
+  - usercount
+  - userhost
+  - users
+  - version-stat
+  - wa
+  - watch
+  - weather
+  - wkb
+  - wordcompletition
+  - xauth
+  - xetra
+  - xmms2
+  - xmmsinfo
+  - xmms
+  - xqf
diff --git a/_testing/report-test.zsh b/_testing/report-test.zsh
new file mode 100755 (executable)
index 0000000..ffe536a
--- /dev/null
@@ -0,0 +1,63 @@
+#!/bin/zsh
+
+local failmark="\e[31m✘\e[0m"
+local passmark="\e[32m✔\e[0m"
+local skipmark="\e[33m☡\e[0m"
+local failed=0
+local T=
+
+if [[ $MARKDOWN_REPORT == 1 ]] {
+    echo '## Irssi Scripts Test Report'
+    failmark=:x:
+    passmark=:white_check_mark:
+    skipmark=:construction:
+    T="|"
+} \
+else {
+    echo '============================== TEST REPORT ============================='
+}
+printf "%32s $T LOAD $T HDR $T CRIT $T SCORE $T PASS\n"
+if [[ $MARKDOWN_REPORT == 1 ]] {
+ echo "----: $T :--: $T :-: $T :--: $T ----: $T :---:"
+}
+typeset -a cached_run
+cached_run=()
+REPORT_STAGE=yes
+. ./_testing/_get_files_arr.zsh
+
+typeset -A allow_fail
+allow_fail=($(perl -MYAML::Tiny=LoadFile -e'print "$_ 1 " for @{LoadFile(+shift)->{whitelist}}' _testing/config.yml))
+
+for scriptfile ($filelist) {
+    if [[ $MARKDOWN_REPORT == 1 ]] { print -n '[' }
+    printf "%32s " $scriptfile:t:r
+    if [[ $MARKDOWN_REPORT == 1 ]] { print -n '](Test/'$scriptfile:t:r'/)' }
+    print -n $T
+    local pass=0
+    if [[ -f "Test/${scriptfile:t:r}/failed.yml" ]] { print -n '  '$failmark'   ' } \
+    else { print -n '  '$passmark'   '; ((++pass)) }; print -n $T
+    if { grep -qs 'Severity: 6' "Test/${scriptfile:t:r}/perlcritic.log" } { print -n '  '$failmark'   ' } \
+    else { print -n '  '$passmark'   '; ((++pass)) }; print -n $T
+    if { grep -qs 'Code before strictures are enabled\|Two-argument "open" used' "Test/${scriptfile:t:r}/perlcritic.log" }  { print -n '  '$failmark'   ' } \
+    else { print -n '  '$passmark'   '; ((++pass)) }; print -n $T
+    perl -ne '$score += $1 -1 if /Severity: (\d+)/; END { printf "%3d", $score }' "Test/${scriptfile:t:r}/perlcritic.log" 2>/dev/null
+    print -n '   '$T
+    if [[ $pass -lt 3 ]]  {
+       if [[ -n $allow_fail[$scriptfile:t:r] ]] {
+           print -n '  '$skipmark'   '
+       } \
+       else {
+           print -n '  '$failmark'   '
+           if [[ $failed -lt 254 ]] { ((++failed)) }
+       }
+    } \
+    else {
+       print -n '  '$passmark'   '; ((++pass))
+       echo 1>"Test/${scriptfile:t:r}/passed"
+    }
+    if [[ $+cached_run[(r)$scriptfile] -gt 0 ]] {
+        print -n $T' (c)'
+    }
+    echo
+}
+exit $failed
diff --git a/_testing/run-test.zsh b/_testing/run-test.zsh
new file mode 100755 (executable)
index 0000000..ac34c06
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/zsh
+mkdir -p Test
+local base_path="`pwd`"
+local test_script="$base_path/_testing/_irssi_test.pl"
+
+. ./_testing/_get_files_arr.zsh
+
+for scriptfile ($filelist) {
+    rm -rf "Test/${scriptfile:t:r}"
+    mkdir "Test/${scriptfile:t:r}"
+    perlcritic --theme certrule --exclude RequireEndWithOne -2 $scriptfile >"Test/${scriptfile:t:r}/perlcritic.log"
+    pushd Test
+    rm -fr .home
+    mkdir .home
+    ln -s ../../scripts .home
+    local filename="$base_path/$scriptfile"
+    <<STARTUP>.home/startup
+^set settings_autosave off
+^set use_status_window off
+^set autocreate_windows off
+^set -clear autocreate_query_level
+^set autoclose_windows off
+^set reuse_unused_windows on
+^set -clear log_close_string
+^set -clear log_day_changed
+^set -clear log_open_string
+^set log_timestamp * 
+^load perl
+^script exec \$\$^W = 1
+run ${(qqq)test_script}
+^quit
+STARTUP
+    pushd ${scriptfile:t:r}
+    env TERM=xterm CURRENT_SCRIPT="$scriptfile:t:r" irssi --home="$base_path/Test/.home" >/dev/null 2>stderr.log
+    if [[ ! -s stderr.log ]] { rm -f stderr.log }
+    popd
+    printf . >&2
+    popd
+    perl -i -pe 's,\Q$ENV{PWD}/Test/.home/scripts/\E,,g;s,\Q$ENV{PWD}/Test/.home\E,..,g;s,\Q$ENV{PWD}\E,...,g;s,\(\@INC contains:.*? \.\),,g' ~/irc.log.*
+    mv ~/irc.log.* "Test/${scriptfile:t:r}/irssi.log"
+}
+exit 0
diff --git a/_testing/travis/_get_files_arr.zsh b/_testing/travis/_get_files_arr.zsh
new file mode 100644 (file)
index 0000000..9fb6324
--- /dev/null
@@ -0,0 +1,38 @@
+filelist=(scripts/*.pl)
+if [[ $TRAVIS_PULL_REQUEST != false ]] {
+    local -a scriptfiles
+    OIFS=$IFS; IFS=$'\n'
+    scriptfiles=($(git diff --numstat $TRAVIS_BRANCH|cut -f3|grep '^scripts/.*\.pl'))
+    IFS=$OIFS
+    if [[ $#scriptfiles -gt 0 ]] {
+       filelist=($scriptfiles)
+    }
+} \
+elif [[ $USE_ARTEFACTS_CACHE = yes ]] {
+    local -a cache_allowed
+    OIFS=$IFS; IFS=$'\n'
+    cache_allowed=(scripts/${^$(grep -v __ARTEFACTS_CI__ old-artefacts/can-use-cache | cut -f2- -d\  )})
+    IFS=$OIFS
+
+    if [[ $REPORT_STAGE == yes ]] {
+        autoload -Uz zargs
+        { zargs -r -- old-artefacts/Test/${^cache_allowed:t:r} -- mv -nt Test } 2>/dev/null
+        cached_run=($cache_allowed)
+    } \
+    else {
+        autoload -Uz is-at-least
+        if { is-at-least 5.0.0 } {
+            filelist=(${filelist:|cache_allowed})
+        } \
+        else {
+           # manually filter the array in zsh4
+            local -a scriptfiles
+            for x ($filelist) {
+                if [[ $+cache_allowed[(r)$x] -eq 0 ]] {
+                    scriptfiles+=($x)
+                }
+            }
+            filelist=($scriptfiles)
+        }
+    }
+}
diff --git a/_testing/travis/autoinstall-perl-prereqs.zsh b/_testing/travis/autoinstall-perl-prereqs.zsh
new file mode 100755 (executable)
index 0000000..11c9824
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/zsh
+
+. ./_testing/_get_files_arr.zsh
+
+local -a modlist
+modlist=($(scan-perl-prereqs $filelist))
+
+sudo apt-file update >/dev/null 2>&1
+
+local -a ubu_pkgs
+local -a cpan_mods
+for mod ($modlist) {
+    mod=${mod%\~*}
+    if [[ $mod != Irssi* && $mod != feature ]] {
+        if { ! perl -M$mod -E1 2>/dev/null } {
+            local -a ubu_pkg
+            ubu_pkg=($(apt-file -l search "/perl5/${mod//:://}.pm"))
+            if [[ $#ubu_pkg -gt 0 ]] { ubu_pkgs+=($ubu_pkg) } \
+            else { cpan_mods+=($mod) }
+        }
+    }
+}
+
+if [[ $#ubu_pkgs -gt 0 ]] { sudo apt-get install -qq $ubu_pkgs }
+
+typeset -A broken_tests
+typeset -A broken_mods
+
+broken_tests=($(perl -MYAML::Tiny=LoadFile -e'print "$_ 1 " for @{LoadFile(+shift)->{cpan}{broken_tests}}' _testing/config.yml))
+broken_mods=($(perl -MYAML::Tiny=LoadFile -e'print "$_ 1 " for @{LoadFile(+shift)->{cpan}{broken_modules}}' _testing/config.yml))
+
+for mod ($cpan_mods) {
+    if { ! perl -M$mod -E1 2>/dev/null } {
+        local skip_test=
+        if [[ -n $broken_tests[$mod] ]] {
+            skip_test=--notest
+            echo Skipping broken test on $mod
+        }
+        if [[ -n $broken_mods[$mod] ]] {
+            echo SKIPPING AUTOINSTALL OF BROKEN MODULE $mod
+        } \
+        else {
+            echo Auto-installing $mod
+            sudo cpanm -q --skip-satisfied $skip_test $mod
+        }
+    }
+}
+exit 0
diff --git a/_testing/travis/extract-artefacts.zsh b/_testing/travis/extract-artefacts.zsh
new file mode 100755 (executable)
index 0000000..f383536
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/zsh
+if [[ -z $REPO_LOGIN_TOKEN || -z $TRAVIS_REPO_SLUG ]] { exit 1 }
+autoload -Uz zargs
+
+if { ! git clone -b ci-artefacts https://github.com/$TRAVIS_REPO_SLUG artefacts } {
+    mkdir artefacts && git init artefacts
+    pushd artefacts
+    git remote add origin https://github.com/$TRAVIS_REPO_SLUG
+    git checkout -b ci-artefacts
+    popd
+}
+
+pushd artefacts
+git config user.email "scripts@irssi.org"
+git config user.name "Irssi Scripts Helper"
+git config credential.helper store
+
+git rm -qrf .
+
+echo "This branch stores the travis-ci results for $TRAVIS_REPO_SLUG
+See [the testing read-me](../gh-pages/_testing/) for details." > README.markdown
+pushd ..
+MARKDOWN_REPORT=1 ./_testing/report-test.zsh >> artefacts/README.markdown
+popd
+echo >> README.markdown
+echo "$TRAVIS_COMMIT | $TRAVIS_BUILD_NUMBER" >> README.markdown
+
+mv ../Test .
+rm -fr Test/.home
+zargs -r -- Test/*/passed(N) -- rm
+if [[ $USE_ARTEFACTS_CACHE == yes ]] {
+    mv ../old-artefacts/new-changed-info changed-info
+}
+
+git add .
+git commit -q -m "ci artefacts for $TRAVIS_COMMIT
+
+[skip ci]"
+
+git push -u origin ci-artefacts
diff --git a/_testing/travis/load-old-artefacts.zsh b/_testing/travis/load-old-artefacts.zsh
new file mode 100755 (executable)
index 0000000..f28e38f
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/zsh
+if { ! git clone -q --depth 1 -b ci-artefacts git://github.com/$TRAVIS_REPO_SLUG.git old-artefacts } {
+   mkdir old-artefacts
+}
+echo $(git log --format=%H -1 _testing .travis.yml) __ARTEFACTS_CI__>old-artefacts/new-changed-info
+for f (scripts/*.pl) {
+    echo $(git hash-object $f) ${f:t} >>old-artefacts/new-changed-info
+}
+grep -sxFf old-artefacts/new-changed-info old-artefacts/changed-info >old-artefacts/can-use-cache
+if { ! grep -q __ARTEFACTS_CI__ old-artefacts/can-use-cache } {
+    :>|old-artefacts/can-use-cache
+}
diff --git a/_testing/travis/show-failures.zsh b/_testing/travis/show-failures.zsh
new file mode 100755 (executable)
index 0000000..1ce6229
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/zsh
+
+. ./_testing/_get_files_arr.zsh
+
+if [[ $TRAVIS_PULL_REQUEST != false ]] {
+    echo '======== INTEGRATION REPORT ========='
+    for scriptfile ($filelist) {
+        echo '--- '$scriptfile:t
+        if [[ -f "Test/${scriptfile:t:r}/failed.yml" ]] {
+           echo "FATAL: SCRIPT FAILED TO LOAD  "
+       }
+        cat "Test/${scriptfile:t:r}/stderr.log" 2>/dev/null
+        cat "Test/${scriptfile:t:r}/irssi.log"
+       echo
+       echo 'Source code critic:'
+       cat "Test/${scriptfile:t:r}/perlcritic.log"
+       echo
+    }
+    echo
+    echo '======== YAML DATABASE ========'
+    for scriptfile ($filelist) {
+        if [[ ! -f "Test/${scriptfile:t:r}/failed.yml" ]] {
+           cat "Test/${scriptfile:t:r}/info.yml"
+       }
+    }
+} \
+else {
+    echo '============= DETAILED FAILURE REPORTS ============='
+    for scriptfile ($filelist) {
+        if [[ -f "Test/${scriptfile:t:r}/failed.yml" ]] {
+           echo '--- '$scriptfile:t
+           cat "Test/${scriptfile:t:r}/stderr.log" 2>/dev/null
+           cat "Test/${scriptfile:t:r}/irssi.log"
+           echo
+        }
+    }
+}
diff --git a/_testing/travis/update-scripts-yaml.pl b/_testing/travis/update-scripts-yaml.pl
new file mode 100644 (file)
index 0000000..d3384a8
--- /dev/null
@@ -0,0 +1,100 @@
+use strict; use warnings;
+use YAML::Tiny;
+
+my @docs;
+{ open my $ef, '<:utf8', '_data/scripts.yaml' or die $!;
+  @docs = Load(do { local $/; <$ef> });
+}
+
+my %oldmeta;
+for (@{$docs[0]//[]}) {
+    $oldmeta{$_->{filename}} = $_;
+}
+
+my %newmeta;
+for my $file (<scripts/*.pl>) {
+    my ($filename, $base) =
+       $file =~ m,^scripts/((.*)\.pl)$,;
+    my $info_file = "Test/$base/info.yml";
+    my @cdoc;
+    if (-f $info_file && open my $ef, '<:utf8', $info_file) {
+       local $@;
+       @cdoc = eval { Load(do { local $/; <$ef> }); };
+       if ($@) {
+           print "ERROR $base: $@\n";
+           @cdoc=();
+       }
+    }
+    if (@cdoc) {
+       $newmeta{$filename} = $cdoc[0][0];
+       for my $copykey (qw(modified version)) {
+           unless (defined $newmeta{$filename}{$copykey}) {
+               $newmeta{$filename}{$copykey}
+                   = $oldmeta{$filename}{$copykey}
+                       if defined $oldmeta{$filename}{$copykey};
+           }
+       }
+       $newmeta{$filename}{filename} = $filename;
+       my $modules = delete $newmeta{$filename}{modules};
+       $newmeta{$filename}{modules}
+           = join ' ', @$modules
+               if 'ARRAY' eq ref $modules;
+    }
+    elsif (exists $oldmeta{$filename}) {
+       print "META-INF FOR $base NOT FOUND\n";
+       system "ls 'Test/$base/'*";
+       $newmeta{$filename} = $oldmeta{$filename};
+    }
+    else {
+       print "MISSING META FOR $base\n";
+    }
+}
+my @newdoc = map { $newmeta{$_} } sort keys %newmeta;
+{ open my $ef, '>:utf8', '_data/scripts.yaml' or die $!;
+  print $ef Dump \@newdoc;
+}
+
+my @config;
+if (open my $ef, '<:utf8', '_testing/config.yml') {
+    @config = Load(do { local $/; <$ef> });
+}
+if (@config && @{$config[0]{whitelist}//[]}) {
+    my $changed;
+    my @wl;
+    for my $sf (@{$config[0]{whitelist}}) {
+       if (-s "Test/$sf:passed") {
+           $changed = 1;
+       }
+       else {
+           push @wl, $sf;
+       }
+    }
+    if ($changed) {
+       $config[0]{whitelist} = \@wl;
+       { open my $ef, '>:utf8', '_testing/config.yml' or die $!;
+         print $ef Dump @config;
+        }
+    }
+}
+
+if (exists $ENV{REPO_LOGIN_TOKEN} && exists $ENV{TRAVIS_REPO_SLUG}) {
+    { open my $cred, '>', "$ENV{HOME}/.git-credentials" or die $!;
+      print $cred "https://$ENV{REPO_LOGIN_TOKEN}:x-oauth-basic\@github.com\n";
+    }
+    system qq[
+git config user.email "scripts\@irssi.org"
+git config user.name "Irssi Scripts Helper"
+git config credential.helper store
+git config remote.origin.url https://github.com/$ENV{TRAVIS_REPO_SLUG}
+git checkout '$ENV{TRAVIS_BRANCH}'
+if [ "\$(git log -1 --format=%an)" != "\$(git config user.name)" -a \\
+     "\$(git log -1 --format=%cn)" != "\$(git config user.name)" ]; then
+    git add _data/scripts.yaml
+    git commit -m 'automatic scripts database update for $ENV{TRAVIS_COMMIT}
+
+[skip ci]'
+    git config push.default simple
+    git push origin
+fi
+];
+}
git clone https://git.99rst.org/PROJECT