blob: 5f9a03abf8e2db6cb22344921e52eec25c924500 [file] [log] [blame]
Joey Armstrong7614e222023-09-28 17:18:33 -04001# -*- makefile -*-
2# -----------------------------------------------------------------------
3# Copyright 2022-2023 Open Networking Foundation (ONF) and the ONF Contributors
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# -----------------------------------------------------------------------
17
18$(if $(DEBUG),$(warning ENTER))
19
20##-------------------##
21##---] GLOBALS [---##
22##-------------------##
23.PHONY: lint-shell lint-shell-all lint-shell-mod lint-shell-src
24
25# Gather sources to check
26shell-check-find := find .
27shell-check-find += -name 'vendor' -prune
28shell-check-find += -o \( -name '*.sh' -o -name '*.bash' \)
29shell-check-find += -type f -print0
30
31# shell-check := $(env-clean) shellcheck
32shell-check := shellcheck
33
34shell-check-args += --check-sourced
35
36##------------------##
37##---] MACROS [---##
38##------------------##
39
40## -----------------------------------------------------------------------
41## Intent: Derive a list of dependencies when make builds a target by name
42## -----------------------------------------------------------------------
43## Given:
44## target - Makefile target name to check if evaluating
45## listref - An indirect make variable containing a list of file paths
46##
47## Return:
48## target - Variable assigned a list of target dependencies
49## -----------------------------------------------------------------------
50## Usage: $(gen-lint-shell-deps,lint-shell-mod,BY_GIT)
51## lint-shell-mod := foo bar tans fans
52## lint-shell-mod : $(lint-shell-mod)
53## $(lint-shell-mod):
54## perform-action-on-one-dependency $@
55## -----------------------------------------------------------------------
56gen-lint-shell-deps =\
57 $(strip \
58 $(foreach target,$(1),\
59 $(if $(findstring $(target),$(MAKECMDGOALS)),\
60 $(foreach listref,$(2),\
61 $(eval $(target) := $(null))\
62 $(foreach path,$($(listref)),\
63 $(if $(DEBUG),$(info ** $$(eval $(target) += $(addprefix $(target)--,$(path)))))\
64 $(eval $(target) += $(addprefix $(target)--,$(path)))\
65 )\
66 )\
67 )\
68 )\
69)# gen-lint-shell-deps()
70
71##-------------------##
72##---] TARGETS [---##
73##-------------------##
74ifndef NO-LINT-SHELL # enabled(?)
75 lint : lint-shell
76endif
77
78## -----------------------------------------------------------------------
79## Conditional target: lint all source or source by name
80## -----------------------------------------------------------------------
81ifdef SHELL_SRC
82 lint-shell : lint-shell-src
83else
84 lint-shell : lint-shell-all
85endif
86
87## -----------------------------------------------------------------------
88## Intent: Perform a lint check on available sources
89## 1) Display shellcheck version
90## 2) Invoke shellcheck on all files with an *.sh extension
91## -----------------------------------------------------------------------
92lint-shell-all: lint-shellcheck-cmd-version
93
94 # $(call banner-enter,(Target $@))
95 $(env-clean) $(shell-check-find) \
96 | $(xargs-n1) $(shell-check) $(shell-check-args)
97 # $(call banner-leave,(Target $@))
98
99## -----------------------------------------------------------------------
100## Intent: Perform lint check on a named list of files passed in
101## 1) Display shellcheck version
102## 2) Iterate and run shellcheck on each given file path.
103## -----------------------------------------------------------------------
104SHELL_SRC ?= $(error $(MAKE) $@ SHELL_SRC= is required)
105$(call gen-lint-shell-deps,lint-shell-src,SHELL_SRC)
106
107lint-shell-src: \
108 lint-shellcheck-cmd-version \
109 $(lint-shell-src)
110
111## -----------------------------------------------------------------------
112## Intent: Perform lint check on locally modified files
113## 1) Display shellcheck version
114## 2) Gather a list of locally modified files (~git status)
115## 3) Iterate and run shellcheck on each gathered file.
116## -----------------------------------------------------------------------
117BY_GIT = $(shell git diff --name-only HEAD | grep -e '\.sh')
118$(call gen-lint-shell-deps,lint-shell-mod,BY_GIT)
119
120lint-shell-mod :\
121 lint-shellcheck-cmd-version \
122 $(lint-shell-mod)
123
124## -----------------------------------------------------------------------
125## Intent: Workhorse target:
126## 1) gen-lint-shell-deps used to create target specific dependency lists.
127## 2) These dependencies are used to invoke shellcheck against a single
128## path from the list.
129## 3) lint-shell-mod : $(lint-shell-mod)
130## Named targets are dependent on a list of file to check.
131## 4) make lint-shell-mod
132## Building a named target will force iteration, running shellcheck
133## against each file path in the dependency list.
134## -----------------------------------------------------------------------
135.PHONY: $(lint-shell-mod)
136.PHONY: $(lint-shell-src)
137$(lint-shell-mod) $(lint-shell-src):
138 $(env-clean) $(shell-check) $(shell-check-args) $(lastword $(subst --,$(space),$@))
139
140$(if $(DEBUG),$(warning LEAVE))
141
142# [TODO]
143# -----------------------------------------------------------------------
144# Implement exclusion lists by appling $(filter-out $(lint-shell-excl))
145# against the list of files passed to gen-lint-shell-deps. Not definining
146# a target dependency will inhibit runnig shellcheck on a file.
147
148# Ignore vendor/ scripts but they really should be lintable
149# lint-shell-excl += 'vendor'
150# -----------------------------------------------------------------------
151
152# [EOF]