tree

package
v0.0.0-...-d0d2323 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: BSD-2-Clause Imports: 12 Imported by: 0

Documentation

Overview

Package tree implements the on-disk Tarantool-rocks layout: the path scheme under <tree>/share/tarantool, <tree>/lib/tarantool, <tree>/bin, and the Deploy operation that copies a built rock's artifacts into it.

The layout is fixed for Tarantool:

<tree>/share/tarantool/rocks/<name>/<ver>/   — per-rock install dir
<tree>/share/tarantool/                       — deploy_lua_dir
<tree>/lib/tarantool/                         — deploy_lib_dir
<tree>/bin/                                   — bin scripts

This package uses forward-slash Unix paths exclusively via path/filepath; no Windows-specific handling.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func MungedPath

func MungedPath(deployDir, target, pkg, ver string) string

MungedPath returns the versioned_name form of target under deployDir: the munged `<pkg>_<ver>` token dash-joined onto the path remainder after the deploy-dir prefix (core/path.lua path.versioned_name). Exported because installer logic — selecting the active version among munged siblings — needs the same string formation that Deploy used.

Example

ExampleMungedPath shows the conflict-resolution filename LuaRocks uses when two rock versions would deploy the same target: the "<pkg>_<ver>" token (dots and dashes turned to underscores) is joined onto the path remainder.

package main

import (
	"fmt"

	"github.com/tarantool/go-luarocks/tree"
)

func main() {
	fmt.Println(tree.MungedPath(
		"/opt/tt/.rocks/share/tarantool",
		"/opt/tt/.rocks/share/tarantool/demo.lua",
		"demo", "1.0.0-1",
	))
}
Output:
/opt/tt/.rocks/share/tarantool/demo_1_0_0_1-demo.lua

Types

type BinWrap

type BinWrap struct {
	// Interpreter is the absolute path to the Lua interpreter the wrapper
	// execs, e.g. "/opt/tarantool/bin/tarantool".
	Interpreter string
	// Sysconfdir is the value exported as LUAROCKS_SYSCONFDIR, matching
	// upstream's cfg.sysconfdir (default "/etc/luarocks").
	Sysconfdir string
}

BinWrap carries the two environment-dependent inputs upstream bakes into a command wrapper (fs/unix.lua wrap_script): the absolute interpreter path (cfg.variables.LUA_BINDIR + cfg.lua_interpreter) and cfg.sysconfdir.

type Paths

type Paths struct {
	// Tree is the tree root (e.g. ".rocks" in a project, or a system
	// tarantool prefix). Always an absolute or project-relative path.
	Tree string
}

Paths computes the conventional subdirectories under a tree root.

All methods are pure functions of Tree; they do not touch disk. The caller is responsible for ensuring directories exist (Tree.Open does the minimal mkdir).

Example

ExamplePaths computes the conventional subdirectories of a rocks tree. All methods are pure functions of Tree; they touch no disk.

package main

import (
	"fmt"

	"github.com/tarantool/go-luarocks/tree"
)

func main() {
	p := tree.Paths{Tree: "/opt/tt/.rocks"}

	fmt.Println(p.RocksDir())
	fmt.Println(p.InstallDir("metrics", "1.0-1"))
	fmt.Println(p.DeployLuaDir())
	fmt.Println(p.DeployLibDir())
	fmt.Println(p.BinDir())
	fmt.Println(p.ConfDir("metrics", "1.0-1"))
	fmt.Println(p.DocDir("metrics", "1.0-1"))
}
Output:
/opt/tt/.rocks/share/tarantool/rocks
/opt/tt/.rocks/share/tarantool/rocks/metrics/1.0-1
/opt/tt/.rocks/share/tarantool
/opt/tt/.rocks/lib/tarantool
/opt/tt/.rocks/bin
/opt/tt/.rocks/share/tarantool/rocks/metrics/1.0-1/conf
/opt/tt/.rocks/share/tarantool/rocks/metrics/1.0-1/doc

func (Paths) BinDir

func (p Paths) BinDir() string

BinDir returns <tree>/bin — destination for build.install.bin entries.

func (Paths) ConfDir

func (p Paths) ConfDir(name, ver string) string

ConfDir returns <tree>/share/tarantool/rocks/<name>/<ver>/conf — the per-rock configuration directory. Upstream installs build.install.conf via install_to into path.conf_dir(name,version) (a per-rock dir) and never relocates conf to a shared etc dir (repos.deploy_files handles only bin/lua/lib), so conf files reside permanently under the install dir.

func (Paths) DeployLibDir

func (p Paths) DeployLibDir() string

DeployLibDir returns <tree>/lib/tarantool — where compiled .so modules are flattened to slashed paths during Deploy.

func (Paths) DeployLuaDir

func (p Paths) DeployLuaDir() string

DeployLuaDir returns <tree>/share/tarantool — where dotted .lua modules are flattened to slashed paths during Deploy.

func (Paths) DocDir

func (p Paths) DocDir(name, ver string) string

DocDir returns <tree>/share/tarantool/rocks/<name>/<ver>/doc — the per-rock documentation directory.

func (Paths) InstallDir

func (p Paths) InstallDir(name, ver string) string

InstallDir returns <tree>/share/tarantool/rocks/<name>/<ver> — the per-rock install directory holding rockspec, rock_manifest, build/, doc/.

func (Paths) RocksDir

func (p Paths) RocksDir() string

RocksDir returns <tree>/share/tarantool/rocks — the rocks_dir upstream luarocks refers to.

type Tree

type Tree struct {
	Paths

	// Store reads/writes the tree-level and per-rock manifest files. The
	// default is manif.FileStore. Tests inject fakes.
	Store rocks.ManifestStore

	// BinWrap, when non-nil, makes Deploy reproduce upstream LuaRocks'
	// command-script handling (repos.deploy_files → fs.wrap_script): the real
	// script is installed under the per-rock dir and the public <tree>/bin entry
	// becomes a generated /bin/sh launcher. When nil, build.install.bin entries
	// are copied verbatim (the pre-parity behavior; kept for callers that
	// construct a Tree without a Tarantool target).
	BinWrap *BinWrap

	// Provider resolves the currently-active provider of a deploy item (a
	// module name for lua/lib, a command name for bin) from the tree manifest,
	// returning the provider's rock name+version. It backs Deploy's
	// check_spot_if_available (repos.lua:248): when nil, every deployed file is
	// treated as having no current provider and takes the plain active path.
	// The facade sets this from the pre-install tree manifest.
	Provider func(item string) (name, version string, ok bool)
}

Tree is the in-memory handle on a Tarantool rocks tree on disk. It composes the path scheme (Paths) and a ManifestStore. Operations that mutate the tree — Deploy chiefly — go through this type.

func Open

func Open(cfg rocks.Config) (*Tree, error)

Open returns a Tree handle backed by cfg.Tree on disk. The minimal set of subdirectories — RocksDir, DeployLuaDir, DeployLibDir, BinDir — are created if missing (the tree-init step is idempotent).

cfg.Tarantool fields are not consulted: tree management is independent of the Tarantool target (which only matters at build time).

func (*Tree) DeleteVersion

func (t *Tree) DeleteVersion(name, version string) error

DeleteVersion undeploys a single installed rock version: it deletes the files this version deployed (recorded in its rock_manifest, at their actual — plain or versioned — paths), removes the per-rock install directory, and prunes the rock's name directory when no other version remains. It is the file-removal half of upstream repos.delete_version (repos.lua:585-695).

Promotion of a next-highest kept version back to the active (unversioned) name is the caller's responsibility via the tree manifest; it only matters when multiple versions of the same rock are installed (the --keep path).

func (*Tree) Deploy

func (t *Tree) Deploy(spec *rocks.Rockspec, srcDir, buildDir string) (*rocks.RockManifest, error)

Deploy copies the artifacts of a built rock into the tree, producing the per-rock RockManifest (path → md5 hex) that the caller then writes to <install-dir>/rock_manifest via t.Store.WriteRock.

Two source directories are consulted:

  • srcDir holds the original rockspec source tree (the output of fetch.Fetch). Deploy reads .lua modules, prebuilt .so/.dylib modules, install.{lua,lib,bin,conf} files, and copy_directories from srcDir at the rockspec-relative paths.
  • buildDir holds compiled artifacts produced by the build subsystem. Deploy reads .c-source-derived .so files and table-form module artifacts from buildDir at the canonical slashed path `<dotted/slashed>.so`.

For callers without a separate build phase (pure-.lua rocks, or unit tests where srcDir already contains every artifact), pass srcDir as both arguments — the lookup is layered and both forms work.

What gets copied where:

  • build.modules: dotted module name → slashed path; .lua → DeployLuaDir, .so → DeployLibDir.
  • build.install.lua / .lib: the KEY is a dotted module name (upstream is_module_path=true) → module_to_path(key) subdir; a .lua source is renamed to <last-segment>.lua. See installDest.
  • build.install.conf: the KEY is a literal path joined under the per-rock ConfDir (<install-dir>/conf); conf is never deployed to a shared dir.
  • build.install.bin: the KEY is a literal path. When BinWrap is set the real script lands in the per-rock <install-dir>/bin and BinDir gets an executable launcher (0o755); when nil the script is copied verbatim (0o755).
  • build.copy_directories: each entry is a directory under srcDir copied recursively into the per-rock install dir (only a "doc" dir is recorded in the rock_manifest; see copyTree).

Collisions with previously-deployed versions are handled via munged filenames; see conflicts.go.

Deploy is a linear pipeline: each numbered stage below handles one rock artifact section (rockspec, build.modules, build.install.*, copy_directories, make subtree) in the same order upstream build.lua does. The per-section logic lives in the deploy* helpers so this orchestrator stays a readable sequence.

func (*Tree) Which

func (t *Tree) Which(module string) (string, bool)

Which resolves a dotted Lua module name to the on-disk file that would satisfy `require("<module>")` against this tree.

Search order matches upstream `package.path` then `package.cpath`:

  1. DeployLuaDir/<slashed>.lua
  2. DeployLuaDir/<slashed>/init.lua
  3. DeployLibDir/<slashed>.so

Returns ("", false) when none of the above exist on disk.

Conflict-munged siblings (`.../foo.lua~name_version`) are NOT considered — only the active (plain) path. That mirrors how Tarantool's `require` works against the rocks tree.

Example

ExampleTree_Which resolves a dotted module to its on-disk file; a fresh tree has nothing deployed, so the lookup misses.

package main

import (
	"fmt"
	"log"
	"os"

	rocks "github.com/tarantool/go-luarocks"
	"github.com/tarantool/go-luarocks/tree"
)

func main() {
	dir, err := os.MkdirTemp("", "rocks")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(dir)

	tr, err := tree.Open(rocks.Config{Tree: dir})
	if err != nil {
		log.Fatal(err)
	}

	path, ok := tr.Which("no.such.module")
	fmt.Printf("%q %v\n", path, ok)
}
Output:
"" false

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL