-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace Makefile
with justfile
#979
Conversation
Issues to consider when reviewing this. QA
Refactoring the
|
We typically do this now, although it's not in repo-template yet and this file was copied from there originally.
Not sure if there is a reason that this is not included in the existing files.
We can remove the `touch requirements.*.txt` workaround, because this is handled in the `justfile`.
As repo-template, except for specifying Python version: https://github.com/opensafely-core/repo-template/blob/e3d84fe3981d7f3df8f3cfa3c3a0a72e33cea5f2/pyproject.toml Let's keep this in its own file for now, as we are not yet using `pyproject.toml` in this project. This also uses a few extra ignore options than we would normally specify for new projects. We could remove these in future, but it seems less disruptive to leave the affected code as is for now.
There might be a better way, but not sure how you can pass the additional needed argument to `pip-compile`. We want: `--extras=drivers` for the production dependencies, but this fails with the dev dependencies.
And pin sqlalchemy to v1 v2 is incompatible until we change the cohort-extractor code.
This was copied over from the `Makefile`, but we need to amend it slightly to work with `just`.
8b5abe5
to
aa47996
Compare
export BUILD_DATE=$(shell date +'%y-%m-%dT%H:%M:%S.%3NZ') | ||
export REVISION=$(shell git rev-parse --short HEAD) | ||
# We retrieve the version in GitHub Actions differently, | ||
# so allow overriding this value. | ||
export VERSION=${VERSION:-$(shell git describe --tags)} | ||
export DOCKER_BUILDKIT=1 | ||
docker-compose build --pull {{ args }} {{ env }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to use #!/usr/bin/env bash
for these env vars to be picked up by docker-compose - the just default is that each line is run in a separate shell, so they will be lost. e.g.
# justfile
myenv:
export MYENVVAR=yeahyeahyeah
echo $MYENVVAR
% just myenv
export MYENVVAR=yeahyeahyeah
echo $MYENVVAR
sh: MYENVVAR: unbound variable
error: Recipe `myenv` failed on line 25 with exit code 1
@@ -0,0 +1,148 @@ | |||
# just has no idiom for setting a default value for an environment variable | |||
# so we shell out, as we need VIRTUAL_ENV in the justfile environment | |||
export VIRTUAL_ENV := `echo ${VIRTUAL_ENV:-.venv}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you use env_var_or_default()
? https://just.systems/man/en/chapter_31.html#environment-variables
export VIRTUAL_ENV := `echo ${VIRTUAL_ENV:-.venv}` | |
export VIRTUAL_ENV := env_var_or_default("VIRTUAL_ENV", ".venv") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export DEFVAR := env_var_or_default("DEFVAR", "Iamdefault")
defvaraction:
echo $DEFVAR
% just defvaraction
echo $DEFVAR
Iamdefault
% DEFVAR=mydefvar just defvaraction
echo $DEFVAR
mydefvar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should update it in the repo template?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we probably should...! I notice that was written two years ago - it's very possible that just
did not have this feature when that comment was written...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(do you want to update the template, or should I?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thinking about it - it would be good to land these changes here & test them before we port it upstream to the template?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think just docker-build
will work as expected
_compile-dev src dst *args: virtualenv | ||
#!/usr/bin/env bash | ||
set -euo pipefail | ||
|
||
# exit if src file is older than dst file (-nt = 'newer than', but we negate with || to avoid error exit code) | ||
test "${FORCE:-}" = "true" -o {{ src }} -nt {{ dst }} || exit 0 | ||
$BIN/pip-compile --allow-unsafe --output-file={{ dst }} {{ src }} {{ args }} | ||
|
||
|
||
_compile-prod src dst *args: virtualenv | ||
#!/usr/bin/env bash | ||
set -euo pipefail | ||
|
||
# exit if src file is older than dst file (-nt = 'newer than', but we negate with || to avoid error exit code) | ||
test "${FORCE:-}" = "true" -o {{ src }} -nt {{ dst }} || exit 0 | ||
$BIN/pip-compile --allow-unsafe --extras=drivers --output-file={{ dst }} {{ src }} {{ args }} | ||
|
||
|
||
# update requirements.prod.txt if requirements.prod.in has changed | ||
requirements-prod *args: | ||
"{{ just_executable() }}" _compile-prod setup.py requirements.prod.txt {{ args }} | ||
|
||
|
||
# update requirements.dev.txt if requirements.dev.in has changed | ||
requirements-dev *args: requirements-prod | ||
"{{ just_executable() }}" _compile-dev requirements.dev.in requirements.dev.txt {{ args }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could condense this like so:
_compile-dev src dst *args: virtualenv | |
#!/usr/bin/env bash | |
set -euo pipefail | |
# exit if src file is older than dst file (-nt = 'newer than', but we negate with || to avoid error exit code) | |
test "${FORCE:-}" = "true" -o {{ src }} -nt {{ dst }} || exit 0 | |
$BIN/pip-compile --allow-unsafe --output-file={{ dst }} {{ src }} {{ args }} | |
_compile-prod src dst *args: virtualenv | |
#!/usr/bin/env bash | |
set -euo pipefail | |
# exit if src file is older than dst file (-nt = 'newer than', but we negate with || to avoid error exit code) | |
test "${FORCE:-}" = "true" -o {{ src }} -nt {{ dst }} || exit 0 | |
$BIN/pip-compile --allow-unsafe --extras=drivers --output-file={{ dst }} {{ src }} {{ args }} | |
# update requirements.prod.txt if requirements.prod.in has changed | |
requirements-prod *args: | |
"{{ just_executable() }}" _compile-prod setup.py requirements.prod.txt {{ args }} | |
# update requirements.dev.txt if requirements.dev.in has changed | |
requirements-dev *args: requirements-prod | |
"{{ just_executable() }}" _compile-dev requirements.dev.in requirements.dev.txt {{ args }} | |
_compile src dst env *args: virtualenv | |
#!/usr/bin/env bash | |
set -euo pipefail | |
# exit if src file is older than dst file (-nt = 'newer than', but we negate with || to avoid error exit code) | |
test "${FORCE:-}" = "true" -o {{ src }} -nt {{ dst }} || exit 0 | |
$BIN/pip-compile --allow-unsafe {{ if env == "dev" { "--extras=drivers" } else { "" } }} --output-file={{ dst }} {{ src }} {{ args }} | |
# update requirements.prod.txt if requirements.prod.in has changed | |
requirements-prod *args: | |
"{{ just_executable() }}" _compile setup.py requirements.prod.txt prod {{ args }} | |
# update requirements.dev.txt if requirements.dev.in has changed | |
requirements-dev *args: requirements-prod | |
"{{ just_executable() }}" _compile requirements.dev.in requirements.dev.txt dev {{ args }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I wasn't sure what the idiomatic way of doing things is.
(Just's README is very long, and I didn't find it easy to find much in its documentation either. At least without reading both end-to-end, which I haven't done.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh I'm still mostly figuring out what's possible in justfiles, more than what's idomatic or conventional. I found the just programmer's manual hit the right spot for me in terms of being able to grok some useful features.
actually now you mention it, I think we can make this probably more idiomatic by removing the use of just_executable()
& making requirements-*
only have dependencies, like this:
# update requirements.dev.txt if requirements.dev.in has changed
requirements-dev *args: requirements-prod (_compile "requirements.dev.in" "requirements.dev.txt" "dev" args)
(not sure if this is much better or not, but kind of nice not to invoke a child just process...)
|
||
# exit if src file is older than dst file (-nt = 'newer than', but we negate with || to avoid error exit code) | ||
test "${FORCE:-}" = "true" -o {{ src }} -nt {{ dst }} || exit 0 | ||
$BIN/pip-compile --allow-unsafe --extras=drivers --output-file={{ dst }} {{ src }} {{ args }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think --extras
should be --extra
.
|
||
# clean up temporary files | ||
clean: | ||
rm -rf .venv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate that this line is unchanged from repo-template, but I feel we should use the value of VIRTUAL_ENV
(Line 3) rather than hard-code .venv
. If we don't, then just clean
may not remove the virtual env.
@@ -0,0 +1,148 @@ | |||
# just has no idiom for setting a default value for an environment variable | |||
# so we shell out, as we need VIRTUAL_ENV in the justfile environment | |||
export VIRTUAL_ENV := `echo ${VIRTUAL_ENV:-.venv}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If VIRTUAL_ENV
isn't set, then the makefile creates the virtual env in venv
but the justfile creates it in .venv
. I prefer the latter, but it would be good to announce the change, as someone could inadvertently end up with two virtual envs; one that their muscle memory and setup work with, and one that the justfile works with.
A good way to make the change noisy -- and something we should do regardless -- would be to change .gitignore
so that it ignored .venv
but not venv
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I run just devenv
in a new shell, then I see:
Backend subprocess exited when trying to invoke get_requires_for_build_wheel
Failed to parse /Users/iaindillingham/Code/opensafely-core/cohort-extractor/setup.py
error: Recipe `_compile-prod` failed with exit code 2
error: Recipe `requirements-prod` failed on line 58 with exit code 2
If I run just virtualenv
, source .venv/bin/activate
, and pip install .
, then within the stack trace I see:
Version 'not-from-a-package' is not valid according to PEP 440.
Admittedly, I see the same when I run make devenv
; but I think we should fix this issue before replacing the makefile with the justfile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're already seeing the entire output from pip-compile
, as there's not a difference between make
& just
maybe it's a separate ticket?
cohort-extractor % ./.venv/bin/pip-compile --allow-unsafe --extra=drivers --output-file=requirements.prod.txt setup.py
Backend subprocess exited when trying to invoke get_requires_for_build_wheel
Failed to parse /Users/tom/Documents/bennett-institute/cohort-extractor/setup.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. I've made #980. It blocks my review, I'm afraid.
@StevenMaude @inglesp is it worth doing this given that Cohort Extractor is now deprecated? Or should we just close this PR? |
And do an overhaul of the repository structure to use Ruff.