1#!/usr/bin/env bash
2# Generates BuildData.java
3# Usage: gen_build_data.sh path/to/BuildData.java my.package.name
4# Author: Benoit Sigoure (tsuna@stumbleupon.com)
5
6# Fail entirely if any command fails.
7set -e
8
9DST=$1
10PACKAGE=$2
11VERSION=$3
12CLASS=`basename "$1" .java`
13
14fatal() {
15  echo >&2 "$0: error: $*."
16  exit 1
17}
18
19[ -n "$DST" ] || fatal 'missing destination path'
20[ -n "$PACKAGE" ] || fatal 'missing package name'
21[ -n "$CLASS" ] || fatal 'bad destination path'
22
23echo "Generating $DST"
24# Make sure the directory where we'll put `$DST' exists.
25dir=`dirname "$DST"`
26mkdir -p "$dir"
27
28TZ=UTC
29export TZ
30# Can't use the system `date' tool because it's not portable.
31sh=`/usr/local/bin/python3.8 <<EOF
32import time
33t = time.time();
34print ("timestamp=%d" % t);
35print ("date=%r" % time.strftime("%Y/%m/%d %T %z", time.gmtime(t)))
36EOF`
37eval "$sh"  # Sets the timestamp and date variables.
38
39user=`whoami`
40host=`hostname`
41repo=`pwd`
42branch=`git branch | grep -h '\*.*' | awk '{print $2}'`
43
44sh=`git rev-list --pretty=format:%h HEAD --max-count=1 \
45    | sed '1s/commit /full_rev=/;2s/^/short_rev=/'`
46eval "$sh"  # Sets the full_rev & short_rev variables.
47
48is_mint_repo() {
49  git rev-parse --verify HEAD >/dev/null &&
50  git update-index --refresh >/dev/null &&
51  git diff-files --quiet &&
52  git diff-index --cached --quiet HEAD
53}
54
55if is_mint_repo; then
56  repo_status='MINT'
57else
58  repo_status='MODIFIED'
59fi
60
61cat >"$DST" <<EOF
62/* This file was generated by $0.  Do not edit manually.  */
63package $PACKAGE;
64
65/** Build data for {@code $PACKAGE} */
66public final class $CLASS {
67  /** Version string MAJOR.MINOR.MAINT */
68  public static final String version = "$VERSION";
69  /** Short revision at which this package was built. */
70  public static final String short_revision = "$short_rev";
71  /** Full revision at which this package was built. */
72  public static final String full_revision = "$full_rev";
73  /** UTC date at which this package was built. */
74  public static final String date = "$date";
75  /** UNIX timestamp of the time of the build. */
76  public static final long timestamp = $timestamp;
77
78  /** Represents the status of the repository at the time of the build. */
79  public static enum RepoStatus {
80    /** The status of the repository was unknown at the time of the build. */
81    UNKNOWN,
82    /** There was no local modification during the build. */
83    MINT,
84    /** There were some local modifications during the build. */
85    MODIFIED;
86  }
87  /** Status of the repository at the time of the build. */
88  public static final RepoStatus repo_status = RepoStatus.$repo_status;
89
90  /** Username of the user who built this package. */
91  public static final String user = "$user";
92  /** Host on which this package was built. */
93  public static final String host = "$host";
94  /** Path to the repository in which this package was built. */
95  public static final String repo = "$repo";
96  /** Git branch */
97  public static final String branch = "$branch";
98
99  /** Human readable string describing the revision of this package. */
100  public static final String revisionString() {
101    return "$PACKAGE $VERSION built at revision $short_rev ($repo_status)";
102  }
103  /** Human readable string describing the build information of this package. */
104  public static final String buildString() {
105    return "Built on $date by $user@$host:$repo";
106  }
107
108  // These functions are useful to avoid cross-jar inlining.
109
110  /** Version string MAJOR.MINOR.MAINT */
111  public static String version() {
112    return version;
113  }
114  /** Short revision at which this package was built. */
115  public static String shortRevision() {
116    return short_revision;
117  }
118  /** Full revision at which this package was built. */
119  public static String fullRevision() {
120    return full_revision;
121  }
122  /** UTC date at which this package was built. */
123  public static String date() {
124    return date;
125  }
126  /** UNIX timestamp of the time of the build. */
127  public static long timestamp() {
128    return timestamp;
129  }
130  /** Status of the repository at the time of the build. */
131  public static RepoStatus repoStatus() {
132    return repo_status;
133  }
134  /** Username of the user who built this package. */
135  public static String user() {
136    return user;
137  }
138  /** Host on which this package was built. */
139  public static String host() {
140    return host;
141  }
142  /** Path to the repository in which this package was built. */
143  public static String repo() {
144    return repo;
145  }
146
147  // Can't instantiate.
148  private $CLASS() {}
149
150  public static void main(String[] args) {
151    System.out.println(revisionString());
152    System.out.println(buildString());
153  }
154}
155EOF
156