Skip to content
Snippets Groups Projects
Commit f4fd7035 authored by Cam Saül's avatar Cam Saül
Browse files

Put version in properties file

parent 6509c491
No related branches found
No related tags found
No related merge requests found
......@@ -25,3 +25,4 @@ profiles.clj
/coverage
/resources/sample-dataset.db.trace.db
/deploy/artifacts/*
/resources/version.properties
#! /bin/bash
# Generate the src/metabase/version.clj file
generate_version_info() {
# Generate the resources/version.properties file
version() {
# Skip on CircleCI since this is interactive
if [ ! $CI ]; then
LATEST_TAG=$(git describe origin/master --tags --abbrev=0)
VERSION=$(./version)
echo "Tagging this uberjar as version $LATEST_TAG"
echo "Tagging this uberjar as version '$VERSION'"
read -e -p "Is this OK? [y/n] " TAG_IS_OKAY_Y_OR_N
if [ $TAG_IS_OKAY_Y_OR_N != "y" ]; then
......@@ -14,18 +14,16 @@ generate_version_info() {
exit 1
fi
# Ok, now generate the appropriate file. Ha! we are ghetto
TEMPLATES="src/metabase/version.clj resources/frontend_client/app/version.js"
for template in $TEMPLATES; do
cat "$template.template" | perl -pe "s/{{VERSION}}/$LATEST_TAG/" > $template
# Ok, now generate the appropriate version.properties file.
VERSION_PROPERTIES_FILE=resources/version.properties
echo "version=$VERSION" > $VERSION_PROPERTIES_FILE
# We don't want these version changes being passed along to master so tell git to ignore them
git update-index --assume-unchanged $template
done
# # We don't want these version changes being passed along to master so tell git to ignore them
# git update-index --assume-unchanged $VERSION_PROPERTIES_FILE
fi
}
build_frontend() {
frontend() {
echo "Running 'npm install' to download javascript dependencies..." &&
npm install &&
......@@ -33,7 +31,7 @@ build_frontend() {
./node_modules/webpack/bin/webpack.js -p
}
generate_sample_dataset() {
sample-dataset() {
if [ -f resources/sample-dataset.db.mv.db ]; then
echo "Sample Dataset already generated."
else
......@@ -42,13 +40,13 @@ generate_sample_dataset() {
fi
}
build_uberjar() {
uberjar() {
echo "Running 'lein uberjar'..."
lein uberjar
}
all() {
generate_version_info && build_frontend && generate_sample_dataset && build_uberjar
version && frontend && sample-dataset && uberjar
}
# Default to running all but let someone specify if desired
......
......@@ -70,7 +70,7 @@
[expectations "2.1.2"] ; unit tests
[marginalia "0.8.0"] ; for documentation
[ring/ring-mock "0.2.0"]]
:plugins [[cider/cider-nrepl "0.9.1"] ; Interactive development w/ cider NREPL in Emacs
:plugins [[cider/cider-nrepl "0.10.0-SNAPSHOT"] ; Interactive development w/ cider NREPL in Emacs
[jonase/eastwood "0.2.1"] ; Linting
[lein-ancient "0.6.7"] ; Check project for outdated dependencies + plugins w/ 'lein ancient'
[lein-bikeshed "0.2.0"] ; Linting
......@@ -78,8 +78,9 @@
[lein-expectations "0.0.8"] ; run unit tests with 'lein expectations'
[lein-instant-cheatsheet "2.1.4"] ; use awesome instant cheatsheet created by yours truly w/ 'lein instant-cheatsheet'
[lein-marginalia "0.8.0"] ; generate documentation with 'lein marg'
[refactor-nrepl "1.1.0"]] ; support for advanced refactoring in Emacs/LightTable
[refactor-nrepl "2.0.0-SNAPSHOT"]] ; support for advanced refactoring in Emacs/LightTable
:global-vars {*warn-on-reflection* true} ; Emit warnings on all reflection calls
:env {:mb-run-mode "dev"}
:jvm-opts ["-Dlogfile.path=target/log"
"-Xms1024m" ; give JVM a decent heap size to start with
"-Xmx2048m" ; hard limit of 2GB so we stop hitting the 4GB container limit on CircleCI
......
// -*- mode: javascript; -*-
//
// ************************************************************
// * WARNING: DO NOT EDIT VERSION.JS DIRECTLY! *
// * VERSION.JS IS AUTOMATICALLY GENERATED BY A PERL SCRIPT. *
// * INSTEAD, EDIT VERSION.JS.TEMPLATE. *
// ************************************************************
'use strict';
!function() {
this.METABASE_VERSION = "[UNDEFINED]"; // this is a placeholder; run ./build_uberjare generate_version_info to add an appropriate value
}();
// -*- mode: javascript; -*-
//
// ************************************************************
// * WARNING: DO NOT EDIT VERSION.JS DIRECTLY! *
// * VERSION.JS IS AUTOMATICALLY GENERATED BY A PERL SCRIPT. *
// * INSTEAD, EDIT VERSION.JS.TEMPLATE. *
// ************************************************************
'use strict';
!function() {
this.METABASE_VERSION = "{{VERSION}}";
}();
(ns metabase.config
(:require [environ.core :as environ]
(:require (clojure.java [io :as io]
[shell :as shell])
[clojure.string :as s]
[environ.core :as environ]
[medley.core :as m])
(:import (clojure.lang Keyword)))
(:import clojure.lang.Keyword))
(def ^:const app-defaults
(def ^:private ^:const app-defaults
"Global application defaults"
{;; Database Configuration (general options? dburl?)
:mb-run-mode "prod"
......@@ -39,15 +42,16 @@
;; These are convenience functions for accessing config values that ensures a specific return type
(defn ^Integer config-int [k] (when-let [val (config-str k)] (Integer/parseInt val)))
(defn ^Boolean config-bool [k] (when-let [val (config-str k)] (Boolean/parseBoolean val)))
(defn ^Keyword config-kw [k] (when-let [val (config-str k)] (keyword val)))
(defn ^Integer config-int [k] (some-> k config-str Integer/parseInt))
(defn ^Boolean config-bool [k] (some-> k config-str Boolean/parseBoolean))
(defn ^Keyword config-kw [k] (some-> k config-str keyword))
(def ^:const config-all
"Global application configuration as a dictionary.
Combines hard coded defaults with optional user specified overrides from environment variables."
(into {} (map (fn [k] [k (config-str k)]) (keys app-defaults))))
(into {} (for [k (keys app-defaults)]
[k (config-str k)])))
(defn config-match
......@@ -64,5 +68,33 @@
(m/filter-keys (fn [k] (re-matches prefix-regex (str k))) environ/env))
(m/map-keys (fn [k] (let [kstr (str k)] (keyword (subs kstr (+ 1 (count prefix))))))))))
(defn ^Boolean is-dev? [] (= :dev (config-kw :mb-run-mode)))
(defn ^Boolean is-prod? [] (= :prod (config-kw :mb-run-mode)))
(defn ^Boolean is-test? [] (= :test (config-kw :mb-run-mode)))
;;; Version stuff
;; Metabase version is of the format `GIT-TAG (GIT-SHORT-HASH GIT-BRANCH)`
(defn- mb-version-from-shell-script
"Build a Metabase version string by calling the `./version` shell script, which generates the string from the git tag, hash, and branch."
[]
(-> (shell/sh "./version") :out s/trim))
(defn- mb-version-from-file
"Look up the Metabase version string from the `version.properties` file (this is generated by `./build_uberjar`)."
[]
(with-open [reader (io/reader "resources/version.properties")]
(let [props (java.util.Properties.)]
(.load props reader)
(get props "version"))))
(defn mb-version
"Return a string used to identify the current version of Metabase.
This comes from `resources/version.properties` for prod builds and is fetched directly from git for dev.
(mb-version) -> \"v0.11.1 (6509c49 master)\"."
[]
(if (is-prod?)
(mb-version-from-file)
(mb-version-from-shell-script)))
......@@ -95,7 +95,7 @@
(defn init
"General application initialization function which should be run once at application startup."
[]
(log/info "Metabase Initializing ... ")
(log/info (format "Starting Metabase version %s..." (config/mb-version)))
;; First of all, lets register a shutdown hook that will tidy things up for us on app exit
(.addShutdownHook (Runtime/getRuntime) (Thread. ^Runnable destroy))
(log/debug "Using Config:\n" (with-out-str (clojure.pprint/pprint config/config-all)))
......
......@@ -8,19 +8,16 @@
[metabase.api.routes :as api]
(metabase.models common
[setting :as setting])
[metabase.setup :as setup]
[metabase.util :as u]
(metabase [config :as config]
[setup :as setup]
[util :as u])
metabase.util.password))
(defn- load-index-template
"Slurp in the Metabase index.html file as a `String`"
[]
(slurp (io/resource "frontend_client/index.html")))
(def ^:private ^:const date-format-rfc2616
"Java SimpleDateFormat representing rfc2616 style date used in http headers."
"EEE, dd MMM yyyy HH:mm:ss zzz")
(defn- index-page-vars
"Static values that we inject into the index.html page via Mustache."
[]
......@@ -29,23 +26,27 @@
:password_complexity (metabase.util.password/active-password-complexity)
:setup_token (setup/token-value)
:timezones metabase.models.common/timezones
;; Version info
:version (config/mb-version)
;; all of these values are dynamic settings from the admin UI but we include them here for bootstrapping availability
:anon-tracking-enabled (setting/get :anon-tracking-enabled)
:-site-name (setting/get :-site-name)})
(defn- index [request]
(-> (io/resource "frontend_client/index.html")
slurp
(stencil/render-string {:bootstrap_json (json/generate-string (index-page-vars))})
resp/response
(resp/content-type "text/html")
(resp/header "Last-Modified" (u/now-with-format date-format-rfc2616))))
;; Redirect naughty users who try to visit a page other than setup if setup is not yet complete
(let [index (fn [request]
(-> (resp/response (stencil/render-string
(load-index-template)
{:bootstrap_json (json/generate-string (index-page-vars))}))
(resp/content-type "text/html")
(resp/header "Last-Modified" (u/now-with-format date-format-rfc2616))))]
(defroutes routes
(GET "/" [] index) ; ^/$ -> index.html
(GET "/favicon.ico" [] (resp/resource-response "frontend_client/favicon.ico"))
(context "/api" [] api/routes) ; ^/api/ -> API routes
(context "/app" []
(route/resources "/" {:root "frontend_client/app"}) ; ^/app/ -> static files under frontend_client/app
(route/not-found {:status 404 ; return 404 for anything else starting with ^/app/ that doesn't exist
:body "Not found."}))
(GET "*" [] index))) ; Anything else (e.g. /user/edit_current) should serve up index.html; Angular app will handle the rest
(defroutes routes
(GET "/" [] index) ; ^/$ -> index.html
(GET "/favicon.ico" [] (resp/resource-response "frontend_client/favicon.ico"))
(context "/api" [] api/routes) ; ^/api/ -> API routes
(context "/app" []
(route/resources "/" {:root "frontend_client/app"}) ; ^/app/ -> static files under frontend_client/app
(route/not-found {:status 404 ; return 404 for anything else starting with ^/app/ that doesn't exist
:body "Not found."}))
(GET "*" [] index)) ; Anything else (e.g. /user/edit_current) should serve up index.html; Angular app will handle the rest
;; -*- mode: clojure; -*-
;;
;; ************************************************************
;; * WARNING: DO NOT EDIT VERSION.CLJ DIRECTLY! *
;; * VERSION.CLJ IS AUTOMATICALLY GENERATED BY A PERL SCRIPT. *
;; * INSTEAD, EDIT VERSION.CLJ.TEMPLATE. *
;; ************************************************************
(ns metabase.version
"Info about the current version of Metabase.")
(def ^:const tag
"Git tag for this version of Metabase."
"[UNDEFINED]") ; set version by running ./build-uberjar generate_version_info
;; -*- mode: clojure; -*-
;;
;; ************************************************************
;; * WARNING: DO NOT EDIT VERSION.CLJ DIRECTLY! *
;; * VERSION.CLJ IS AUTOMATICALLY GENERATED BY A PERL SCRIPT. *
;; * INSTEAD, EDIT VERSION.CLJ.TEMPLATE. *
;; ************************************************************
(ns metabase.version
"Info about the current version of Metabase.")
(def ^:const tag
"Git tag for this version of Metabase."
"{{VERSION}}")
#! /bin/bash
# Return the version string used to describe this version of Metabase.
TAG=$(git describe origin/master --tags --abbrev=0)
HASH=$(git show-ref --head --hash=7 head)
BRANCH=$(git symbolic-ref --short HEAD)
echo "$TAG ($HASH $BRANCH)"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment