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 ...@@ -25,3 +25,4 @@ profiles.clj
/coverage /coverage
/resources/sample-dataset.db.trace.db /resources/sample-dataset.db.trace.db
/deploy/artifacts/* /deploy/artifacts/*
/resources/version.properties
#! /bin/bash #! /bin/bash
# Generate the src/metabase/version.clj file # Generate the resources/version.properties file
generate_version_info() { version() {
# Skip on CircleCI since this is interactive # Skip on CircleCI since this is interactive
if [ ! $CI ]; then 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 read -e -p "Is this OK? [y/n] " TAG_IS_OKAY_Y_OR_N
if [ $TAG_IS_OKAY_Y_OR_N != "y" ]; then if [ $TAG_IS_OKAY_Y_OR_N != "y" ]; then
...@@ -14,18 +14,16 @@ generate_version_info() { ...@@ -14,18 +14,16 @@ generate_version_info() {
exit 1 exit 1
fi fi
# Ok, now generate the appropriate file. Ha! we are ghetto # Ok, now generate the appropriate version.properties file.
TEMPLATES="src/metabase/version.clj resources/frontend_client/app/version.js" VERSION_PROPERTIES_FILE=resources/version.properties
for template in $TEMPLATES; do echo "version=$VERSION" > $VERSION_PROPERTIES_FILE
cat "$template.template" | perl -pe "s/{{VERSION}}/$LATEST_TAG/" > $template
# We don't want these version changes being passed along to master so tell git to ignore them # # We don't want these version changes being passed along to master so tell git to ignore them
git update-index --assume-unchanged $template # git update-index --assume-unchanged $VERSION_PROPERTIES_FILE
done
fi fi
} }
build_frontend() { frontend() {
echo "Running 'npm install' to download javascript dependencies..." && echo "Running 'npm install' to download javascript dependencies..." &&
npm install && npm install &&
...@@ -33,7 +31,7 @@ build_frontend() { ...@@ -33,7 +31,7 @@ build_frontend() {
./node_modules/webpack/bin/webpack.js -p ./node_modules/webpack/bin/webpack.js -p
} }
generate_sample_dataset() { sample-dataset() {
if [ -f resources/sample-dataset.db.mv.db ]; then if [ -f resources/sample-dataset.db.mv.db ]; then
echo "Sample Dataset already generated." echo "Sample Dataset already generated."
else else
...@@ -42,13 +40,13 @@ generate_sample_dataset() { ...@@ -42,13 +40,13 @@ generate_sample_dataset() {
fi fi
} }
build_uberjar() { uberjar() {
echo "Running 'lein uberjar'..." echo "Running 'lein uberjar'..."
lein uberjar lein uberjar
} }
all() { 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 # Default to running all but let someone specify if desired
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
[expectations "2.1.2"] ; unit tests [expectations "2.1.2"] ; unit tests
[marginalia "0.8.0"] ; for documentation [marginalia "0.8.0"] ; for documentation
[ring/ring-mock "0.2.0"]] [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 [jonase/eastwood "0.2.1"] ; Linting
[lein-ancient "0.6.7"] ; Check project for outdated dependencies + plugins w/ 'lein ancient' [lein-ancient "0.6.7"] ; Check project for outdated dependencies + plugins w/ 'lein ancient'
[lein-bikeshed "0.2.0"] ; Linting [lein-bikeshed "0.2.0"] ; Linting
...@@ -78,8 +78,9 @@ ...@@ -78,8 +78,9 @@
[lein-expectations "0.0.8"] ; run unit tests with 'lein expectations' [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-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' [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 :global-vars {*warn-on-reflection* true} ; Emit warnings on all reflection calls
:env {:mb-run-mode "dev"}
:jvm-opts ["-Dlogfile.path=target/log" :jvm-opts ["-Dlogfile.path=target/log"
"-Xms1024m" ; give JVM a decent heap size to start with "-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 "-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 (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]) [medley.core :as m])
(:import (clojure.lang Keyword))) (:import clojure.lang.Keyword))
(def ^:const app-defaults (def ^:private ^:const app-defaults
"Global application defaults" "Global application defaults"
{;; Database Configuration (general options? dburl?) {;; Database Configuration (general options? dburl?)
:mb-run-mode "prod" :mb-run-mode "prod"
...@@ -39,15 +42,16 @@ ...@@ -39,15 +42,16 @@
;; These are convenience functions for accessing config values that ensures a specific return type ;; 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 ^Integer config-int [k] (some-> k config-str Integer/parseInt))
(defn ^Boolean config-bool [k] (when-let [val (config-str k)] (Boolean/parseBoolean val))) (defn ^Boolean config-bool [k] (some-> k config-str Boolean/parseBoolean))
(defn ^Keyword config-kw [k] (when-let [val (config-str k)] (keyword val))) (defn ^Keyword config-kw [k] (some-> k config-str keyword))
(def ^:const config-all (def ^:const config-all
"Global application configuration as a dictionary. "Global application configuration as a dictionary.
Combines hard coded defaults with optional user specified overrides from environment variables." 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 (defn config-match
...@@ -64,5 +68,33 @@ ...@@ -64,5 +68,33 @@
(m/filter-keys (fn [k] (re-matches prefix-regex (str k))) environ/env)) (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)))))))))) (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-prod? [] (= :prod (config-kw :mb-run-mode)))
(defn ^Boolean is-test? [] (= :test (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 @@ ...@@ -95,7 +95,7 @@
(defn init (defn init
"General application initialization function which should be run once at application startup." "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 ;; First of all, lets register a shutdown hook that will tidy things up for us on app exit
(.addShutdownHook (Runtime/getRuntime) (Thread. ^Runnable destroy)) (.addShutdownHook (Runtime/getRuntime) (Thread. ^Runnable destroy))
(log/debug "Using Config:\n" (with-out-str (clojure.pprint/pprint config/config-all))) (log/debug "Using Config:\n" (with-out-str (clojure.pprint/pprint config/config-all)))
......
...@@ -8,19 +8,16 @@ ...@@ -8,19 +8,16 @@
[metabase.api.routes :as api] [metabase.api.routes :as api]
(metabase.models common (metabase.models common
[setting :as setting]) [setting :as setting])
[metabase.setup :as setup] (metabase [config :as config]
[metabase.util :as u] [setup :as setup]
[util :as u])
metabase.util.password)) 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 (def ^:private ^:const date-format-rfc2616
"Java SimpleDateFormat representing rfc2616 style date used in http headers." "Java SimpleDateFormat representing rfc2616 style date used in http headers."
"EEE, dd MMM yyyy HH:mm:ss zzz") "EEE, dd MMM yyyy HH:mm:ss zzz")
(defn- index-page-vars (defn- index-page-vars
"Static values that we inject into the index.html page via Mustache." "Static values that we inject into the index.html page via Mustache."
[] []
...@@ -29,23 +26,27 @@ ...@@ -29,23 +26,27 @@
:password_complexity (metabase.util.password/active-password-complexity) :password_complexity (metabase.util.password/active-password-complexity)
:setup_token (setup/token-value) :setup_token (setup/token-value)
:timezones metabase.models.common/timezones :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 ;; 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) :anon-tracking-enabled (setting/get :anon-tracking-enabled)
:-site-name (setting/get :-site-name)}) :-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 ;; Redirect naughty users who try to visit a page other than setup if setup is not yet complete
(let [index (fn [request] (defroutes routes
(-> (resp/response (stencil/render-string (GET "/" [] index) ; ^/$ -> index.html
(load-index-template) (GET "/favicon.ico" [] (resp/resource-response "frontend_client/favicon.ico"))
{:bootstrap_json (json/generate-string (index-page-vars))})) (context "/api" [] api/routes) ; ^/api/ -> API routes
(resp/content-type "text/html") (context "/app" []
(resp/header "Last-Modified" (u/now-with-format date-format-rfc2616))))] (route/resources "/" {:root "frontend_client/app"}) ; ^/app/ -> static files under frontend_client/app
(defroutes routes (route/not-found {:status 404 ; return 404 for anything else starting with ^/app/ that doesn't exist
(GET "/" [] index) ; ^/$ -> index.html :body "Not found."}))
(GET "/favicon.ico" [] (resp/resource-response "frontend_client/favicon.ico")) (GET "*" [] index)) ; Anything else (e.g. /user/edit_current) should serve up index.html; Angular app will handle the rest
(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