Files
BrowserOS/packages/browseros/tools/bdev/internal/engine/status.go
Nikhil 39a7d49c25 feat: add workspace-centric bdev cli (#585)
* fix: clean-up bdev

* feat: add workspace-centric bdev cli

* fix: address review comments for 0326-bdev_cli_redesign

* fix: address review feedback for PR #585

* fix: address review feedback for PR #585
2026-03-27 08:48:23 -07:00

86 lines
2.8 KiB
Go

package engine
import (
"context"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/git"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/patch"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/repo"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/resolve"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/workspace"
)
type WorkspaceStatus struct {
Workspace workspace.Entry `json:"workspace"`
RepoHead string `json:"repo_head"`
BaseCommit string `json:"base_commit"`
LastApplyRev string `json:"last_apply_rev,omitempty"`
LastSyncRev string `json:"last_sync_rev,omitempty"`
LastExtractRev string `json:"last_extract_rev,omitempty"`
ActiveResolve bool `json:"active_resolve"`
NeedsApply []string `json:"needs_apply"`
NeedsUpdate []string `json:"needs_update"`
Orphaned []string `json:"orphaned"`
UpToDate []string `json:"up_to_date"`
SyncState string `json:"sync_state"`
}
func InspectWorkspace(ctx context.Context, ws workspace.Entry, repoInfo *repo.Info) (*WorkspaceStatus, error) {
head, err := git.HeadRev(ctx, repoInfo.Root)
if err != nil {
return nil, err
}
state, err := workspace.LoadState(ws.Path)
if err != nil {
return nil, err
}
repoSet, err := patch.LoadRepoPatchSet(repoInfo.PatchesDir, nil)
if err != nil {
return nil, err
}
localSet, err := patch.BuildWorkingTreePatchSet(ctx, ws.Path, repoInfo.BaseCommit, nil)
if err != nil {
return nil, err
}
status := &WorkspaceStatus{
Workspace: ws,
RepoHead: head,
BaseCommit: repoInfo.BaseCommit,
LastApplyRev: state.LastApplyRev,
LastSyncRev: state.LastSyncRev,
LastExtractRev: state.LastExtractRev,
ActiveResolve: resolve.Exists(ws.Path),
}
for _, delta := range patch.Compare(repoSet, localSet) {
switch delta.Kind {
case patch.NeedsApply:
status.NeedsApply = append(status.NeedsApply, delta.Path)
case patch.NeedsUpdate:
status.NeedsUpdate = append(status.NeedsUpdate, delta.Path)
case patch.Orphaned:
status.Orphaned = append(status.Orphaned, delta.Path)
case patch.UpToDate:
status.UpToDate = append(status.UpToDate, delta.Path)
}
}
status.SyncState = inferSyncState(status)
return status, nil
}
func inferSyncState(status *WorkspaceStatus) string {
switch {
case status.ActiveResolve:
return "conflicted"
case status.LastSyncRev == "":
return "never-synced"
case status.LastSyncRev != status.RepoHead:
return "needs-sync"
case len(status.NeedsApply) > 0:
return "drifted"
case len(status.NeedsUpdate) > 0 || len(status.Orphaned) > 0:
return "local-changes"
default:
return "synced"
}
}