Skip to content
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

MF_NON_INTERACTIVE does not seem to work at all #77

Open
ezzatron opened this issue Jun 12, 2022 · 3 comments
Open

MF_NON_INTERACTIVE does not seem to work at all #77

ezzatron opened this issue Jun 12, 2022 · 3 comments

Comments

@ezzatron
Copy link
Member

Currently we manually set MF_NON_INTERACTIVE to true under CI, and try to detect it otherwise. But I'm pretty sure the detection is not working at all. After looking into it, I'm not even sure it's possible to detect an interactive shell under make. None of the suggestions I have seen hold up to actual testing (e.g. https://stackoverflow.com/questions/4251559/how-can-i-tell-if-a-makefile-is-being-run-from-an-interactive-shell).

Unless @jmalloc you have any ideas about how to actually detect non-interactivity under make, perhaps we should either:

  • Stop passing "non-interactive" options to commands completely, and let the individual commands handle it; OR
  • Always pass "non-interactive" options to commands; OR
  • Always pass "non-interactive" options to commands under CI, but never outside of CI

The following Makefile:

DEFAULT_GOAL := test

export EXAMPLE_A := $(shell [ -t 0 ] || echo true)
export EXAMPLE_B := $(shell [[ $$- == *i* ]] && echo true)
export EXAMPLE_C := $(shell echo $$-)

test:
	echo "EXAMPLE_A=$(EXAMPLE_A)"
	echo "EXAMPLE_B=$(EXAMPLE_B)"
	echo "EXAMPLE_C=$(EXAMPLE_C)"

Gives the following output under various interactive and non-interactive circumstances:

$ make
echo "EXAMPLE_A="
EXAMPLE_A=
echo "EXAMPLE_B="
EXAMPLE_B=
echo "EXAMPLE_C=hBc"
EXAMPLE_C=hBc

$ bash -c make
echo "EXAMPLE_A="
EXAMPLE_A=
echo "EXAMPLE_B="
EXAMPLE_B=
echo "EXAMPLE_C=hBc"
EXAMPLE_C=hBc

$ make > /dev/stdout
echo "EXAMPLE_A="
EXAMPLE_A=
echo "EXAMPLE_B="
EXAMPLE_B=
echo "EXAMPLE_C=hBc"
EXAMPLE_C=hBc
@jmalloc
Copy link
Contributor

jmalloc commented Jun 12, 2022

Based on our discussion this morning it seems like our logic might be lacking there.

Here are some example expression that checks both STDIN and STDOUT are TTYs and hence likely to be interactive:

xxx:
	[[ -t 0 && -t 1 ]] && echo YES

Both TTYs:

$ make
[[ -t 0 && -t 1 ]] && echo YES
YES

STDIN not a TTY:

$ echo foo | make
[[ -t 0 && -t 1 ]] && echo YES
make: *** [xxx] Error 1

STDOUT not a TTY:

$ make | cat
[[ -t 0 && -t 1 ]] && echo YES
make: *** [xxx] Error 1

It might be the case that performing this test directly in the recipe like this behaves differently to the way another sub-shell would detect it's STDIN/STDOUT too. If we can't get this working I would opt for:

Always pass "non-interactive" options to commands;

@ezzatron
Copy link
Member Author

It might be the case that performing this test directly in the recipe like this behaves differently to the way another sub-shell would detect it's STDIN/STDOUT too.

Yeah, I think that was part of it too. We do the detection inside a $(shell) call currently, which could change the results. I'll give it a test.

@ezzatron
Copy link
Member Author

Confirmed that $(shell) changes the results. Given the following Makefile:

RESULT := $(shell [[ -t 0 && -t 1 ]] && echo interactive || echo non-interactive)

test:
	@echo Direct:
	@[[ -t 0 && -t 1 ]] && echo interactive || echo non-interactive
	@echo Shell call:
	@echo $(RESULT)

I get the following results:

$ make # both TTYs
Direct:
interactive
Shell call:
non-interactive

$ echo | make # STDIN not a TTY
Direct:
non-interactive
Shell call:
non-interactive

$ make | cat # STDOUT not a TTY
Direct:
non-interactive
Shell call:
non-interactive

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants