Config: .env = projects root only; derive each project's forge from git
Reduce .env to just REPOS_HOST_PATH (the projects root); runtime bootstrap moves to compose/defaults. Projects are the subdirectories of the single root — removed the project-directories feature (store table, service methods, /api/config/project-dirs, Settings section). Each project's forge is derived from its git remote (matched to a configured forge, else the bare host) and shown as a pill next to its name (State.Forge via scanner ForgeFor + svc.ForgeDisplay). Removed first-run .env seeding; forges + identity are managed in Settings. Added forge.HostOf. AGENT.md updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+20
-47
@@ -9,7 +9,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -391,46 +390,6 @@ func (s *Service) DeleteForge(ctx context.Context, id int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProjectDirs lists configured project directories.
|
||||
func (s *Service) ProjectDirs(ctx context.Context) ([]store.ProjectDir, error) {
|
||||
return s.store.ListProjectDirs(ctx)
|
||||
}
|
||||
|
||||
// AddProjectDir adds a directory to scan. The path must exist inside the
|
||||
// container (i.e. be under a mounted base) and be a directory.
|
||||
func (s *Service) AddProjectDir(ctx context.Context, path string) (store.ProjectDir, error) {
|
||||
path = filepath.Clean(strings.TrimSpace(path))
|
||||
if path == "" {
|
||||
return store.ProjectDir{}, fmt.Errorf("a path is required")
|
||||
}
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return store.ProjectDir{}, fmt.Errorf("path not found in the container: %s (is it under a mounted directory?)", path)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return store.ProjectDir{}, fmt.Errorf("not a directory: %s", path)
|
||||
}
|
||||
d, err := s.store.AddProjectDir(ctx, path)
|
||||
if err != nil {
|
||||
return store.ProjectDir{}, err
|
||||
}
|
||||
s.feed.Record(activity.ActorUser, "project-dir-added", path, "")
|
||||
if s.refresh == nil {
|
||||
return d, nil
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// SetProjectDirEnabled toggles a project directory.
|
||||
func (s *Service) SetProjectDirEnabled(ctx context.Context, id int64, enabled bool) error {
|
||||
return s.store.SetProjectDirEnabled(ctx, id, enabled)
|
||||
}
|
||||
|
||||
// DeleteProjectDir removes a project directory.
|
||||
func (s *Service) DeleteProjectDir(ctx context.Context, id int64) error {
|
||||
return s.store.DeleteProjectDir(ctx, id)
|
||||
}
|
||||
|
||||
// GitIdentity returns the configured commit identity.
|
||||
func (s *Service) GitIdentity(ctx context.Context) (name, email string) {
|
||||
name, _ = s.store.GetSetting(ctx, "git_user_name", "")
|
||||
@@ -450,13 +409,27 @@ func (s *Service) SetGitIdentity(ctx context.Context, name, email string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// ScanRoots returns the enabled project directories (for the scanner).
|
||||
func (s *Service) ScanRoots(ctx context.Context) []string {
|
||||
roots, err := s.store.EnabledRoots(ctx)
|
||||
if err != nil && s.log != nil {
|
||||
s.log.Warn("could not read project dirs", "err", err)
|
||||
// ForgeDisplay maps a repo's origin remote URL to a label for the forge it
|
||||
// belongs to: a configured forge's name (or its host) when the remote host
|
||||
// matches one, otherwise the bare remote host, otherwise "". Used by the scanner
|
||||
// to show each project's forge next to its name.
|
||||
func (s *Service) ForgeDisplay(ctx context.Context, remoteURL string) string {
|
||||
host, _, _, ok := forge.ParseRemote(remoteURL)
|
||||
if !ok || host == "" {
|
||||
return ""
|
||||
}
|
||||
return roots
|
||||
forges, err := s.store.ListForges(ctx)
|
||||
if err == nil {
|
||||
for _, f := range forges {
|
||||
if strings.EqualFold(forge.HostOf(f.BaseURL), host) {
|
||||
if f.Name != "" {
|
||||
return f.Name
|
||||
}
|
||||
return host
|
||||
}
|
||||
}
|
||||
}
|
||||
return host // not a configured forge, but still informative
|
||||
}
|
||||
|
||||
// ApplyGitConfig writes the container's git global config from the store: a
|
||||
|
||||
Reference in New Issue
Block a user