Export works but not when `] add` package

I am on this one for too long and can’t fix it yet :smiling_face_with_tear: :laughing:
A MWE is not productible unfortunately

file RingStarProblems.jl contains:

module RingStarProblems
    if "JULIA_REGISTRYCI_AUTOMERGE" in keys(ENV) && ENV["JULIA_REGISTRYCI_AUTOMERGE"]

    else
          ###    Some code
          ###    Some usings
          using Gurobi 
         ...
          ### Some includes
          include("options.jl")
          ...

          export Both
   end
end

The following works, that’s great! (i.e., git clone then activating the package and launching it)

➜  tmp git clone git@github.com:jkhamphousone/RingStarProblems.jl.git
Cloning into 'RingStarProblems.jl'...
remote: Enumerating objects: 3410, done.
[...] # Some git clone infos
➜  tmp cd RingStarProblems.jl 
➜  RingStarProblems.jl git:(main) julia -t auto -q 
julia> import Pkg ; Pkg.activate(".") ; using Revise ; import RingStarProblems as RSP
  Activating project at `~/Desktop/tmp/RingStarProblems.jl`
Precompiling RingStarProblems
        Info Given RingStarProblems was explicitly requested, output will be shown live 
[ Info: Loading Revise, Aqua
[ Info: Loading JuMP
[ Info: Loading Gurobi
[...] # Some outputs

julia> pars = RSP.SolverParameters(
               solve_mod      = RSP.Both(),          # ILP, B&BC or Both
               sp_solve       = RSP.Poly(),
               writeresults   = RSP.WHTML(),         # output results locally, html or no output ""
               o_i            = 0,                   # opening costs
               s_ij           = RSP.Euclidian(),     # star costs
               r_ij           = RSP.Euclidian(),     # ring costs
               backup_factor  = 0.01,                # backup_factor c'=0.01c and d'=0.01c
               do_plot        = false,               # plot_results (to debug)
               two_opt        = 0,                   # use two_opt heuristic (not functional yet)
               tildeV         = 100,                 # uncertain nodes set
               timelimit      = 120,                 # Gurobi TL
               log_level      = 1,                   # console output log_level
               redirect_stdio = false,               # redirecting_stdio to output file
               F              = 183,                 # total failing time F, see PhD manuscript
               use_blossom    = false,               # use blossom inequalities (not functional yet)
               alphas         = [3],                 # See [Labbé et al., 2004](ttps://doi.org/10.1002/net.10114)
               nthreads       = 4,                   # Number of threads used in GUROBI, set 0 for maximum number of available threads
               ucstrat        = 4                    # user cut strategy
              )
RingStarProblems.SolverParameters
  solve_mod: RingStarProblems.Options.SolveMod.Both RingStarProblems.Options.SolveMod.Both()
  sp_solve: RingStarProblems.Options.SPSolve.Poly RingStarProblems.Options.SPSolve.Poly()
  tildeV: Int64 100
  alphas: Array{Int64}((1,)) [3]
  F: Float64 183.0
  warm_start: Array{Int64}((0,)) Int64[]
  inst_trans: Int64 2
  ucstrat: Int64 4
  ucstrat_limit: Int64 2000
  uctolerance: Float64 0.01
  timelimit: Int64 120
  nthreads: Int64 4
  writeresults: RingStarProblems.Options.WResults.WHTML RingStarProblems.Options.WResults.WHTML()
  nrand: Int64 0
  o_i: Int64 0
  s_ij: RingStarProblems.Options.Costs.Euclidian RingStarProblems.Options.Costs.Euclidian()
  r_ij: RingStarProblems.Options.Costs.Euclidian RingStarProblems.Options.Costs.Euclidian()
  backup_factor: Float64 0.01
  nb_runrand: Tuple{Int64, Int64}
  two_opt: Int64 0
  do_plot: Bool false
  log_level: Int64 1
  lp_relaxation: Bool false
  assert: Bool true
  write_log: Bool false
  post_procedure: Bool true
  F_interval: Tuple{Float64, Float64}
  redirect_stdio: Bool false
  use_blossom: Bool false
  gFreuse_lazycons: Bool true


julia>

While the following doesn’t: (i.e., ] add the package then lauching it)

(@v1.10) pkg> add RingStarProblems
   Resolving package versions...
  No Changes to `~/.julia/environments/v1.10/Project.toml`
  No Changes to `~/.julia/environments/v1.10/Manifest.toml`
Precompiling project...
  1 dependency successfully precompiled in 8 seconds. 231 already precompiled.
  1 dependency had output during precompilation:
┌ RingStarProblems
│  [ Info: Loading Revise
│  [ Info: Loading JuMP
│  [ Info: Loading Gurobi
...

julia> import RingStarProblems as RSP

julia> pars = RSP.SolverParameters(
               solve_mod      = RSP.Both(),          # ILP, B&BC or Both
               sp_solve       = RSP.Poly(),
               writeresults   = RSP.WHTML(),         # output results locally, html or no output ""
               o_i            = 0,                   # opening costs
               s_ij           = RSP.Euclidian(),     # star costs
               r_ij           = RSP.Euclidian(),     # ring costs
               backup_factor  = 0.01,                # backup_factor c'=0.01c and d'=0.01c
               do_plot        = false,               # plot_results (to debug)
               two_opt        = 0,                   # use two_opt heuristic (not functional yet)
               tildeV         = 100,                 # uncertain nodes set
               timelimit      = 120,                 # Gurobi TL
               log_level      = 1,                   # console output log_level
               redirect_stdio = false,               # redirecting_stdio to output file
               F              = 183,                 # total failing time F, see PhD manuscript
               use_blossom    = false,               # use blossom inequalities (not functional yet)
               alphas         = [3],                 # See [Labbé et al., 2004](ttps://doi.org/10.1002/net.10114)
               nthreads       = 4,                   # Number of threads used in GUROBI, set 0 for maximum number of available threads
               ucstrat        = 4                    # user cut strategy
              )
ERROR: UndefVarError: `Both` not defined
Stacktrace:
 [1] getproperty(x::Module, f::Symbol)
   @ Base ./Base.jl:31
 [2] top-level scope
   @ REPL[3]:1

julia>

I am lost on this one. I don’t get why it works with git clone and activating the project but not with ] add while the code did not change.
Could someone help if you please ? :smiley:

The code that was registered is here: GitHub - jkhamphousone/RingStarProblems.jl at c14a9c89357d388e2976b07857574c2c55f199f8 (v0.1.0). Since you’ve made changes since then, you will get those by adding the URL (which gives the latest in-development version), but not adding by name (which gives the latest registered version).

1 Like

@ericphanson Thanks!!! You are my today rescuer hahaha! Can continue the developments now :smiley:

1 Like

Out of curiosity, what is the rationale behind this conditional statement inside your main module? That’s rather unusual and it makes me think there might be a better solution for whatever it is you want to do

2 Likes

Dear Guillaume, thank you so much for your input that might improve my code!

I am testing if the environment variable "JULIA_REGISTRYCI_AUTOMERGE" exists and is true because when I was registering the version 0.1.0 of my package (the first one), there was at some point an error thrown by AutoMerge bot. I believe this is because I am using Gurobi.jl which is a proprietary software.

From the README:
" My package fails to load because it needs proprietary software/additional setup to work, what can I do?

Before merging a pull request, AutoMerge will check that your package can be installed and loaded. It is OK for your package to not be fully functional, but making it at least load successfully would streamline registration, as it does not require manual intervention from the registry maintainers. This would also let other packages depend on it, and use its functionalities only when the proprietary software is available in the system, as done for example by the CUDA.jl package. If you are not able or willing to make your package always loadable without the proprietary dependency (which is the preferred solution), you can check if the environment variable JULIA_REGISTRYCI_AUTOMERGE is equal to true and make your package loadable during AutoMerge at least, so that it can be registered without manual intervention. Examples of packages with proprietary software that use the environment variable check include Gurobi.jl and CPLEX.jl."

Note that in RingStarProblems.jl, as suggested in an issue, we should probably work on depending on MathOptInterface instead of relying on JuMP and specific solvers.

On a side small note I should replace:

    if "JULIA_REGISTRYCI_AUTOMERGE" in keys(ENV) && ENV["JULIA_REGISTRYCI_AUTOMERGE"]

    else
          ###    Some code
          ###    Some usings
          using Gurobi 
         ...
          ### Some includes
          include("options.jl")
          ...

          export Both
   end

With:

    if !("JULIA_REGISTRYCI_AUTOMERGE" in keys(ENV) && ENV["JULIA_REGISTRYCI_AUTOMERGE"]) # TODO: try to see if removing it works on next registration
          ###    Some code
          ###    Some usings
          using Gurobi 
         ...
          ### Some includes
          include("options.jl")
          ...
          export Both
      
   end

So you’re cheating the automerge bot by registering what is essentially an empty package? That doesn’t seem like a good solution.
I would recommend making the solver parametric in your code (which is very easy with JuMP), and picking HiGHS.jl as the default. Users can then switch to Gurobi if they are able to get a license, and that way GitHub CI will be happy too.

2 Likes

Thank you for this good idea @gdalle :smiley: I opened an issue on my repository and will try to code what you suggested!

@gdalle
However, I think it will not be possible to use HiGHS.jl because my solver uses callbacks for the Branch and Benders cut method.:

Available solvers

Solver-independent callback support is limited to a few solvers. This includes CPLEX, GLPK, Gurobi, Xpress, and SCIP.

Then pick another open source solver like SCIP.jl?

3 Likes

@gdalle, thank you so much for suggesting the open-source SCIP.jl! Turns out, I can’t use it too :sweat_smile: I’ll have a look at GLPK soon :smiley:

GLPK is open-source and supports callbacks.

See Benders decomposition · JuMP

1 Like