ocaml-community/lambda-term

XDG Base Directory Specification

Opened this issue · 5 comments

I am writing this in the hope of seeing the XDG Base Directory Specification published by freedesktop.org be supported by lambda-term.

I would be very willing to make a pull request doing as such, but I thought it would be good to check in first.

There are additional details here on what it is, and a mention of Debian's strong recommendation to support it. And I think it is a nontrivial thing to keep users happy, as it helps keep their home directory clutter-free in an easy fashion. I can expand on this if need be, but I'm sure you know what I mean.

I found a library on opam that does just the thing:

$ opam install ocaml-xdg-basedir
# #require "xdg-basedir";;
# XDGBaseDir.Config.user_dir ()
- : string = "/home/genki/.config"
# XDGBaseDir.Cache.user_dir ()
- : string = "/home/genki/.cache"
(* And many more. *)

Two benefits off top of my head:

  1. Config files like the ~/.lambda-input-inputrc can be placed in one's config directory.
  2. Programs like your utop, can easily rely on say, an attribute called config_home being exported by ITerm_resources (that could also return AppData on Windows perhaps?), so that this sort of logic doesn't have to be built into every derivative program.
  • Then, for example, .utop-history can go in one's cache file, rather than being another file cluttering one's home directory.

Perhaps the best thing would be to try to get every OCaml program to add in ocaml-xdg-basedir and use it, but unfortunately, it is not just a problem within the OCaml world where program developers (including myself) can often forget or delay adding this functionality in. So, I see it as a convenient and sensible abstraction for lambda-term given how I see it being used.

There is of course the worry that these sort of user configuration options can add on extra bloat and logic that is a slippery slope. However, XDGBDS is a very standard specification, and doesn't require any manual user configuration.

I even think it would be nice if ~/.ocamlinit could be configured to be in one's configuration directory, as it should ideally be in my understanding. Unfortunately, I tried to sign up for the mailing list here as directed to from the read-only OCaml mirror, but the link seems to be dead.

I would be very willing to make a pull request doing as such, but I thought it would be good to check in first, and see what you think about this issue at large. Thanks for your time.

Sorry, I missed the notification for this ticket.

I'm fine with using the XDG specification for the location of configuration files and the history, and I'll accept a patch for it. I think initially it should read config files in both the home directory and the XDG dirs, with maybe a warning telling the user that files should be moved.

I even think it would be nice if ~/.ocamlinit could be configured to be in one's configuration directory, as it should ideally be in my understanding. Unfortunately, I tried to sign up for the mailing list here as directed to from the read-only OCaml mirror, but the link seems to be dead.

Ah, the link is broken indeed. You can find an up-to-date link here. You can also submit push request on the read-only mirror, or open a ticket on mantis

Sorry, I missed the notification for this ticket.

No worries, thanks for your time.

I'm fine with using the XDG specification for the location of configuration
files and the history, and I'll accept a patch for it. I think initially it
should read config files in both the home directory and the XDG dirs, with
maybe a warning telling the user that files should be moved.

Okay, so this is my initial thought on how to implement: it seems we want a
function that will take in a file name and a location (one of Cache, Config, or
Data), and attempt to find the corresponding file in the user's home directory.
If it does find the file, it will print out the warning telling the user that
the files should be moved to the corresponding location, but return that full
filename regardless. However, if it doesn't find the file, it will return the
filename corresponding to a [potentially non-existent] file in the "ideal"
location. So, something like this, to add underneath the definition of home
in lTerm_resources.ml:

(* This is a stub: I had trouble finding a clean, simple way to check if a file exists,
   so given we go ahead with the below, would appreciate thoughts on that. *)
let file_exists file_name = true

let xdgbd_warning loc file_name =
  let loc_name = match loc with
    | `Cache  -> "$XDG_CACHE_HOME"
    | `Config -> "$XDG_CONFIG_HOME"
    | `Data   -> "$XDG_DATA_HOME" in
  Printf.printf
    "Warning: it is recommended to move `%s` to `%s`, see:\n%s\n"
    file_name loc_name
    "http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html"

let xdgbd_file loc name =
  let home_file = Filename.concat home name in
  if file_exists home_file then
    let () = xdgbd_warning loc home_file in
    home_file
  else
    let loc_file = match loc with
      | `Cache  -> XDGBaseDir.Cache.user_file
      | `Config -> XDGBaseDir.Config.user_file
      | `Data   -> XDGBaseDir.Data.user_file in
    loc_file name

let cache_file  = xdgbd_file `Cache
let config_file = xdgbd_file `Config
let data_file   = xdgbd_file `Data

Hopefully this was along the lines of what you were thinking, let me know if
not. To be clear, I have very little experience in OCaml outside of classwork,
so please be as pedantic as you'd like.

Ah, the link is broken indeed. You can find an up-to-date link here. You can
also submit push request on the read-only mirror, or open a ticket on mantis

Great, thanks, will check these out.

OK, note that it is usually better to submit a pull-request to review code as the github interface makes it easy to comment on specific lines.

Some comments on the code:

  • for file_exists, Sys.file_exists should do

  • except if you do need the specific features of polymorphic variants, it is generally better to use normal variants. Especially type errors are much better. So it'd be better to have:

    type xdg_location = Config | Cache | Data
  • warnings should be printed on stderr, so you should use Printf.eprintf instead of Printf.printf

  • the check for the old location in the home directory should only be done if the user of the library request it. i.e. new code should only check the XDG location, and only code that requires backward compatibility would check the legacy location. Technically xdgdb_file could take an optional argument:

    let xdgbg_file ~loc ?(allow_legacy_location=false) name =
      ...

    And the .mli would document the behavior of setting this argument to true

PS: I updated the README of ocaml regarding the mailing list link

OK, note that it is usually better to submit a pull-request to review code as
the github interface makes it easy to comment on specific lines.

You are totally right, sorry about that!

As for the rest of the comments, I incorporated them just now, and will submit
a PR shortly. Thank you so much for your time.

PS: I updated the README of ocaml regarding the mailing list link

Thank you! Subscribed.

Closing because has been resolved.