Open catflydotio opened 2 years ago
Poked at this a little bit tonight because I also ran into #878 while testing out the Flask app.
One thing I noticed about checksPass
is that no uses of it actually take multiple check functions. I updated it to the following:
func checksPass(sourceDir string, check checkFn) bool {
return check(sourceDir)
}
After changing fileExists
to fileExistsAny
and implementing fileExistsAll
, I also went through all the scanners that used fileExists
and multiple files (django, go, python, ruby). I'm fairly certain the Django one is the only one needs to make use of fileExistsAll
, and even that is debatable...it could just use manage.py
.
Hope that's helpful.
Attach my patch as well: fileExists.patch.txt
@catflydotio can we close this?
No, this still isn't a PR. I'm reacquainting myself with it...
We know our Django launcher is greedy, claiming any project that has a
requirements.txt
. The files involved are flyctl/internal/sourcecode/scan.go and flyctl/internal/sourcecode/helpers.go.scan.go
has the different launch configurators (Remix, Elixir, Django, etc.), and uses some helper functions inhelpers.go
.It looks as though the Django launcher means to find projects with both
requirements.txt
andmanage.py
, which seems like a decent way to identify Django projects correctly, but it's using the helper functionfileExists()
, which returnstrue
if either is present.Ruby, Go, Django, and Python launchers all use
fileExists()
with two files. I haven't checked to see what behaviour is expected from it by the Ruby, Go, and Python launchers, but if we change the behaviour offileExists()
to fix Django, we may break something else.I think there's a problem with
fileExists()
:Here's
fileExists()
in flyctl/internal/sourcecode/helpers.go:What I think it does:
For every file in the list we pass to it,
If everything's gone through and no file was found, finally return false.
(Is it necessary to check whether the thing is a directory? Will it ever not have an extension? Putting that aside...)
What I want it to do, for the Django launcher:
For every file,
If neither of those falses ever happen, then all files were present and we can return true.
(If we're worried there might be a dir there with the name we're looking for, what if there's both a file and a dir, and it finds the dir first? Is that possible? We'd get a false false from that...)
(Checked on Go playground in case I was missing some subtlety around the intermediate checkFn type: https://go.dev/play/p/oc70A7a7Yl-)
I'd add this to helpers.go and rename
fileExists()
tofileExistsAny()
, and go through the launchers to figure out which needs which.I think there's a problem with
checksPass()
:Next twist:
fileExists()
and other checks are used in a helper calledchecksPass()
.checksPass()
takes a source directory, and potentially multiple check functions. And it returns true if any of the checks is true. It doesn't matter yet, because each time it's used so far, there's only one check. But I suspect this is not the intended behaviour for this one at all.So I would propose renaming it to
checksPassAll()
and adjusting it to require all checks to pass in order to return true:Other functions that seem OK
We also have
fileContains()
anddirContains()
, that return true if a pattern is found at least once. Which looks like their intended behaviour. ButdirContains()
might be better nameddirContainsPattern()
or something.Other similarly-named helpers
We've also got flyctl/helpers/fs.go, with a
FileExists()
and aDirectoryExists()
, that each take a path and a (single) filename.FileExists()
is used in 8 files, including scan.go. Contrast withfileExists()
which only gets used in scan.go.