Git Repository

Stackyard

Stackyard scannt lokale Entwicklungsordner und bündelt Projekte, Git-Status, TODOs, Toolchains, Docker-Compose-Setups, Datei- und Launcher-Funktionen sowie Operations-Informationen in einer lokalen WebUI.

Projektseite ↗
HTTPShttps://zanvex.de/git/stackyard.git

internal/project/model.go

Zum Verzeichnis
package project

import (
	"crypto/sha1"
	"encoding/hex"
	"path/filepath"
	"time"
)

type State string

const (
	StateActive       State = "active"
	StatePaused       State = "paused"
	StateArchived     State = "archived"
	StateExperimental State = "experimental"
)

type Project struct {
	ID            string
	Name          string
	RootName      string
	Path          string
	PrimaryType   string
	Tags          []string
	State         State
	Favorite      bool
	Description   string
	Notes         string
	Labels        []string
	LastOpenedAt  time.Time
	Git           GitInfo
	MiseTools     []string
	Ports         []int
	ComposeFiles  []string
	TodoPath      string
	ReadmePath    string
	Markers       []string
	LastModified  time.Time
	LastScannedAt time.Time
}

type GitInfo struct {
	IsRepo            bool
	Branch            string
	Dirty             bool
	Ahead             int
	Behind            int
	LastCommitHash    string
	LastCommitSubject string
	LastCommitAt      time.Time
}

type HealthLevel string

type Collection struct {
	ID         int64
	Name       string
	Color      string
	SortOrder  int
	ProjectIDs []string
}

type Snapshot struct {
	ID         int64
	Name       string
	ProjectIDs []string
	CreatedAt  time.Time
}

type ScannerRule struct {
	Path string
	Kind string
}

type Dependency struct {
	ProjectID          string
	DependsOnProjectID string
}

type Event struct {
	ID        int64
	Level     string
	Message   string
	CreatedAt time.Time
}

const (
	HealthGood    HealthLevel = "good"
	HealthWarning HealthLevel = "warning"
	HealthMuted   HealthLevel = "muted"
)

func IDFromPath(path string) string {
	sum := sha1.Sum([]byte(filepath.Clean(path)))
	return hex.EncodeToString(sum[:])
}

func (p Project) HasMarker(name string) bool {
	for _, marker := range p.Markers {
		if marker == name {
			return true
		}
	}
	return false
}

func (p Project) HasMise() bool {
	return p.HasMarker(".mise.toml")
}

func (p Project) HasDockerCompose() bool {
	return len(p.ComposeFiles) > 0 || p.HasMarker("docker-compose.yml") || p.HasMarker("compose.yml")
}

func (p Project) Health() HealthLevel {
	if !p.Git.IsRepo && p.ReadmePath == "" && p.TodoPath == "" {
		return HealthMuted
	}
	if p.Git.Dirty || p.ReadmePath == "" || p.TodoPath == "" {
		return HealthWarning
	}
	return HealthGood
}

func (p Project) HealthLabel() string {
	switch p.Health() {
	case HealthGood:
		return "Healthy"
	case HealthWarning:
		return "Needs attention"
	default:
		return "Basic"
	}
}

func (p Project) Warnings() []string {
	warnings := make([]string, 0, 3)
	if p.Git.IsRepo && p.Git.Dirty {
		warnings = append(warnings, "Uncommitted changes")
	}
	if p.ReadmePath == "" {
		warnings = append(warnings, "README missing")
	}
	if p.TodoPath == "" {
		warnings = append(warnings, "TODO missing")
	}
	return warnings
}

func (p Project) SummarySignals() []string {
	signals := make([]string, 0, 4)
	if p.HasMise() && len(p.MiseTools) > 0 {
		signals = append(signals, "mise")
	}
	if p.HasDockerCompose() {
		signals = append(signals, "docker")
	}
	if len(p.Ports) > 0 {
		signals = append(signals, "ports")
	}
	return signals
}