When developing large projects, I sometimes 1) lose track of what packages I ]added but am not using any longer, and 2) what packages I’m using but not actually making use of.
Is there a tool to detect these kind of situations? Or how do you deal with that? Right now I’m just manually looking in the code to see what I need and what I don’t and I try (with Revise) to see if things fail when I remove stuff.
First case (check packages that project Proj is actually using) should be easy:
using Proj
using TOML
deps = TOML.parsefile("Project.toml")["deps"]
for d in deps
if !isdefined(Proj, Symbol(d))
println("$d is not being used")
end
This is assuming the simple case in which Proj is only a module with the same name. Otherwise, you should navigate through the different modules of the project.
For the second case (check packages that are used/imported, but not really “used”), I have no idea.
That should do it, although it should be possible to accomplish purely syntactically. If import X or using X doesn’t appear anywhere in the package code then X is not used. Parsing fully correctly is hard, of course, but Julia’s own parser and CSTParser both do it already.
Start removing packages one by one, run all of your code and see when things break
But seriously, thank you for asking this. I’m currently in a similar position, and have been trying to figure this out (the above method could take up to 16 hours per test, and I’ve got 6 or 7 packages I’m not sure of…)
I don’t think a linter should warn about the latter, because you might only have that call there to run the init function in the package, or the package might add a method to a function say in Base. In both cases that using statement does something, even though it might appear unnecessary.
Just tried this now, had to fix a few things, hopefully this helps:
using Proj
using Pkg.TOML
deps = TOML.parsefile("Project.toml")["deps"]
remove = String[]
for d in keys(deps)
if !isdefined(Proj, Symbol(d))
push!(remove, d)
end
end
println("rm ", join(remove, " "))