From 4e5aec17a85ee1b72ef0f21234d11e987522cf1a Mon Sep 17 00:00:00 2001 From: Marin Nozhchev Date: Wed, 1 Oct 2025 21:41:59 +0300 Subject: [PATCH 1/7] tests: use local ts --- Makefile | 6 +- tools/ts | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 3 deletions(-) create mode 100755 tools/ts diff --git a/Makefile b/Makefile index 54752cc..33e344e 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,8 @@ test: go test -race -cover -covermode atomic -v -vet=all -timeout 15m -p 1\ ./... \ -args -test.gocoverdir="${PWD}/coverage/covdata" \ - | ts -s -# NB: ts command requires moreutils package; awk trick from https://stackoverflow.com/a/25764579 doesn't stream output + | tools/ts -s + go tool covdata percent -i=./coverage/covdata # Convert to old text format for coveralls upload go tool covdata textfmt -i=./coverage/covdata -o ./coverage/covprofile @@ -41,4 +41,4 @@ check_tidy: check_modern: go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@v0.20.0 ./... # non-zero exit status on issues found -# nb: modernize is not part of golangci-lint yet - https://github.com/golangci/golangci-lint/issues/686 +# nb: modernize is not part of golangci-lint yet - https://github.com/golangci/golangci-lint/issues/686 diff --git a/tools/ts b/tools/ts new file mode 100755 index 0000000..575ebcc --- /dev/null +++ b/tools/ts @@ -0,0 +1,192 @@ +#!/usr/bin/env perl + +=head1 NAME + +ts - timestamp input + +=head1 SYNOPSIS + +ts [-r] [-i | -s] [-m] [format] + +=head1 DESCRIPTION + +ts adds a timestamp to the beginning of each line of input. + +The optional format parameter controls how the timestamp is formatted, +as used by L. The default format is "%b %d %H:%M:%S". In +addition to the regular strftime conversion specifications, +"%.S" and "%.s" and "%.T" +are like "%S" and "%s" and "%T", but provide subsecond resolution +(ie, "30.00001" and "1301682593.00001" and "1:15:30.00001"). + +If the -r switch is passed, it instead converts existing timestamps in +the input to relative times, such as "15m5s ago". Many common timestamp +formats are supported. Note that the Time::Duration and Date::Parse perl +modules are required for this mode to work. Currently, converting localized +dates is not supported. + +If both -r and a format is passed, the existing timestamps are +converted to the specified format. + +If the -i or -s switch is passed, ts reports incremental timestamps instead of +absolute ones. The default format changes to "%H:%M:%S", and "%.S" and "%.s" can +be used as well. In case of -i, every timestamp will be the time elapsed since +the last timestamp. In case of -s, the time elapsed since start of the program +is used. + +The -m switch makes the system's monotonic clock be used. + +=head1 ENVIRONMENT + +The standard TZ environment variable controls what time zone dates +are assumed to be in, if a timezone is not specified as part of the date. + +=head1 AUTHOR + +Copyright 2006 by Joey Hess + +Licensed under the GNU GPL. + +=cut + +use warnings; +use strict; +use POSIX q{strftime}; +no warnings 'utf8'; + +$|=1; + +my $rel=0; +my $inc=0; +my $sincestart=0; +my $mono=0; +use Getopt::Long; +GetOptions( + "r" => \$rel, + "i" => sub { $inc=1; $sincestart=0 }, + "s" => sub { $inc=0; $sincestart=1 }, + "m" => \$mono +) && @ARGV <= 1 or die "usage: ts [-r] [-i | -s] [-m] [format]\n"; + +if ($rel) { + eval q{ + use Date::Parse; + use Time::Duration; + }; + die $@ if $@; +} + +my $use_format=@ARGV; +my $format="%b %d %H:%M:%S"; +if ($inc || $sincestart) { + $format="%H:%M:%S"; + $ENV{TZ}='GMT'; +} +$format=shift if @ARGV; + +# For subsecond resolution, Time::HiRes is needed. +my $hires=0; +if ($format=~/\%\.[SsT]/ || $mono) { + require Time::HiRes; + use Time::HiRes qw(CLOCK_MONOTONIC); + $hires=1; +} + +my $lastseconds = 0; +my $lastmicroseconds = 0; +my $monodelta; + +if ($mono) { + my $raw_time = Time::HiRes::clock_gettime(CLOCK_MONOTONIC); + $lastseconds = time; + $lastmicroseconds = int(1000000 * ($raw_time - int($raw_time))); + $monodelta = $lastseconds - int($raw_time); +} +elsif ($hires) { + ($lastseconds, $lastmicroseconds) = Time::HiRes::gettimeofday(); +} +else { + $lastseconds = time; +} + + +while () { + if (! $rel) { + if ($hires) { + my $f=$format; + my $seconds; + my $microseconds; + if ($mono) { + my $raw_time = + Time::HiRes::clock_gettime(CLOCK_MONOTONIC) + + $monodelta; + $seconds = int($raw_time); + $microseconds = int(1000000 * ($raw_time - $seconds)); + } + else { + ($seconds, $microseconds) = Time::HiRes::gettimeofday(); + } + + if ($inc || $sincestart) { + my $deltaseconds = $seconds - $lastseconds; + my $deltamicroseconds = $microseconds - $lastmicroseconds; + if ($deltamicroseconds < 0) { + $deltaseconds -= 1; + $deltamicroseconds += 1000000; + } + if ($inc) { + $lastseconds = $seconds; + $lastmicroseconds = $microseconds; + } + $seconds = $deltaseconds; + $microseconds = $deltamicroseconds; + } + my $s=sprintf("%06i", $microseconds); + $f=~s/\%\.([SsT])/%$1.$s/g; + print strftime($f, localtime($seconds)); + } + else { + if ($inc || $sincestart) { + my $seconds = time; + my $deltaseconds = $seconds - $lastseconds; + if ($inc) { + $lastseconds = $seconds; + } + print strftime($format, localtime($deltaseconds)); + } + else { + print strftime($format, localtime); + } + } + print " ".$_; + } + else { + s{\b( + \d\d[-\s\/]\w\w\w # 21 dec 17:05 + (?:\/\d\d+)? # 21 dec/93 17:05 + [\s:]\d\d:\d\d # (time part of above) + (?::\d\d)? # (optional seconds) + (?:\s+[+-]\d\d\d\d)? # (optional timezone) + | + \w{3}\s+\d{1,2}\s+\d\d:\d\d:\d\d # syslog form + | + \d\d\d\d[-:]\d\d[-:]\d\dT\d\d:\d\d:\d\d.\d+Z? # ISO-8601 + | + (?:\w\w\w,?\s+)? # (optional Day) + \d+\s+\w\w\w\s+\d\d+\s+\d\d:\d\d:\d\d + # 16 Jun 94 07:29:35 + (?:\s+\w\w\w|\s[+-]\d\d\d\d)? + # (optional timezone) + | + \w\w\w\s+\w\w\w\s+\d\d\s+\d\d:\d\d + # lastlog format + )\b + }{ + $use_format + ? strftime($format, localtime(str2time($1))) + : concise(ago(time - str2time($1), 2)) + }exg; + + print $_; + } +} From b6a14582c942520dde44705ea8a32f672acba06a Mon Sep 17 00:00:00 2001 From: Marin Nozhchev Date: Wed, 1 Oct 2025 22:14:03 +0300 Subject: [PATCH 2/7] fixup --- tools/ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/ts b/tools/ts index 575ebcc..21e807b 100755 --- a/tools/ts +++ b/tools/ts @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# Copied from https://github.com/pgdr/moreutils/blob/a87889a3bf06fb6be6022b14c152f2f7de608910/ts =head1 NAME From 72db8935e1c1998d9615f1be25ae08388218cc27 Mon Sep 17 00:00:00 2001 From: Marin Nozhchev Date: Wed, 1 Oct 2025 22:15:25 +0300 Subject: [PATCH 3/7] fixup --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64237db..08973b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,9 +25,7 @@ jobs: - name: Build run: go build -v ./... - name: Test - run: | - sudo apt-get install moreutils -y - make test + run: make test - name: Checks run: | make checks From 9fc505657d1d8d22fc5cded37ef076338bac8cd1 Mon Sep 17 00:00:00 2001 From: Marin Nozhchev Date: Wed, 1 Oct 2025 22:38:18 +0300 Subject: [PATCH 4/7] fixup --- .gitignore | 4 +- Makefile | 7 +- tools/ts | 193 ----------------------------------------------------- 3 files changed, 9 insertions(+), 195 deletions(-) delete mode 100755 tools/ts diff --git a/.gitignore b/.gitignore index 05ca3b9..53af89e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ go.work.sum # env file .env -/coverage \ No newline at end of file +/coverage + +tools/ts diff --git a/Makefile b/Makefile index 33e344e..c57cee0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,10 @@ +tools/ts: + mkdir -p tools + wget -O tools/ts https://github.com/pgdr/moreutils/raw/a87889a3bf06fb6be6022b14c152f2f7de608910/ts + chmod +x tools/ts + .PHONY: test -test: +test: tools/ts mkdir -p coverage/covdata # Use the new binary format to ensure integration tests and cross-package calls are counted towards coverage # https://go.dev/blog/integration-test-coverage diff --git a/tools/ts b/tools/ts deleted file mode 100755 index 21e807b..0000000 --- a/tools/ts +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env perl -# Copied from https://github.com/pgdr/moreutils/blob/a87889a3bf06fb6be6022b14c152f2f7de608910/ts - -=head1 NAME - -ts - timestamp input - -=head1 SYNOPSIS - -ts [-r] [-i | -s] [-m] [format] - -=head1 DESCRIPTION - -ts adds a timestamp to the beginning of each line of input. - -The optional format parameter controls how the timestamp is formatted, -as used by L. The default format is "%b %d %H:%M:%S". In -addition to the regular strftime conversion specifications, -"%.S" and "%.s" and "%.T" -are like "%S" and "%s" and "%T", but provide subsecond resolution -(ie, "30.00001" and "1301682593.00001" and "1:15:30.00001"). - -If the -r switch is passed, it instead converts existing timestamps in -the input to relative times, such as "15m5s ago". Many common timestamp -formats are supported. Note that the Time::Duration and Date::Parse perl -modules are required for this mode to work. Currently, converting localized -dates is not supported. - -If both -r and a format is passed, the existing timestamps are -converted to the specified format. - -If the -i or -s switch is passed, ts reports incremental timestamps instead of -absolute ones. The default format changes to "%H:%M:%S", and "%.S" and "%.s" can -be used as well. In case of -i, every timestamp will be the time elapsed since -the last timestamp. In case of -s, the time elapsed since start of the program -is used. - -The -m switch makes the system's monotonic clock be used. - -=head1 ENVIRONMENT - -The standard TZ environment variable controls what time zone dates -are assumed to be in, if a timezone is not specified as part of the date. - -=head1 AUTHOR - -Copyright 2006 by Joey Hess - -Licensed under the GNU GPL. - -=cut - -use warnings; -use strict; -use POSIX q{strftime}; -no warnings 'utf8'; - -$|=1; - -my $rel=0; -my $inc=0; -my $sincestart=0; -my $mono=0; -use Getopt::Long; -GetOptions( - "r" => \$rel, - "i" => sub { $inc=1; $sincestart=0 }, - "s" => sub { $inc=0; $sincestart=1 }, - "m" => \$mono -) && @ARGV <= 1 or die "usage: ts [-r] [-i | -s] [-m] [format]\n"; - -if ($rel) { - eval q{ - use Date::Parse; - use Time::Duration; - }; - die $@ if $@; -} - -my $use_format=@ARGV; -my $format="%b %d %H:%M:%S"; -if ($inc || $sincestart) { - $format="%H:%M:%S"; - $ENV{TZ}='GMT'; -} -$format=shift if @ARGV; - -# For subsecond resolution, Time::HiRes is needed. -my $hires=0; -if ($format=~/\%\.[SsT]/ || $mono) { - require Time::HiRes; - use Time::HiRes qw(CLOCK_MONOTONIC); - $hires=1; -} - -my $lastseconds = 0; -my $lastmicroseconds = 0; -my $monodelta; - -if ($mono) { - my $raw_time = Time::HiRes::clock_gettime(CLOCK_MONOTONIC); - $lastseconds = time; - $lastmicroseconds = int(1000000 * ($raw_time - int($raw_time))); - $monodelta = $lastseconds - int($raw_time); -} -elsif ($hires) { - ($lastseconds, $lastmicroseconds) = Time::HiRes::gettimeofday(); -} -else { - $lastseconds = time; -} - - -while () { - if (! $rel) { - if ($hires) { - my $f=$format; - my $seconds; - my $microseconds; - if ($mono) { - my $raw_time = - Time::HiRes::clock_gettime(CLOCK_MONOTONIC) + - $monodelta; - $seconds = int($raw_time); - $microseconds = int(1000000 * ($raw_time - $seconds)); - } - else { - ($seconds, $microseconds) = Time::HiRes::gettimeofday(); - } - - if ($inc || $sincestart) { - my $deltaseconds = $seconds - $lastseconds; - my $deltamicroseconds = $microseconds - $lastmicroseconds; - if ($deltamicroseconds < 0) { - $deltaseconds -= 1; - $deltamicroseconds += 1000000; - } - if ($inc) { - $lastseconds = $seconds; - $lastmicroseconds = $microseconds; - } - $seconds = $deltaseconds; - $microseconds = $deltamicroseconds; - } - my $s=sprintf("%06i", $microseconds); - $f=~s/\%\.([SsT])/%$1.$s/g; - print strftime($f, localtime($seconds)); - } - else { - if ($inc || $sincestart) { - my $seconds = time; - my $deltaseconds = $seconds - $lastseconds; - if ($inc) { - $lastseconds = $seconds; - } - print strftime($format, localtime($deltaseconds)); - } - else { - print strftime($format, localtime); - } - } - print " ".$_; - } - else { - s{\b( - \d\d[-\s\/]\w\w\w # 21 dec 17:05 - (?:\/\d\d+)? # 21 dec/93 17:05 - [\s:]\d\d:\d\d # (time part of above) - (?::\d\d)? # (optional seconds) - (?:\s+[+-]\d\d\d\d)? # (optional timezone) - | - \w{3}\s+\d{1,2}\s+\d\d:\d\d:\d\d # syslog form - | - \d\d\d\d[-:]\d\d[-:]\d\dT\d\d:\d\d:\d\d.\d+Z? # ISO-8601 - | - (?:\w\w\w,?\s+)? # (optional Day) - \d+\s+\w\w\w\s+\d\d+\s+\d\d:\d\d:\d\d - # 16 Jun 94 07:29:35 - (?:\s+\w\w\w|\s[+-]\d\d\d\d)? - # (optional timezone) - | - \w\w\w\s+\w\w\w\s+\d\d\s+\d\d:\d\d - # lastlog format - )\b - }{ - $use_format - ? strftime($format, localtime(str2time($1))) - : concise(ago(time - str2time($1), 2)) - }exg; - - print $_; - } -} From af4796d80cab34ac4c4d89578f3a55eed25e8fcd Mon Sep 17 00:00:00 2001 From: Marin Nozhchev Date: Wed, 1 Oct 2025 22:43:02 +0300 Subject: [PATCH 5/7] fixup --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c57cee0..58731bb 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ tools/ts: mkdir -p tools - wget -O tools/ts https://github.com/pgdr/moreutils/raw/a87889a3bf06fb6be6022b14c152f2f7de608910/ts + curl -L -o tools/ts https://github.com/pgdr/moreutils/raw/a87889a3bf06fb6be6022b14c152f2f7de608910/ts + @echo "5369255252856847959250559657008535288592f87961732c58614992543415 tools/ts" | sha256sum --check --strict chmod +x tools/ts .PHONY: test From f14844718de1007e1cd6138e9e7019402b4bbf0e Mon Sep 17 00:00:00 2001 From: Marin Nozhchev Date: Wed, 1 Oct 2025 22:46:12 +0300 Subject: [PATCH 6/7] fixup --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 58731bb..ac8672e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ tools/ts: mkdir -p tools curl -L -o tools/ts https://github.com/pgdr/moreutils/raw/a87889a3bf06fb6be6022b14c152f2f7de608910/ts - @echo "5369255252856847959250559657008535288592f87961732c58614992543415 tools/ts" | sha256sum --check --strict + @echo "96a9504920a81570e0fc5df9c7a8be76b043261d9ed4a702af0238bdbe5ad5ea tools/ts" | sha256sum --check --strict chmod +x tools/ts .PHONY: test From a7c3b70dbfedd43f2a1e70d55eaab52c6c19a143 Mon Sep 17 00:00:00 2001 From: Marin Nozhchev Date: Wed, 1 Oct 2025 22:52:58 +0300 Subject: [PATCH 7/7] fixup --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index ac8672e..23c9e77 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ tools/ts: +# ts is a perl script. perl is installed on most linux systems, and in ubuntu Github runners. mkdir -p tools curl -L -o tools/ts https://github.com/pgdr/moreutils/raw/a87889a3bf06fb6be6022b14c152f2f7de608910/ts @echo "96a9504920a81570e0fc5df9c7a8be76b043261d9ed4a702af0238bdbe5ad5ea tools/ts" | sha256sum --check --strict