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

Add support for a .shared directory #16

Open
calebdw opened this issue Jun 9, 2024 · 2 comments
Open

Add support for a .shared directory #16

calebdw opened this issue Jun 9, 2024 · 2 comments

Comments

@calebdw
Copy link

calebdw commented Jun 9, 2024

Hello!

I'm in the process of migration all of my repos over to bare repos with worktrees, and something I come across is that in some repos I have gitignored, untracked files that need to be in every worktree (think .env files, etc.).

What I propose is this: if a .shared directory exists in the same directory as all the other worktrees, then the contents of the directory would be symlinked into a new worktree when it is created. Nested paths could be supported as well so .shared/docker/certs/local.crt could be symlinked to main/docker/certs/local.crt

Now I know I can use a hook to do this, but this seems a common enough use case that it would be great if this plugin could provide first class support for it.

Thanks!

@calebdw
Copy link
Author

calebdw commented Jun 10, 2024

For reference, here's how I've implemented this locally using the created hook:

--- Symlink shared files to the worktree.
--- @param root string
--- @param worktree string
--- @return nil
local function symlink_shared_files(root, worktree)
  local shared = root..'/.shared'
  util.symlink_files(shared, root..'/'..worktree, true, true)
end

local gwt = require('git-worktree')
gwt.setup(opts)

gwt.on_tree_change(function(op, meta)
  if op == gwt.Operations.Create then
    symlink_shared_files(gwt:get_root(), meta.path)
  end
end)

-- in my utils

--- This recursively symlinks files from a src directory to a dest directory.
--- @param src string
--- @param dest string
--- @param relative? boolean
--- @param force? boolean
--- @return nil
function M.symlink_files(src, dest, relative, force)
  relative = relative ~= false
  force = force == true

  local Job = require('plenary.job')
  local Path = require('plenary.path')
  local scan = require('plenary.scandir')

  local src_path = Path:new(src)
  local dest_path = Path:new(dest)

  if not src_path:exists() then
    vim.notify('Shared directory does not exist: ' .. src, vim.log.levels.DEBUG)
    return
  end

  scan.scan_dir_async(src_path:absolute(), {
    hidden = true,
    add_dirs = false,
    on_insert = function(entry)
      local target = dest_path:joinpath(Path:new(entry):make_relative(src_path:absolute()))

      local args = { '-s' }
      if relative then table.insert(args, '-r') end
      if force then table.insert(args, '-f') end

      table.insert(args, entry)
      table.insert(args, target:absolute())

      Job:new({
        command = 'ln',
        args = args,
        on_exit = function(_, code)
          if code == 0 then return end
          vim.schedule(function()
            vim.notify(
              'Failed to symlink ' .. entry .. ' -> ' .. target:absolute(),
              vim.log.levels.ERROR
            )
          end)
        end,
      }):start()
    end,
  })
end

@polarmutex
Copy link
Owner

I will take a look at this soon, sorry been busy

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