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

Nix package manager support #658

Closed
ElrohirGT opened this issue Apr 20, 2024 · 14 comments
Closed

Nix package manager support #658

ElrohirGT opened this issue Apr 20, 2024 · 14 comments

Comments

@ElrohirGT
Copy link

Is your feature request related to a problem? Please describe.

The Problem: I tried to package this great plugin to use with Nix. Unfortunately when I tried running the installation process it fails because Nix has a read only file system, this is what guarantees their reproducibility. Here's an example:
image

Describe the solution you'd like

Would there be a way to make the command:

:dodge#install()

install dependencies on a custom location?

Something like:

:dodge#install("custom_installation_path")

Describe alternatives you've considered

I've tried to search vimUtils.buildVimPlugin options that would enable me to run commands during the installation phase but couldn't find anything that would allow me to run this command some kind of installation phase or when starting neovim.

Any help would be greatly appreciated!

Additional context

{pkgs, ...}: {
  extraPlugins = [
    (
      pkgs.vimUtils.buildVimPlugin {
        name = "doge";
        version = "v4.6.3";
        src = pkgs.fetchFromGitHub {
          owner = "kkoomen";
          repo = "vim-doge";
          # Versión 4.6.3
          # https://github.com/kkoomen/vim-doge/releases/tag/v4.6.3
          rev = "622736ca29ecd6e2720623696d48179c4da430ac";
          hash = "sha256-avWfs84aOuSV9yX6sOwAj1NOzkGfjXM7S6Wr4W5rVtA=";
        };
      }
    )
  ];
}
@ElrohirGT
Copy link
Author

I've tried to search on the source code and from what I could find:

-- /autoload/doge.vim
"" @public
" Install the necessary dependencies.
function! doge#install(...) abort
  for l:filename in ['vim-doge-helper', 'vim-doge-helper.exe']
    let l:filepath = g:doge_dir . '/bin/' . l:filename
    if filereadable(l:filepath)
      let l:binary_version = split(doge#utils#trim(system(shellescape(l:filepath) . ' --version')), ' ')[1]
      let l:local_version = doge#utils#trim(readfile(g:doge_dir . '/.version')[0])
      if l:binary_version ==# l:local_version
        echom g:doge_prefix . ' already using latest version, skipping binary download'
        return 0
      endif
    endif
  endfor

Would it be enough to just change the l:filepath variable to something custom if the user supplies it as a parameter? I kept reading and it seems to call /scripts/install.sh which contains:

# /scripts/install.sh
set -e
set -u

if ! which curl > /dev/null 2>&1; then
  echo "curl: command not found" >&2
  echo 'Please make sure that curl is installed and available in your $PATH' >&2
  exit 127
fi

ROOT_DIR=$(cd "$(dirname "$0")/.."; pwd -P)
OUTFILE="./bin/vim-doge-helper"

cd "$ROOT_DIR"

if [ -e "$OUTFILE" ]; then
  rm -f "$OUTFILE"
fi

[ ! -d ./bin ] && mkdir ./bin

Among other things.

When does $0 get set? I tried searching for the place but all I could find was:

-- /autoload/doge.vim
  if has('win32')
    let l:command = (executable('pwsh.exe') ? 'pwsh.exe' : 'powershell.exe')
    let l:command .= ' -Command ' . shellescape('Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force; & ' . shellescape(g:doge_dir . '/scripts/install.ps1'))
    let l:term_height = 8
  else
    let l:command = fnameescape(g:doge_dir) . '/scripts/install.sh'
    let l:term_height = 4
  endif

But i don't see any parameter being passed to install.sh. Any help would be greatly appreciated!

@kkoomen
Copy link
Owner

kkoomen commented Apr 27, 2024

Hi there.

Would there be a way to make the command:

:dodge#install()

install dependencies on a custom location?

Something like:

:dodge#install("custom_installation_path")

I assume you meant "doge#install", if so, then yeah sure, I can allow that.

However, I personally am not familiar with Nix nor have I ever used it. So far I understand it's a package manager and you're using a vim plugin called vimnix for this? For now I have two questions:

(1) I don't understand why you are allowed to clone but it seems that you aren't allowed to make any changes to the cloned directory, is that the immutable aspect you're talking about?

(2) It sounds like you also can't use coc or other plugins that, like vim-doge, that modify the directory after cloning, right? does Nix limit you in using certain vim plugins besides vim-doge?

Would it be enough to just change the l:filepath variable to something custom if the user supplies it as a parameter?

I need to think about the required changes for this.

When does $0 get set?

It's a default parameter that is set by default which always refers to the path of the currently executed (bash) file. Open up a test.sh and write echo "$0" and then run bash test.sh, it will print test.sh, i.e. the name of the executed file.

@ElrohirGT
Copy link
Author

I assume you meant "doge#install", if so, then yeah sure, I can allow that.

Yes! Sorry I misspelled.

... So far I understand it's a package manager and you're using a vim plugin called vimnix for this? ...

Yes sorta like that. Here's an MRE. Copy the Nix function into a file with a .nix extension and run the following command:

nix-shell {file.nix}

This will create a shell environment with vim configured and your plugin installed. Try running doge#install(). It should fail like the image:
image

Here's the content of the file.nix:

# file.nix
{pkgs ? import <nixpkgs> {}, ...}: let
  vimRice = (pkgs.vim_configurable.override {}).customize {
    name = "vim";
    # Install plugins for example for syntax highlighting of nix files
    vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
      start = [
        (
          pkgs.vimUtils.buildVimPlugin {
            name = "doge";
            version = "v4.6.3";
            src = pkgs.fetchFromGitHub {
              owner = "kkoomen";
              repo = "vim-doge";
              # Versión 4.6.3
              # https://github.com/kkoomen/vim-doge/releases/tag/v4.6.3
              rev = "622736ca29ecd6e2720623696d48179c4da430ac";
              hash = "sha256-avWfs84aOuSV9yX6sOwAj1NOzkGfjXM7S6Wr4W5rVtA=";
            };
          }
        )
      ];
      opt = [];
    };
    vimrcConfig.customRC = ''
      " Map leader...
      let mapleader=" "

      " your custom vimrc
      set nocompatible
      set backspace=indent,eol,start

      " Turn on syntax highlighting by default
      filetype plugin on
      syntax on
      " ...
    '';
  };
in
  pkgs.mkShell {
    packages = with pkgs; [
      curl
      vimRice
    ];

    shellHook = ''
         export PATH=${pkgs.curl}/bin/curl:$PATH
      alias vim="${vimRice}/bin/vim"
    '';
  }

I don't understand why you are allowed to clone but it seems that you aren't allowed to make any changes to the cloned directory, is that the immutable aspect you're talking about?

The way Nix works is it create a separate partition on your drive to store every dependency that you install with it, this place where everything installed by nix gets managed is called the store. You can't modify the contents of the store directly. Only by defining derivations that do so, this is the core of nix and what makes builds reproducible. So basically, I can define a derivation to download something from github and package it as a vim plugin, which is what I'm doing with your plugin!

I can install your plugin and configure it with Nix but since I can't modify the contents of the partition where Nix installed the plugin when I try to run doge#install() it fails, since it tries to download files into a directoy inside the Nix Store. I tried searching for ways to run the command doge#install() during the installation phase of the derivation of the vimPlugin but couldn't manage to figure out a way.

So the solution I propose is to be able to modify the installation path of this dependencies. You can make the parameter to do so optional so it doesn't brake existing configuration and your package would be easier to package with Nix!

It sounds like you also can't use coc or other plugins that, like vim-doge, that modify the directory after cloning, right? does Nix limit you in using certain vim plugins besides vim-doge?

There's ways to use coc or other plugin managers in tandem with Nix. You loose the some guarantees like complete reproducibility but it's possible as far as I know. My vim setup is just pure nix since I don't want to loose those guarantees.

It's a default parameter that is set by default...

Ooohhh gotcha! The more you know!

@kkoomen
Copy link
Owner

kkoomen commented Apr 28, 2024

Okay but if you want me to allow an installation path parameter, do you only need to install the bin directory in a different location or the whole vim-doge directory?

@ElrohirGT
Copy link
Author

Hmmm... What do you mean by whole vim-doge? Are there other commands that try to create/download/edit files inside where vim-doge is installed?

From what I could see when I searched the codebase, install.sh downloaded an executable and placed it inside 'vim-doge installation path/bin'. So as far as I'm aware only the bin directory should be able to be installed on a different location.

@kkoomen
Copy link
Owner

kkoomen commented May 1, 2024

Try out the feature/custom-install-path branch. I've added a new configurable (n)vim option:

let g:doge_install_path= '/your/custom/path'

or for nvim:

vim.g.doge_install_path = '/your/custom/path'

If you're satisfied with the results, I'll merge #659. If it still doesn't work for you, let me know what the problems are.

@ElrohirGT
Copy link
Author

Great! I don't have my computer with me right now but will do once I get home!

@kkoomen
Copy link
Owner

kkoomen commented May 1, 2024

@ElrohirGT I've already merged it, because tests are passing and I did tested it myself though, so it should be good. Let me know after you've tested it.

@kkoomen
Copy link
Owner

kkoomen commented May 1, 2024

This feature has been merged and released in v4.7.0.

@ElrohirGT
Copy link
Author

ElrohirGT commented May 2, 2024

Hi! I tried installing the new package version and it now installs everything successfully! Unfortunately when I try to use the plugin it fails with:
image

When I tried running the executable manually it also gives me the same error of "required file not found":
image

@kkoomen
Copy link
Owner

kkoomen commented May 3, 2024

Mhmm... as of now, I honestly have zero clue. My tests are passing and when I do it locally, everything works:

┌─ ~/vim-doge-install/bin
└──── ➜  ./vim-doge-helper
error: the following required arguments were not provided:
  --filepath <FILEPATH>
  --parser <PARSER>
  --doc-name <DOC_NAME>
  --line <LINE>

Usage: vim-doge-helper --filepath <FILEPATH> --parser <PARSER> --doc-name <DOC_NAME> --line <LINE>

For more information, try '--help'.

@kkoomen
Copy link
Owner

kkoomen commented May 3, 2024

I think this is up to you to debug, because I can't debug it as I have zero experience with Nix, sorry. If you found the problem, feel free to comment here.

@ElrohirGT
Copy link
Author

Hmmm... how weird, I'll try to debug it, maybe the file got corrupted somehow or it doesn't have the right permissions.

@ElrohirGT
Copy link
Author

In the end I couldn't figure out the problem so I enden up using neogen. I leave this here to any other Nix user who use vim-doge but couldn't make it work with Nix.

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

No branches or pull requests

2 participants