-
Notifications
You must be signed in to change notification settings - Fork 21
/
justfile
214 lines (170 loc) · 7.78 KB
/
justfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# Developer Notes
# If you are looking at this file there are a few helpful things to note.
# - `@` is used to alter what `just` chooses to print.
# It can largely be ignored during development and inserted after when tuning the UI.
# - Double curly braces `{{...}}` are used for evaluating `just` variables and functions
# - By default, these recipes are run from the directory of this file.
# This can be changed but is helpful for us in most recipes.
#
# other recipe ideas:
# - production image building
# - format python
help_message := "shared recipes for ldmx-sw development
Some folks use 'ldmx' as an alias for 'just' in which case you can
replace 'just' with 'ldmx' in the examples below.
USAGE:
just <cmd> [arguments...]
Multiple commands can be provided at once and they will be run in sequence.
just init configure build test
COMMANDS:
"
# inherited from ldmx-env bash functions
# we could look into removing this and instead having the denv_workspace be
# the justfile_directory() itself but that is a larger change than introducing just
# the denv workspace is colloquially known as LDMX_BASE
export LDMX_BASE := parent_directory(justfile_directory())
# tell denv where the workspace is
# usually, denv deduces where the workspace is by finding the .denv directory,
# but we want to set where the denv is within the justfile so users could (for example)
# run their ldmx-sw build from within some other denv by invoking fire from just
# just -f path/to/ldmx-sw/justfile fire config.py
# would run this denv even if there is a denv in the directory where config.py is.
export denv_workspace := LDMX_BASE
# make sure APPTAINER_CACHEDIR is not in the home directory
# unless the user has already defined it
# just 1.15
export APPTAINER_CACHEDIR := env("APPTAINER_CACHEDIR", LDMX_BASE / ".apptainer")
_default:
@just --list --justfile {{ justfile() }} --list-heading "{{ help_message }}"
# this install is private since I'd prefer users knowing what tools they are installing;
# however, the CI needs to install denv before it can run any testing
[private]
install-denv:
curl -s https://raw.githubusercontent.com/tomeichlersmith/denv/main/install | sh
# configure how ldmx-sw will be built
# added ADDITIONAL_WARNINGS and CLANG_TIDY to help improve code quality
# base configure command defining how cmake is called, private so only experts call it
[private]
configure-base *CONFIG:
denv cmake -B build -S . {{ CONFIG }}
# default configure of build when developing
configure *CONFIG: (configure-base "-DADDITIONAL_WARNINGS=ON -DENABLE_CLANG_TIDY=ON" CONFIG)
# configure minimal option for faster compilation
configure-quick: (configure-base)
# configure with Address Sanitizer (ASAN) and UndefinedBehaviorSanitizer (UBSan)
configure-asan-ubsan: (configure-base "-DENABLE_SANITIZER_UNDEFINED_BEHAVIOR=ON -DENABLE_SANITIZER_ADDRESS=ON")
# This is the same as just configure but reports all (non-3rd-party) warnings as errors
configure-force-error: (configure "-DWARNINGS_AS_ERRORS=ON")
# Use alternative compiler and enable LTO (test compiling only, won't run properly)
configure-clang-lto: (configure "-DENABLE_LTO=ON -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang")
# Keep debug symbols so running with gdb provides more helpful detail
configure-gdb: (configure-base "-DCMAKE_BUILD_TYPE=Debug")
# compile and install ldmx-sw
build ncpu=num_cpus():
denv cmake --build build --target install -- -j{{ ncpu }}
# run the ldmx-sw tests
test *ARGS:
cd build && denv ctest {{ ARGS }}
# run ldmx-sw with the input configuration script
[no-cd]
fire config_py *ARGS:
denv fire {{ config_py }} {{ ARGS }}
# run gdb on a config file
[no-cd]
debug config_py *ARGS:
denv gdb fire {{ config_py }} {{ ARGS }}
# initialize a containerized development environment
init:
#!/usr/bin/env sh
# while setting the denv_workspace is helpful for other
# commands that can assume the denv is already initialized,
# we need to unset this environment variable to make sure
# the test is done appropriately.
# just makes sure this recipe runs from the directory of
# the justfile so we know we are in the correct location.
unset denv_workspace
if denv check --workspace --quiet; then
echo "\033[32mWorkspace already initialized.\033[0m"
denv config print
else
denv init --clean-env --name ldmx ldmx/dev:latest ${LDMX_BASE}
fi
# check that the necessary programs for running ldmx-sw are present
check:
#!/usr/bin/env sh
if ! command -v denv 2>&1 > /dev/null; then
echo "\033[31mThe program 'denv' is not present.\033[0m"
exit 1
else
echo "\033[32m'denv' has been found.\033[0m"
fi
# denv can check for container runners it needs
denv check
# confirm(PROMPT) just 1.23
# remove the build and install directories of ldmx-sw
[confirm("This will remove the build and install directories. Are you sure?")]
clean:
rm -r build install
# format the ldmx-sw source code
format: format-cpp format-just
# format the C++ source code of ldmx-sw
format-cpp *ARGS='-i':
#!/usr/bin/env sh
set -exu
format_list=$(mktemp)
git ls-tree -r HEAD --name-only | egrep '(\.h|\.cxx)$' > ${format_list}
denv clang-format {{ ARGS }} $(cat ${format_list})
rm ${format_list}
# format the justfile
format-just:
@just --fmt --unstable --justfile {{ justfile() }}
# shellcheck doesn't have a "apply-formatting" option
# because it really is more of a tidier (its changes could affect code meaning)
# so only a check is implemented here
# ISSUE: the filter implemented here gets all files that are either executable
# or have the '.sh' extension. This includes a python script in TrigScint
# and some bash-specific scripts as well. Not sure how to handle them.
# check the scripts for common errors and bugs
shellcheck:
#!/usr/bin/env sh
set -exu
format_list=$(mktemp)
git ls-tree -r HEAD | awk '{ if ($1 == 100755 || $4 ~ /\.sh/) print $4 }' > ${format_list}
shellcheck --severity style --shell sh $(cat ${format_list})
# below are the mimics of ldmx <cmd>
# we could think about removing them if folks are happy with committing to the
# just-style commands above
# open the ROOT shell within the software environment
root *ARGS="":
denv root {{ ARGS }}
# open a ROOT file with a graphical browser
rootbrowse FILE:
denv rootbrowse {{ FILE }}
# change which image is used for the denv
use IMAGE:
denv config image {{ IMAGE }}
# make sure the image is pulled down
pull IMAGE:
denv config image {{ IMAGE }} && denv config image pull
# mount a directory into the denv
mount DIR:
denv config mounts {{ DIR }}
# pass an environment variable into the denv
setenv +ENVVAR:
denv config env copy {{ ENVVAR }}
# configure and build ldmx-sw
compile ncpu=num_cpus() *CONFIG='': (configure CONFIG) (build ncpu)
# re-build ldmx-sw and then run a config
recompFire config_py *ARGS: compile (fire config_py ARGS)
# install the validation module
# `python3 -m pip install Validation/` is the standard `pip` install method.
# We add `--upgrade` to tell `pip` it should overwrite the package if it already has been
# # installed before which is helpful in the case where someone is updating the code and running
# # the new code within the container. The `--target install/python/` arguments tell `pip`
# # where to install the package. This directory is where we currently store our python modules
# # and is where the container expects them to be. The `--no-cache` argument tells `pip` to
# # not use a cache for downloading any dependencies from the internet which is necessary since
# # `pip` will not be able to write to the cache location within the container.
# # install the python Validation plotting module
install-validation:
denv python3 -m pip install Validation/ --upgrade --target install/python/ --no-cache