diff options
author | Leif Lindholm <leif.lindholm@linaro.org> | 2015-08-23 15:55:28 +0100 |
---|---|---|
committer | Leif Lindholm <leif.lindholm@linaro.org> | 2015-08-23 19:54:16 +0100 |
commit | 383404f60db98c820917084c358930220307c0de (patch) | |
tree | e1a2526d0af076392ef0588c53ba956451bf8e7d | |
parent | 03273664e91b1b5b5750899f1bdd070bfd40b226 (diff) |
Initial revision of upstream changes tracker
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
-rw-r--r-- | sqlite-common | 166 | ||||
-rwxr-xr-x | track-changes.sh | 154 |
2 files changed, 320 insertions, 0 deletions
diff --git a/sqlite-common b/sqlite-common new file mode 100644 index 0000000..a388c4c --- /dev/null +++ b/sqlite-common @@ -0,0 +1,166 @@ +#!/bin/sh + +# +# Project functions +# +get_project_id() +{ + sqlite "$DB_FILE" "select ROWID from projects where name='$1'" || return 1 +} + +get_project_dir() +{ + sqlite "$DB_FILE" "select dirname from projects where name='$1'" || return 1 +} + +get_project_remote() +{ + sqlite "$DB_FILE" "select remote from projects where name='$1'" || return 1 +} + +add_project() +{ + sqlite "$DB_FILE" "insert into projects values('$1', '$2', '$3')" +} + +delete_project() +{ + PROJECT_ID=`get_project_id "$1"` || return 1 + sqlite -echo "$DB_FILE" "BEGIN; DELETE FROM filetrack WHERE project='$PROJECT_ID'; DELETE FROM projects WHERE ROWID='$PROJECT_ID'; COMMIT;" + if [ $? -eq 0 ]; then + echo "Project '$1' and associated files deleted successfully." + return 0 + fi + return 1 +} + +fetch_project() +{ + PROJECT_DIR=`get_project_dir "$1"` || return 1 + + cd "$PROJECT_DIR" + git fetch "`get_project_remote $1`" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "Failed to fetch project '$1' from '`get_project_remote $1`'!" >&2 + cd - >/dev/null + return 1 + fi + cd - >/dev/null +} + +list_projects() +{ + sqlite "$DB_FILE" "select * from projects" +} + +get_projects() +{ + sqlite "$DB_FILE" "SELECT DISTINCT name FROM projects" +} + +get_project_files() +{ + PROJECT_ID=`get_project_id "$1"` || return 1 + sqlite "$DB_FILE" "SELECT DISTINCT name FROM filetrack WHERE project='$PROJECT_ID'" +} + +update_project() +{ + fetch_project "$1" + + get_project_files "$1" | while read FILE; do + update_file "$1" "$FILE" + done +} + +# +# File functions +# +get_file_logged_hash() +{ + sqlite "$DB_FILE" "SELECT F.hash FROM filetrack as F JOIN projects as P WHERE P.name='$1' AND F.name='$2' ORDER BY F.timestamp DESC LIMIT 1" +} + +get_file_upstream_hash() +{ + PROJECT_DIR=`get_project_dir "$1"` || return 1 + cd "$PROJECT_DIR" + git log --pretty=oneline -1 origin/master -- "$2" | awk '{print $1;}' + cd - >/dev/null +} + +log_file() +{ + PROJECT_ID=`get_project_id "$1"` || return 1 + HASH=`get_file_upstream_hash "$1" "$2"` + + sqlite "$DB_FILE" "insert into filetrack values('$PROJECT_ID', '$2', '$HASH', DATETIME('now'))" +} + +add_file() +{ + PROJECT_ID=`get_project_id "$1"` || return 1 + PROJECT_DIR=`get_project_dir "$1"` || return 1 + + fetch_project "$1" + + cd "$PROJECT_DIR" + git show origin/master:"$2" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + cd - >/dev/null + echo "File '$2' not found in project '$1'." >&2 + return 1 + fi + + cd - >/dev/null + log_file "$1" "$2" +} + +update_file() +{ + UPSTREAM=`get_file_upstream_hash "$1" "$2"` + LOGGED=`get_file_logged_hash "$1" "$2"` + if [ X"$UPSTREAM" != X"$LOGGED" ]; then + echo "$1: file '$2' has been updated" + log_file "$1" "$2" + fi +} + +list_project_files() +{ + sqlite "$DB_FILE" "select F.name from filetrack as F join projects as P where P.name='$1' and P.rowid=F.project" +} + +list_all_files() +{ + sqlite "$DB_FILE" "select P.name, F.name from filetrack as F join projects as P" +} + + +# +# "All" functions +# +update_all() +{ + get_projects "$1" | while read PROJECT; do + update_project "$PROJECT" + done +} + + +# +# Setup functions +# +database_exists() +{ + [ -e "$DB_FILE" ] && return 0 + return 1 +} + +database_create() +{ + echo -n "Creating database ($DB_FILE): " + sqlite "$DB_FILE" "create table projects(name text UNIQUE, remote text, dirname text)" + sqlite "$DB_FILE" "create table filetrack(project integer NOT NULL, name text, hash text, timestamp datetime, FOREIGN KEY(project) REFERENCES projects(ROWID))" + echo "done." +} diff --git a/track-changes.sh b/track-changes.sh new file mode 100755 index 0000000..a646d9f --- /dev/null +++ b/track-changes.sh @@ -0,0 +1,154 @@ +#!/bin/sh + +. `dirname $0`/sqlite-common + +DB_FILE=~/etc/"edk2.sql" + +ACTION= +PROJECT= + +printusage() +{ + echo "usage: `basename $0` <options> <action> <action arguments>" +} + +die_printusage() +{ + printusage + exit 1 +} + +do_all() +{ + case $ACTION in + update) + if [ $# -ne 0 ]; then + die_printusage + fi + update_all + ;; + *) + die_printusage + ;; + esac + + return $? +} + +do_project() +{ + case $ACTION in + add) # add-project <name> <remote> <dirname> + if [ $# -ne 3 ]; then + die_printusage + fi + add_project $* + ;; + del) + if [ $# -ne 1 ]; then + die_printusage + fi + delete_project $* + ;; + list) + list_projects + ;; + update) + if [ $# -ne 1 ]; then + die_printusage + fi + update_project $* + ;; + *) + die_printusage + ;; + esac + + return $? +} + +do_file() +{ + case $ACTION in + add) # add-file <project> <file> + if [ $# -ne 2 ]; then + die_printusage + fi + add_file $* + ;; + del) # del-file <project> <file> + if [ $# -ne 2 ]; then + die_printusage + fi + delete_file $* + ;; + list) # list-files [project] + if [ $# -eq 1 ]; then + list_project_files "$1" + elif [ $# -eq 0 ]; then + list_all_files + else + die_printusage + fi + ;; + update) # update-file <project> <file> + if [ $# -ne 2 ]; then + die_printusage + fi + fetch_project "$1" + update_file $* + ;; + *) + die_printusage + ;; + esac + + return $? +} + +which sqlite >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "sqlite not found - please install it!" + exit 1 +fi + +# +# First stage command line parsing +# +while [ $# -gt 0 ]; do + case "$1" in + -d) + DB_FILE="$2" + shift + ;; +# add-project|del-project|list-projects|update-project) +# add-file|del-file|list-files|update-file) +# update-all) + ?*-?*) + ACTION="`echo $1 | cut -d- -f1`" + SCOPE="`echo $1 | cut -d- -f2`" + shift + break + ;; + *) + printusage + exit 1 + ;; + esac + shift +done + +if [ X"$ACTION" = X"" -o X"$SCOPE" = X"" ]; then + printusage + exit 1 +fi + +database_exists || database_create + +# 'files' -> 'file' and 'projects' -> 'project' +SCOPE=`echo $SCOPE | sed 's/^\(.*\)s$/\1/'` + +do_$SCOPE $* +exit $? + + |