project

package
v0.0.0-beta.32 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package project provides per-project identity, registry, and per-project SQLite storage for docsiq. A project is identified by a normalized git remote URL slug and persisted in $DATA_DIR/registry.db.

Index

Constants

This section is empty.

Variables

View Source
var ErrDuplicateRemote = errors.New("remote already registered to another project")

ErrDuplicateRemote is returned when Register would violate the UNIQUE constraint on projects.remote (two projects cannot share a remote).

View Source
var ErrNotFound = errors.New("project not found")

ErrNotFound is returned when a registry lookup has no matching row.

Functions

func DetectRemote

func DetectRemote(cwd string) (string, error)

DetectRemote runs `git -C <cwd> remote get-url origin` and returns the trimmed remote URL. Returns an error if git is missing, cwd is not a git repo, origin is not configured, or the command produces empty output.

This is intentionally a shell-out rather than a library dependency: docsiq targets environments that already have git installed (the whole product is aimed at AI coding agents working in git repos), and shelling out avoids pulling in go-git (~4 MB of transitive deps) just to read one config value.

func IsValidSlug

func IsValidSlug(s string) bool

IsValidSlug returns true iff s matches the canonical slug charset and length bounds. Used by OpenForProject and registry consumers.

func Slug

func Slug(remote string) (string, error)

Slug normalizes a git remote URL into a filesystem-safe, URL-safe slug.

Supported input shapes:

https://github.com/owner/repo[.git]
http://host/owner/repo[.git]
git@github.com:owner/repo[.git]
ssh://git@host:22/owner/repo[.git]
ssh://user@host/path/to/repo.git
owner/repo  (already-path-ish)

Rules applied in order:

  1. Strip surrounding whitespace; reject empty.
  2. Strip trailing ".git".
  3. Drop the user@ portion and protocol (ssh://, https://, git://, file://).
  4. SCP-style `git@host:owner/repo` → `host/owner/repo`.
  5. URL-decode the path so %-escapes don't leak into the slug.
  6. Lowercase.
  7. Replace every non-[a-z0-9_-] rune with '-'.
  8. Collapse runs of '-' and trim leading/trailing '-'.
  9. Reject empty result; cap length.

Returns an error if the remote is empty, produces an empty slug after normalization, or contains only non-slug characters.

Types

type Project

type Project struct {
	Slug      string `json:"slug"`
	Name      string `json:"name"`
	Remote    string `json:"remote"`
	CreatedAt int64  `json:"created_at"`
}

Project is the canonical identity of a scoped workspace in docsiq.

Slug — URL-safe identifier (charset [a-z0-9_-]) derived from Remote. Name — human-readable display name (defaults to last path component of Remote). Remote — normalized git remote URL, or "_default" / "legacy" for sentinel projects. CreatedAt — Unix epoch seconds when the project was first registered.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry wraps a tiny SQLite database at $DATA_DIR/registry.db that stores the slug → project mapping. It uses the same DSN-pragma pattern as internal/store so WAL and foreign keys are actually enforced under the modernc.org/sqlite driver.

func OpenRegistry

func OpenRegistry(dataDir string) (*Registry, error)

OpenRegistry opens (or creates) the registry DB at $DATA_DIR/registry.db. Creates dataDir (0o755) if missing. Fails if dataDir is empty.

func (*Registry) Close

func (r *Registry) Close() error

Close releases the underlying database handle.

func (*Registry) DB

func (r *Registry) DB() *sql.DB

DB exposes the raw *sql.DB handle for callers that need it (e.g. tests or future admin tooling). Returns nil on a zero Registry.

func (*Registry) Delete

func (r *Registry) Delete(slug string) error

Delete removes a project row by slug. Returns ErrNotFound if no row matched. This does NOT touch the per-project data dir on disk — callers that want the files gone must rm -rf separately (see `projects delete --purge`).

func (*Registry) Get

func (r *Registry) Get(slug string) (*Project, error)

Get returns the project with the given slug, or ErrNotFound.

func (*Registry) GetByRemote

func (r *Registry) GetByRemote(remote string) (*Project, error)

GetByRemote returns the project with the given remote, or ErrNotFound.

func (*Registry) List

func (r *Registry) List() ([]*Project, error)

List returns all registered projects ordered by created_at ascending. Returns an empty slice (not nil) when the registry is empty.

func (*Registry) Register

func (r *Registry) Register(p Project) error

Register inserts a new project. The slug must pass IsValidSlug. The remote must be non-empty; duplicates (by remote) return ErrDuplicateRemote. CreatedAt is set to time.Now().Unix() if the caller did not provide one.

Jump to

Keyboard shortcuts

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