How to find missing dependencies of .jl file without executing it

I have a program consisting of a single .jl file, which is using a bunch of packages with directive using. There is more of them than absolutely necessary, since sometimes it’s not clear from documentation what is the base minimum. I would like to minimize their number, but it is painful to do so by trial and error. Running my program requires a complicated system setup, which takes time and is hard to undo when REPL reports an error due to a missing dependency.

Is there a way to parse/analyze the program to check for missing dependecies?

You can use some heuristics and guessing based on the name used but no it’s in general impossible to do. It’s not even something you can figure out simply by running the program either.

3 Likes

Can this be turned around? So that after running this single .jl all used/visited dependencies are listed?

One way to confirm that a package Foo is needed:

  1. Search if the name Foo is used in the code – let aside the line with using Foo.
  2. Search if any of the names exported by Foo – get them with names(Foo) – are used.

If any of those conditions is met, you do need Foo.

You may still need it, even if no exported name is used, if Foo extends methods of other modules, but it’s a start.

2 Likes

If you expect subsequent runs of the program to be identical in their library usage – i.e. the types and methods encountered during one run should be identical to those in all future runs – you can certainly extract all of the compiled methods, including what module they come from, using e.g. the julia profiler, or perhaps a tool like MethodAnalysis.jl.

2 Likes

Generally you would only be using those packages from which you need some symbols (functions, or variables). A common additional case is conditional loading via Requires.jl.

Set up a test script you can call from the command line that performs a very simplified version of your calculation.

Well, that’s the part that I said is also generally impossible.

You can certainly come up with some rules to keep tack of what you use, but those are still just heuristics. There can be packages that’s needed for some methods but not any new symbols that you use directly. Or ones that registers global handlers for a different package. Ones that provides data for other package. Also what do you do for names used only in untake branches (these are easy to scan from the source but much harder when collecting data from a run). How do you distinguish features that are truely not needed vs ones that just happens to be unneeded in a run.

2 Likes

Unfortunately, this is not a case. The project involves constant experimenting in very fluid environment. It may stabilize some day, so this could become a viable option.

It would be nice to have a tool to do it automagically. It doesn’t have to be perfect or even near the theoretical limit of static dependency verification.