luvit / lit

Toolkit for developing, sharing, and running luvit/lua programs and libraries.
http://lit.luvit.io/
Apache License 2.0
245 stars 58 forks source link

Save snapshots as tags so they don't get deleted by git gc #251

Open squeek502 opened 5 years ago

squeek502 commented 5 years ago

Creates a new tag for each snapshot hash at refs/snapshots/<author>/<name>/v<version> with the tag name snapshots/<author>/<name>/v<version>. The tag ref is created outside of refs/tags so that other methods that iterate the refs don't include snapshots in their iterations (i.e. db.authors() simply returns all nodes in refs/tags). It's confirmed that the tag being in refs/snapshots still makes it exempt from git gc: without the tag, git gc --prune=all prunes the snapshot hash, but with the tag it remains after git gc --prune=all.

Note: This is an incomplete implementation; it only creates the snapshot tag in lit add, not on the server during lit publish (or any other places where it might also need to be created)

This is the other half of #247


I feel like I'm getting a bit in over my head with this, since I'm not super familiar with the db structure/lit internals/git internals/etc, so I thought I'd push the bit that I've got so far for feedback. As far as I can tell, what needs to be done to finish this up is evaluate/update the other instances of db.write throughout the code (rdb.lua, handlers.lua) to also create the snapshot tag.

squeek502 commented 5 years ago

Btw, here's a small little command I was using for testing the existence of a snapshot hash. Name it snapshot.lua and put it in lit/commands:

return function()
  local config = require('autoconfig')()
  local makeDb = require('db')
  local pkg = require('pkg')
  local log = require("log").log

  local db = makeDb(config.database)
  local author_arg = assert(args[2], "missing author argument")
  local name_arg = assert(args[3], "missing name argument")
  local version_arg = assert(args[4], "missing version argument")

  print("")
  if version_arg then
    local author = author_arg
    local name = name_arg
    local version = version_arg
    local package = db.read(author, name, version)
    assert(package, author .. "/" .. name .. "@" .. version .. " not found")
    local meta = pkg.queryDb(db, package)
    local snapshotHash = meta.snapshot
    log("snapshot hash", snapshotHash)
    assert(pkg.queryDb(db, snapshotHash))
  end
  print("")
end

Use it via luvi . -- snapshot <author> <name> <version>.