From ea2b811a3773a9b27e8d3c3a7266c2040a0449b9 Mon Sep 17 00:00:00 2001
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Sat, 15 Aug 2020 22:39:17 +0200
Subject: [PATCH] build: check for unsynced feeds before build (#2092)

Forgetting to `make update` or leaving uncommitted changes in the
repositories managed by Gluon is a recurring cause of confusion, even
for experienced developers. Let's print an obvious warning message in
this case.
---
 Makefile                | 13 +++-------
 scripts/module_check.sh | 54 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 10 deletions(-)
 create mode 100755 scripts/module_check.sh

diff --git a/Makefile b/Makefile
index dabb0ea0d..0d174ac24 100644
--- a/Makefile
+++ b/Makefile
@@ -122,13 +122,6 @@ define CheckTarget
 	fi
 endef
 
-define CheckExternal
-	if [ ! -d openwrt ]; then
-		echo "You don't seem to have obtained the external repositories needed by Gluon; please call \`make update\` first!"
-		exit 1
-	fi
-endef
-
 define CheckSite
 	if ! GLUON_SITEDIR='$(GLUON_SITEDIR)' GLUON_SITE_CONFIG='$(1).conf' $(LUA) -e 'assert(dofile("scripts/site_config.lua")(os.getenv("GLUON_SITE_CONFIG")))'; then
 		echo 'Your site configuration ($(1).conf) did not pass validation'
@@ -155,7 +148,7 @@ LUA := openwrt/staging_dir/hostpkg/bin/lua
 $(LUA):
 	+@
 
-	$(CheckExternal)
+	scripts/module_check.sh
 
 	[ -e openwrt/.config ] || $(OPENWRTMAKE) defconfig
 	$(OPENWRTMAKE) tools/install
@@ -165,7 +158,7 @@ $(LUA):
 config: $(LUA) FORCE
 	+@
 
-	$(CheckExternal)
+	scripts/module_check.sh
 	$(CheckTarget)
 	$(foreach conf,site $(patsubst $(GLUON_SITEDIR)/%.conf,%,$(wildcard $(GLUON_SITEDIR)/domains/*.conf)),\
 		$(call CheckSite,$(conf)); \
@@ -195,7 +188,7 @@ manifest: $(LUA) FORCE
 	@
 	[ '$(GLUON_AUTOUPDATER_BRANCH)' ] || (echo 'Please set GLUON_AUTOUPDATER_BRANCH to create a manifest.'; false)
 	echo '$(GLUON_PRIORITY)' | grep -qE '^([0-9]*\.)?[0-9]+$$' || (echo 'Please specify a numeric value for GLUON_PRIORITY to create a manifest.'; false)
-	$(CheckExternal)
+	scripts/module_check.sh
 
 	(
 		export $(GLUON_ENV)
diff --git a/scripts/module_check.sh b/scripts/module_check.sh
new file mode 100755
index 000000000..76e0e56af
--- /dev/null
+++ b/scripts/module_check.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+set -e
+
+. scripts/modules.sh
+
+GLUONDIR="$(pwd)"
+
+if [ ! -d "$GLUONDIR/openwrt" ]; then
+	echo "You don't seem to have obtained the external repositories needed by Gluon; please call \`make update\` first!"
+	exit 1
+fi
+
+need_sync=false
+
+for module in $GLUON_MODULES; do
+	var=$(echo "$module" | tr '[:lower:]/' '[:upper:]_')
+	eval 'commit_expected=${'"${var}"'_COMMIT}'
+
+	prefix=invalid
+	cd "$GLUONDIR/$module" 2>/dev/null && prefix="$(git rev-parse --show-prefix 2>/dev/null)"
+	if [ "$prefix" ]; then
+		echo "*** No Git repository found at '$module'."
+		need_sync=true
+		continue
+	fi
+
+	commit_actual="$(git rev-parse heads/base 2>/dev/null)"
+	if [ -z "$commit_actual" ]; then
+		echo "*** No base branch found at '$module'."
+		need_sync=true
+		continue
+	fi
+
+	if [ "$commit_expected" != "$commit_actual" ]; then
+		echo "*** base branch at '$module' did not match module file (expected: ${commit_expected}, actual: ${commit_actual})"
+		need_sync=true
+		continue
+	fi
+
+	# Use git status instead of git diff -q, as the latter doesn't
+	# check for untracked files
+	if [ "$(git status --porcelain 2>/dev/null | wc -l)" -ne 0 ]; then
+		echo "*** Module '$module' has uncommitted changes:"
+		git status --short
+	fi
+done
+
+if $need_sync; then
+	echo
+	# shellcheck disable=SC2016
+	echo 'Run `make update` to sync dependencies.'
+	echo
+fi
-- 
GitLab