How to add several subdirectories to LOAD_PATH in startup.jl file?

If I have several subdirectories within a main directory, how would I add it to LOAD_PATH without having to type each of them individually ?

Example:

 push!(LOAD_PATH,"/mainDir/")  ## This is what I want to do

## I do not want to do this:
 push!(LOAD_PATH,"/mainDir/subdir1")
 push!(LOAD_PATH,"/mainDir/subdir2")
 ...
 push!(LOAD_PATH,"/mainDir/subdir300") 

You could use a loop.

But this is quite an unusual workflow, so if you explain what you are trying to do perhaps you will get suggestions for a better solution.

1 Like

Something like this should work.

dir = "/mainDir/"
append!(LOAD_PATH, filter(isdir, joinpath.(dir, readdir(dir))))

But I agree with Tamas that there may be better workflow options.

If there are better solutions, I’d like to hear about them too! I have a library with several dozens of modules that I regularly use for my research. Many are in their own directory because I may have julia, matlab and C++ versions of the algorithms, and python code for SymPy validation scripts, eg, and other test files. Maybe the way to think of the system/workflow is that the subdirectories are a bit more than “just” a module but way less than a package. So, it would be convenient to have a way to add the module subdirectories to the LOAD_PATH? In the mean time, Gunnar’s suggestion is way better than creating the load path by hand.

This is also my question, in Octave and Matlab it is possible to specify the root-directory for a private repository of modules.

You can do that in Julia as well. If you put a path in the load path that contains a bunch of packages then you can load them.

Maybe I missed a point. For me it does not work to have multiple folders and sub-folders that contain my modules. For example this could look like this:

..\MyLib\IO
..\MyLib\Plotting
..\MyLib\String
[...]
..\MyLib\Hardware

You do not have a main module that includes all other modules?

Thanks for the question! Under Octave and Matlab I have several modules for specific tasks / topics.
Similar what you have in your Julia installation, there are also several folders
containing the different modules.

They need to be properly structured packages in order to be loaded as packages. That means they can either be a simple file names Foo.jl (defining a module named Foo) or a directory with the normal package structure.

I refer to the initial post of josimar.
I confirm that the observed behavior is still the same and it does not matter,
if the last char is the directory separation char or not (“/” or “\”).

push!(LOAD_PATH, "/home/spofahl/julia/MyLib/")

is equal to

push!(LOAD_PATH, "/home/spofahl/julia/MyLib")

And the behavior is equal on MS-WINDOWS and Linux OS.
My modules are reachable only, if they are located in the root
directory of my private module-collection, if I put my module in
a sub-directory e.g. “/home/spofahl/julia/MyLib/foo” it
is not found :frowning:
I need to add a push command for this sub-direcetory.
Under octave I can achieve to add all sub-folders by means of the command:

 addpath(genpath("/home/spofahl/octave/MyLib"))

I don’t really understand what it is you’re trying to do, so it’s hard to explain why it is isn’t happening. Can you explain what you would like to have happen explicitly?

Hi Stefan,
I struggle to express myself in a way that makes it clear to experts like Tamas_Papp and you.
I have the impression I miss an important point about the Julian-way to do stuff I am used to
do in a Matlab/Octave-way.
I have to admit that I failed to do it in python (setting up my own collection of modules,
I spent two years ago maybe 10 hours to figure out how to set-up my own private library of modules).
In Julia I managed at least to publish one folder containing modules via the “push!()”-command.
The objective is as follows:

  • Build up my collection of modules
  • Organize the related files in a folder structure
  • Set-up a mechanism that takes care that new folders, containing modules and related files, are added to the search path for modules in an automated manner

Before I wrote these lines I spent (again) quite some times reading the Julia documentation
but up to know the only thing I found was a reference to the push!()-command.

Regards,
Stefan

I have designed a function that does the job that me and “josimar” would like to see happening inside the startup.jl, I hope that it is of interest for others and maybe a starting point for improvement:

[...]
function addpath_genpath(s_dir_MyLib::AbstractString)
  if ~isdir(s_dir_MyLib)
    error(string("\"", s_dir_MyLib, "\" is not a dir!"))
  end
  for (root, dirs, files) in walkdir(s_dir_MyLib; follow_symlinks = false, onerror = identity)
    for i_file in files
      s_fn_body, s_fn_ext = splitext(i_file)
      if s_fn_ext == ".jl"
        s_file = joinpath(root, i_file)
        s_pattern = Regex(string("module[ ]+", s_fn_body))
        for i_line in eachline(open(s_file))
          if occursin(s_pattern, i_line)
            if ~any(occursin.(root, LOAD_PATH))
              push!(LOAD_PATH, root)
            end
          end
        end
      end
    end
  end
end

addpath_genpath("/home/yourname/julia/MyLib/")
[...]

There is one minor question:
How can I avoid that function “addpath_genpath” is listed inside the Workspace?

I think this problem happens when the top level dir has itself a Project.toml file, cause recursion stops when a proj file is reached

1 Like