Browse Source

make the moo reproducible

Normal cows moo every time they feel like it and it might be a "moo",
"moo!" or "moo?". This is completely unacceptable behaviour in our super
cow through as as a superior being it has to show its superiority over
the common cows and the meager easter eggs by being fully reproducible!

The second version of Chris' patch is modified to include an array of
tests for this feature – which doubles as explanation for some of the
moo lines by giving more exact dates – and falling back to current time
if the environment is invalid + passing time around instead of having an
invalid environment be an unrecoverable error (aka: Guru Meditation) as
that is more inline with how apt usually behaves: The wisdom of super cow
should be available to everyone, even to the most misfortune users not
capable of having a valid environment variable.

That makes the code slightly more ugly, so instead of requiring a young
follower to produce a third version a high priest of the cult applied the
finishing touches as he is used to the pain by now – and another round
with the slowpoke high priest would have been a serious threat to the
Debian release schedule which the cow would not approve.

Closes: #848721
Signed-off-by: Super Cow
Thanks: Chris Lamb for initial patch and guru meditation
tags/debian/1.4_rc1
David Kalnischkies 4 years ago
parent
commit
25a14d4ccf
5 changed files with 69 additions and 25 deletions
  1. +24
    -21
      apt-private/private-moo.cc
  2. +0
    -4
      apt-private/private-moo.h
  3. +22
    -0
      apt-private/private-utils.cc
  4. +1
    -0
      apt-private/private-utils.h
  5. +22
    -0
      test/integration/test-00-commands-have-help

+ 24
- 21
apt-private/private-moo.cc View File

@@ -15,6 +15,7 @@

#include <apt-private/private-moo.h>
#include <apt-private/private-output.h>
#include <apt-private/private-utils.h>

#include <stddef.h>
#include <string.h>
@@ -26,8 +27,8 @@
#include <apti18n.h>
/*}}}*/

static std::string getMooLine() { /*{{{*/
time_t const timenow = time(NULL);
static std::string getMooLine(time_t const timenow) /*{{{*/
{
struct tm special;
localtime_r(&timenow, &special);
enum { NORMAL, PACKAGEMANAGER, APPRECIATION, AGITATION, AIRBORN } line;
@@ -64,17 +65,18 @@ static std::string getMooLine() { /*{{{*/
return out.str();
}
/*}}}*/
static bool printMooLine() { /*{{{*/
std::cerr << getMooLine() << std::endl;
static bool printMooLine(time_t const timenow) /*{{{*/
{
std::cerr << getMooLine(timenow);
return true;
}
/*}}}*/
bool DoMoo1(CommandLine &) /*{{{*/
static bool DoMoo1(time_t const timenow) /*{{{*/
{
// our trustworthy super cow since 2001
if (_config->FindI("quiet") >= 2)
return printMooLine();
std::string const moo = getMooLine();
return printMooLine(timenow);
std::string const moo = getMooLine(timenow);
size_t const depth = moo.length()/4;
c1out <<
OutputInDepth(depth, " ") << " (__) \n" <<
@@ -87,12 +89,12 @@ bool DoMoo1(CommandLine &) /*{{{*/
return true;
}
/*}}}*/
bool DoMoo2(CommandLine &) /*{{{*/
static bool DoMoo2(time_t const timenow) /*{{{*/
{
// by Fernando Ribeiro in lp:56125
if (_config->FindI("quiet") >= 2)
return printMooLine();
std::string const moo = getMooLine();
return printMooLine(timenow);
std::string const moo = getMooLine(timenow);
size_t const depth = moo.length()/4;
if (_config->FindB("APT::Moo::Color", false) == false)
c1out <<
@@ -121,12 +123,12 @@ bool DoMoo2(CommandLine &) /*{{{*/
return true;
}
/*}}}*/
bool DoMoo3(CommandLine &) /*{{{*/
static bool DoMoo3(time_t const timenow) /*{{{*/
{
// by Robert Millan in deb:134156
if (_config->FindI("quiet") >= 2)
return printMooLine();
std::string const moo = getMooLine();
return printMooLine(timenow);
std::string const moo = getMooLine(timenow);
size_t const depth = moo.length()/16;
c1out <<
OutputInDepth(depth, " ") << " \\_/ \n" <<
@@ -138,7 +140,7 @@ bool DoMoo3(CommandLine &) /*{{{*/
return true;
}
/*}}}*/
bool DoMooApril(CommandLine &) /*{{{*/
static bool DoMooApril() /*{{{*/
{
// by Christopher Allan Webber and proposed by Paul Tagliamonte
// in a "Community outreach": https://lists.debian.org/debian-devel/2013/04/msg00045.html
@@ -163,11 +165,12 @@ bool DoMooApril(CommandLine &) /*{{{*/
/*}}}*/
bool DoMoo(CommandLine &CmdL) /*{{{*/
{
time_t const timenow = time(NULL);
time_t const timenow = GetSecondsSinceEpoch();

struct tm april;
localtime_r(&timenow, &april);
if (april.tm_mday == 1 && april.tm_mon == 3)
return DoMooApril(CmdL);
return DoMooApril();

signed short SuperCow = 1;
if (CmdL.FileSize() != 0)
@@ -185,11 +188,11 @@ bool DoMoo(CommandLine &CmdL) /*{{{*/
}

switch(SuperCow) {
case 1: return DoMoo1(CmdL);
case 2: return DoMoo2(CmdL);
case 3: return DoMoo3(CmdL);
case 4: return DoMooApril(CmdL);
default: return DoMoo1(CmdL);
case 1: return DoMoo1(timenow);
case 2: return DoMoo2(timenow);
case 3: return DoMoo3(timenow);
case 4: return DoMooApril();
default: return DoMoo1(timenow);
}

return true;


+ 0
- 4
apt-private/private-moo.h View File

@@ -6,9 +6,5 @@
class CommandLine;

APT_PUBLIC bool DoMoo(CommandLine &CmdL);
bool DoMoo1(CommandLine &CmdL);
bool DoMoo2(CommandLine &CmdL);
bool DoMoo3(CommandLine &CmdL);
bool DoMooApril(CommandLine &CmdL);

#endif

+ 22
- 0
apt-private/private-utils.cc View File

@@ -1,11 +1,13 @@
#include <config.h>

#include <apt-pkg/configuration.h>
#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>

#include <apt-private/private-utils.h>

#include <cstdlib>
#include <sstream>
#include <unistd.h>

// DisplayFileInPager - Display File with pager /*{{{*/
@@ -74,3 +76,23 @@ bool EditFileInSensibleEditor(std::string const &filename)
return ExecWait(Process, "editor", false);
}
/*}}}*/
time_t GetSecondsSinceEpoch() /*{{{*/
{
auto const source_date_epoch = getenv("SOURCE_DATE_EPOCH");
if (source_date_epoch == nullptr)
return time(nullptr);

time_t epoch;
std::stringstream ss(source_date_epoch);
ss >> epoch;

if (ss.fail() || !ss.eof())
{
_error->Warning("Environment variable SOURCE_DATE_EPOCH was ignored as it has an invalid value: \"%s\"",
source_date_epoch);
return time(nullptr);
}

return epoch;
}
/*}}}*/

+ 1
- 0
apt-private/private-utils.h View File

@@ -5,5 +5,6 @@

bool DisplayFileInPager(std::string const &filename);
bool EditFileInSensibleEditor(std::string const &filename);
time_t GetSecondsSinceEpoch();

#endif

+ 22
- 0
test/integration/test-00-commands-have-help View File

@@ -63,3 +63,25 @@ testsuccess aptget moo moo moo
testsuccess aptget moo moo moo -q=2
testsuccess aptget moo moo moo moo
testsuccess aptget moo moo moo moo -q=2

export SOURCE_DATE_EPOCH=moo
testwarningmsg 'W: Environment variable SOURCE_DATE_EPOCH was ignored as it has an invalid value: "moo"' apt moo
testmoo() {
export SOURCE_DATE_EPOCH="$(date -d "$1" +'%s')"
testsuccess aptget moo
cp rootdir/tmp/testsuccess.output moo.output
testsuccess grep "$2" moo.output
testsuccessequal "$2" apt moo -qqq
unset SOURCE_DATE_EPOCH
}
testmoo '@0' 'Have you mooed today?'
testmoo '0-12-25' 'Happy package management day!'
testmoo '1930-02-18' "It's a Bird ... It's a Plane ... It's Super Cow!"
testmoo '1966-11-07' 'Whoever needs milk, bows to the animal.'
testmoo '1988-03-29' 'Have you mooed today?'
testmoo '1993-08-16' 'Three moos for Debian!'
testmoo '1998-04-01' 'Have you smashed some milk today?'
testmoo '@1484822790' 'Have you mooed today?'
testmoo '@1484822791' 'Have you mooed today?'
testmoo '@1484822792' 'Have you mooed today?'
testmoo '@1484822793' 'Have you mooed today?'

Loading…
Cancel
Save