215 lines
6.4 KiB
Go
215 lines
6.4 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Workstream represents a stacked-diff workflow
|
|
type Workstream struct {
|
|
// Name is the unique identifier for the workstream
|
|
Name string `json:"name"`
|
|
|
|
// Description provides context about the workstream
|
|
Description string `json:"description"`
|
|
|
|
// BaseBranch is the Git branch this workstream is based on
|
|
BaseBranch string `json:"base_branch"`
|
|
|
|
// Commits is an ordered list of commits in this workstream
|
|
Commits []WorkstreamCommit `json:"commits"`
|
|
|
|
// Created is when the workstream was created
|
|
Created time.Time `json:"created"`
|
|
|
|
// Updated is when the workstream was last modified
|
|
Updated time.Time `json:"updated"`
|
|
|
|
// Status indicates the current state (active, merged, abandoned)
|
|
Status WorkstreamStatus `json:"status"`
|
|
|
|
// Metadata contains additional workstream-specific data
|
|
Metadata map[string]string `json:"metadata,omitempty"`
|
|
}
|
|
|
|
// WorkstreamCommit represents a single commit in a workstream
|
|
type WorkstreamCommit struct {
|
|
// SHA is the Git commit hash
|
|
SHA string `json:"sha"`
|
|
|
|
// Message is the commit message
|
|
Message string `json:"message"`
|
|
|
|
// Author is the commit author
|
|
Author string `json:"author"`
|
|
|
|
// Timestamp is when the commit was created
|
|
Timestamp time.Time `json:"timestamp"`
|
|
|
|
// ParentSHA is the parent commit in the workstream (empty for first commit)
|
|
ParentSHA string `json:"parent_sha,omitempty"`
|
|
|
|
// BaseSHA is the base commit from the base branch
|
|
BaseSHA string `json:"base_sha"`
|
|
|
|
// BranchRef is the Git reference for this commit (e.g., refs/onyx/workstreams/name/commit-1)
|
|
BranchRef string `json:"branch_ref"`
|
|
}
|
|
|
|
// WorkstreamStatus represents the state of a workstream
|
|
type WorkstreamStatus string
|
|
|
|
const (
|
|
// WorkstreamStatusActive indicates the workstream is being actively developed
|
|
WorkstreamStatusActive WorkstreamStatus = "active"
|
|
|
|
// WorkstreamStatusMerged indicates the workstream has been merged
|
|
WorkstreamStatusMerged WorkstreamStatus = "merged"
|
|
|
|
// WorkstreamStatusAbandoned indicates the workstream has been abandoned
|
|
WorkstreamStatusAbandoned WorkstreamStatus = "abandoned"
|
|
|
|
// WorkstreamStatusArchived indicates the workstream has been archived
|
|
WorkstreamStatusArchived WorkstreamStatus = "archived"
|
|
)
|
|
|
|
// WorkstreamCollection represents the collection of all workstreams
|
|
type WorkstreamCollection struct {
|
|
// Workstreams is a map of workstream name to Workstream
|
|
Workstreams map[string]*Workstream `json:"workstreams"`
|
|
|
|
// CurrentWorkstream is the name of the active workstream
|
|
CurrentWorkstream string `json:"current_workstream,omitempty"`
|
|
}
|
|
|
|
// NewWorkstream creates a new workstream
|
|
func NewWorkstream(name, description, baseBranch string) *Workstream {
|
|
now := time.Now()
|
|
return &Workstream{
|
|
Name: name,
|
|
Description: description,
|
|
BaseBranch: baseBranch,
|
|
Commits: []WorkstreamCommit{},
|
|
Created: now,
|
|
Updated: now,
|
|
Status: WorkstreamStatusActive,
|
|
Metadata: make(map[string]string),
|
|
}
|
|
}
|
|
|
|
// AddCommit adds a commit to the workstream
|
|
func (w *Workstream) AddCommit(commit WorkstreamCommit) {
|
|
w.Commits = append(w.Commits, commit)
|
|
w.Updated = time.Now()
|
|
}
|
|
|
|
// GetLatestCommit returns the latest commit in the workstream
|
|
func (w *Workstream) GetLatestCommit() (*WorkstreamCommit, error) {
|
|
if len(w.Commits) == 0 {
|
|
return nil, fmt.Errorf("workstream has no commits")
|
|
}
|
|
return &w.Commits[len(w.Commits)-1], nil
|
|
}
|
|
|
|
// GetCommitCount returns the number of commits in the workstream
|
|
func (w *Workstream) GetCommitCount() int {
|
|
return len(w.Commits)
|
|
}
|
|
|
|
// IsEmpty returns true if the workstream has no commits
|
|
func (w *Workstream) IsEmpty() bool {
|
|
return len(w.Commits) == 0
|
|
}
|
|
|
|
// NewWorkstreamCommit creates a new workstream commit
|
|
func NewWorkstreamCommit(sha, message, author, parentSHA, baseSHA, branchRef string) WorkstreamCommit {
|
|
return WorkstreamCommit{
|
|
SHA: sha,
|
|
Message: message,
|
|
Author: author,
|
|
Timestamp: time.Now(),
|
|
ParentSHA: parentSHA,
|
|
BaseSHA: baseSHA,
|
|
BranchRef: branchRef,
|
|
}
|
|
}
|
|
|
|
// NewWorkstreamCollection creates a new workstream collection
|
|
func NewWorkstreamCollection() *WorkstreamCollection {
|
|
return &WorkstreamCollection{
|
|
Workstreams: make(map[string]*Workstream),
|
|
}
|
|
}
|
|
|
|
// AddWorkstream adds a workstream to the collection
|
|
func (wc *WorkstreamCollection) AddWorkstream(workstream *Workstream) error {
|
|
if _, exists := wc.Workstreams[workstream.Name]; exists {
|
|
return fmt.Errorf("workstream '%s' already exists", workstream.Name)
|
|
}
|
|
wc.Workstreams[workstream.Name] = workstream
|
|
return nil
|
|
}
|
|
|
|
// GetWorkstream retrieves a workstream by name
|
|
func (wc *WorkstreamCollection) GetWorkstream(name string) (*Workstream, error) {
|
|
workstream, exists := wc.Workstreams[name]
|
|
if !exists {
|
|
return nil, fmt.Errorf("workstream '%s' not found", name)
|
|
}
|
|
return workstream, nil
|
|
}
|
|
|
|
// RemoveWorkstream removes a workstream from the collection
|
|
func (wc *WorkstreamCollection) RemoveWorkstream(name string) error {
|
|
if _, exists := wc.Workstreams[name]; !exists {
|
|
return fmt.Errorf("workstream '%s' not found", name)
|
|
}
|
|
delete(wc.Workstreams, name)
|
|
return nil
|
|
}
|
|
|
|
// ListWorkstreams returns all workstreams
|
|
func (wc *WorkstreamCollection) ListWorkstreams() []*Workstream {
|
|
workstreams := make([]*Workstream, 0, len(wc.Workstreams))
|
|
for _, ws := range wc.Workstreams {
|
|
workstreams = append(workstreams, ws)
|
|
}
|
|
return workstreams
|
|
}
|
|
|
|
// SetCurrentWorkstream sets the active workstream
|
|
func (wc *WorkstreamCollection) SetCurrentWorkstream(name string) error {
|
|
if _, exists := wc.Workstreams[name]; !exists {
|
|
return fmt.Errorf("workstream '%s' not found", name)
|
|
}
|
|
wc.CurrentWorkstream = name
|
|
return nil
|
|
}
|
|
|
|
// GetCurrentWorkstream returns the current workstream
|
|
func (wc *WorkstreamCollection) GetCurrentWorkstream() (*Workstream, error) {
|
|
if wc.CurrentWorkstream == "" {
|
|
return nil, fmt.Errorf("no current workstream set")
|
|
}
|
|
return wc.GetWorkstream(wc.CurrentWorkstream)
|
|
}
|
|
|
|
// Serialize converts the workstream collection to JSON
|
|
func (wc *WorkstreamCollection) Serialize() ([]byte, error) {
|
|
data, err := json.MarshalIndent(wc, "", " ")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal workstream collection: %w", err)
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
// DeserializeWorkstreamCollection converts JSON data to a workstream collection
|
|
func DeserializeWorkstreamCollection(data []byte) (*WorkstreamCollection, error) {
|
|
wc := &WorkstreamCollection{}
|
|
if err := json.Unmarshal(data, wc); err != nil {
|
|
return nil, fmt.Errorf("failed to unmarshal workstream collection: %w", err)
|
|
}
|
|
return wc, nil
|
|
}
|