Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot set/change user binary dir on Linux #365

Closed
3 tasks done
salim-b opened this issue Apr 12, 2022 · 8 comments
Closed
3 tasks done

Cannot set/change user binary dir on Linux #365

salim-b opened this issue Apr 12, 2022 · 8 comments

Comments

@salim-b
Copy link

salim-b commented Apr 12, 2022

I just installed tinytex for the first time on a Linux system (Ubuntu 20.04). First of all: Great project, thank you!

Now to my problem: While it's possible to customize the tinytex installation path (aka tinytex "root") via tinytex::install_tinytex()'s dir param, there doesn't seem to exist any means to set/customize the user bin folder where tinytex places the symlinks after successful installation. Instead of the default ~/bin I'd like to use ~/.local/bin (which is the default defined in the XDG Base Directory Specification).

This wouldn't be that much of a problem if I could just manually move the symlinks and forget about it. But tinytex regenerates the ~/bin dir with all symlinks everytime tinytex::tlmgr_install() is executed. Is there any environment variable I could set to avoid this? Or anything else I've missed?


By filing an issue to this repo, I promise that

  • I have fully read the issue guide at https://yihui.org/issue/.
  • I have provided the necessary information about my issue.
    • If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    • If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included xfun::session_info('tinytex'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: remotes::install_github('yihui/tinytex').
    • If I have posted the same issue elsewhere, I have also mentioned it in this issue.
  • I have learned the Github Markdown syntax, and formatted my issue correctly.

I understand that my issue may be closed if I don't fulfill my promises.

@cderv
Copy link
Contributor

cderv commented Apr 13, 2022

Hi,

I believe tinytex is only calling tinytex::tlmgr_path() when add_path = TRUE in the install function. This tlmgr_path() is a thin wrapper around tlmgr path add CLI command. Doc is here: https://www.tug.org/texlive/doc/tlmgr.html#path

On Unix, adds or removes symlinks for executables, man pages, and info pages in the system directories specified by the respective options (see the "option" description above).

You can check the value of the option using tinytex::tlmgr(c("option", "sys_bin")) or all options using tinytex::tlmgr(c("option", "showall")) (or obviously directly in terminal with tlmgr)

Which is the value set ?

I believe you can change this value quiet easily using tlmgr option sys_bin <new value> or tinytex::tlmgr(c("option", "sys_bin", "<new_path>")

This should change the behavior to the tlmgr_path() function. So probably order would be

  • Install TinyTeX with add_path = FALSE
  • Run tinytex::tlmgr(c("options", "sys_bin", "<new_path>")
  • Run tinytex::tlmgr_path()

So afterall it is a tlmgr thing IMO.

Hope it helps

@salim-b
Copy link
Author

salim-b commented Apr 13, 2022

Hi @cderv, thanks a lot for the detailed response!

Which is the value set ?

> tinytex::tlmgr(c("option", "sys_bin"))
tlmgr option sys_bin
Destination for symlinks for binaries (sys_bin): /home/salim/bin

I believe you can change this value quiet easily using tlmgr option sys_bin <new value> or tinytex::tlmgr(c("option", "sys_bin", "<new_path>")

Awesome, that worked!

I've proposed a new FAQ item in yihui/yihui.org#171 about this as well as yihui/yihui.org#172 :)

@yihui
Copy link
Member

yihui commented Apr 13, 2022

Yes, on Linux, the sys_bin option is currently set to ~/bin in the R function:
https://github.com/yihui/tinytex/blob/c3a71c782054e000949c42b1ec547d737e1d11bf/R/install.R#L404
and in the shell script:
https://github.com/yihui/tinytex/blob/c3a71c782054e000949c42b1ec547d737e1d11bf/tools/install-bin-unix.sh#L62

I can definitely set it to ~/.local/bin instead, but I just checked the PATH variable on Ubuntu 20.04, and found that it did not contain ~/.local/bin. ~/bin is still present in PATH. It seems that it's not a good idea to set sys_bin to ~/.local/bin yet, otherwise users will have to adjust PATH manually.

@salim-b
Copy link
Author

salim-b commented Apr 14, 2022

@yihui Yes, I agree that it's too early to change the default. It's a recurring issue on Ubuntu and I don't know what their immediate plans are. Since Ubuntu uses systemd and systemd is a freedesktop.org project adhering to the XDG Base Directory Specification (easily verified by running systemd-path user-binaries which should give /home/username/.local/bin), I think eventually they will make the switch.

We could think about introducing an additional param bin_dir or the like in tinytex::install_tinytex() but maybe it's not worth the hassle. I can live fine with the workaround outlined by @cderv.

yihui added a commit that referenced this issue Apr 14, 2022
@yihui
Copy link
Member

yihui commented Apr 14, 2022

Okay, I just made a change so that ~/.local/bin will be used if it exists. The rationale is that this directory shouldn't exist by default. If it does, I assume that the user really prefers it over ~/bin. That should fix your problem.

Alternatively, I could check if ~/.local/bin is present on PATH instead of merely checking if this directory exists, but I guess the latter might be enough for *nix users.

diff --git a/R/install.R b/R/install.R
index 4d6ac31..65a2f49 100644
--- a/R/install.R
+++ b/R/install.R
@@ -411,7 +411,9 @@ install_prebuilt = function(
 # post-install configurations
 post_install_config = function(add_path, extra_packages, repo, hash = FALSE) {
   if (os_index == 2) {
-    if (!dir_exists(bin_dir <- '~/.local/bin')) dir.create(bin_dir <- '~/bin', FALSE, TRUE)
+    bin_dir = '~/.local/bin'
+    if (!path.expand(bin_dir) %in% env_paths()) bin_dir = '~/bin'
+    dir.create(bin_dir, FALSE, TRUE)
     tlmgr(c('option', 'sys_bin', bin_dir))
   }
   # fix fonts.conf: https://github.com/yihui/tinytex/issues/313
@@ -430,6 +432,11 @@ post_install_config = function(add_path, extra_packages, repo, hash = FALSE) {
   }
 }
 
+# get paths on the PATH variable
+env_paths = function() {
+  unlist(strsplit(Sys.getenv('PATH'), .Platform$path.sep, fixed = TRUE))
+}
+
 download_installer = function(file, version) {
   url = if (version != '') sprintf(
     'https://github.com/yihui/tinytex-releases/releases/download/v%s/%s', version, file
diff --git a/tools/install-bin-unix.sh b/tools/install-bin-unix.sh
index b0a3393..f2bf897 100755
--- a/tools/install-bin-unix.sh
+++ b/tools/install-bin-unix.sh
@@ -60,10 +60,13 @@ fi
 
 cd $TEXDIR/bin/*/
 
+# if ~/.local/bin is on PATH, use it as sys_bin; otherwise use ~/bin
 BINDIR="$HOME/.local/bin"
-if [ ! -d  $BINDIR]; then
+if [[ "$PATH" =~ (^|:)"${BINDIR}"(:|$) ]]; then
+else
   BINDIR="$HOME/bin"
 fi
+mkdir -p $BINDIR
 
 [ $OSNAME != "Darwin" ] && ./tlmgr option sys_bin $BINDIR
 ./tlmgr postaction install script xetex  # GH issue #313

@cderv
Copy link
Contributor

cderv commented Apr 14, 2022

Alternatively, I could check if ~/.local/bin is present on PATH instead of merely checking if this directory exists, but I guess the latter might be enough for *nix users.

FWIW I would need to recheck but I think ~/.local/bin is on PATH on Ubuntu inside GHA but not created.

@yihui
Copy link
Member

yihui commented Apr 14, 2022

Okay, if that's the case, my current fix should work, and the alternative fix could be problematic (would need to check for the existence of the dir or create the dir).

@salim-b
Copy link
Author

salim-b commented Apr 14, 2022

Okay, I just made a change so that ~/.local/bin will be used if it exists. The rationale is that this directory shouldn't exist by default. If it does, I assume that the user really prefers it over ~/bin. That should fix your problem.

Great, much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

3 participants