add command to specify task
add runTask to run spesific task with spesific interface
This commit is contained in:
@@ -3,14 +3,12 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/LazyBachelor/LazyPM/pkg/cli/repl"
|
|
||||||
"github.com/LazyBachelor/LazyPM/pkg/task"
|
"github.com/LazyBachelor/LazyPM/pkg/task"
|
||||||
"github.com/LazyBachelor/LazyPM/pkg/tui"
|
|
||||||
"github.com/LazyBachelor/LazyPM/pkg/web"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var interfaceType string
|
var interfaceType string
|
||||||
|
var stage int
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "survey",
|
Use: "survey",
|
||||||
@@ -42,29 +40,37 @@ var submitCmd = &cobra.Command{
|
|||||||
func runStartCmd(cmd *cobra.Command, args []string) error {
|
func runStartCmd(cmd *cobra.Command, args []string) error {
|
||||||
interfaces := initInterfaces()
|
interfaces := initInterfaces()
|
||||||
|
|
||||||
if cmd.Flags().Changed("interface") {
|
|
||||||
switch interfaceType {
|
|
||||||
case "tui":
|
|
||||||
interfaces = []task.Interface{tui.NewTui()}
|
|
||||||
case "repl":
|
|
||||||
interfaces = []task.Interface{repl.NewRepl()}
|
|
||||||
case "web":
|
|
||||||
interfaces = []task.Interface{web.NewWeb()}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("invalid interface type: %s", interfaceType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := newIntroModel().Run(); err != nil {
|
|
||||||
return returnIfUserQuit(err, "failed to run intro")
|
|
||||||
}
|
|
||||||
|
|
||||||
svc, cleanup, err := initializeServices(cmd.Context())
|
svc, cleanup, err := initializeServices(cmd.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return returnIfUserQuit(err, "failed to initialize services")
|
return returnIfUserQuit(err, "failed to initialize services")
|
||||||
}
|
}
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
|
tasks := initTasks(svc)
|
||||||
|
|
||||||
|
if cmd.Flags().Changed("interface") {
|
||||||
|
if _, ok := interfaces[interfaceType]; !ok {
|
||||||
|
return fmt.Errorf("invalid interface, valid are (tui, repl, web)")
|
||||||
|
}
|
||||||
|
interfaces = map[string]task.Interface{
|
||||||
|
interfaceType: interfaces[interfaceType],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Flags().Changed("stage") {
|
||||||
|
if stage < 1 || stage > len(tasks) {
|
||||||
|
return fmt.Errorf("invalid stage")
|
||||||
|
}
|
||||||
|
if err := runTask(cmd.Context(), tasks[stage-1], interfaces[interfaceType]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := newIntroModel().Run(); err != nil {
|
||||||
|
return returnIfUserQuit(err, "failed to run intro")
|
||||||
|
}
|
||||||
|
|
||||||
surveyTasks := initTasks(svc)
|
surveyTasks := initTasks(svc)
|
||||||
|
|
||||||
if err := taskLoop(cmd.Context(), surveyTasks, interfaces); err != nil {
|
if err := taskLoop(cmd.Context(), surveyTasks, interfaces); err != nil {
|
||||||
@@ -75,7 +81,8 @@ func runStartCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.CompletionOptions.DisableDefaultCmd = true
|
rootCmd.CompletionOptions.DisableDefaultCmd = true
|
||||||
startCmd.Flags().StringVarP(&interfaceType, "interface", "i", "", "Specify which interface to use for the survey (tui, repl, web).")
|
startCmd.Flags().StringVarP(&interfaceType, "interface", "i", "tui", "Specify interface.")
|
||||||
|
startCmd.Flags().IntVarP(&stage, "stage", "s", 1, "Run stage directly")
|
||||||
rootCmd.AddCommand(startCmd)
|
rootCmd.AddCommand(startCmd)
|
||||||
rootCmd.AddCommand(submitCmd)
|
rootCmd.AddCommand(submitCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ func initTasks(svc *service.Services) []*task.Task {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initInterfaces() []task.Interface {
|
func initInterfaces() map[string]task.Interface {
|
||||||
return []task.Interface{repl.NewRepl(), tui.NewTui(), web.NewWeb()}
|
return map[string]task.Interface{
|
||||||
|
"repl": repl.NewRepl(),
|
||||||
|
"tui": tui.NewTui(),
|
||||||
|
"web": web.NewWeb(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ func (m introModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
|
|
||||||
func (m introModel) View() string {
|
func (m introModel) View() string {
|
||||||
if m.width < 55 || m.height < 16 {
|
if m.width < 55 || m.height < 16 {
|
||||||
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, "Terminal too small.")
|
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center,
|
||||||
|
style.TextStyle.Render("Terminal too small."))
|
||||||
}
|
}
|
||||||
|
|
||||||
var content string
|
var content string
|
||||||
@@ -127,10 +128,9 @@ func (m introModel) View() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
boxWidth := min(m.width-10, 90)
|
boxWidth := min(m.width-10, 80)
|
||||||
|
|
||||||
boxStyle := lipgloss.NewStyle().
|
boxStyle := style.BorderStyle.
|
||||||
Border(style.DefaultBorder).
|
|
||||||
Margin(1, 0).Padding(2, 4).Width(boxWidth)
|
Margin(1, 0).Padding(2, 4).Width(boxWidth)
|
||||||
|
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
@@ -138,7 +138,7 @@ func (m introModel) View() string {
|
|||||||
b.WriteString(style.TitleStyle.Render(IntroTitle))
|
b.WriteString(style.TitleStyle.Render(IntroTitle))
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
|
|
||||||
b.WriteString(boxStyle.Render(content))
|
b.WriteString(boxStyle.Render(style.TextStyle.Render(content)))
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
|
|
||||||
helpText := "Press " + keys.Continue.Help().Key + " to continue • " +
|
helpText := "Press " + keys.Continue.Help().Key + " to continue • " +
|
||||||
|
|||||||
@@ -10,60 +10,71 @@ import (
|
|||||||
"github.com/LazyBachelor/LazyPM/pkg/task"
|
"github.com/LazyBachelor/LazyPM/pkg/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
func taskLoop(ctx context.Context, surveyTasks []*task.Task, interfaces []task.Interface) error {
|
func runTask(ctx context.Context, t *task.Task, i task.Interface) error {
|
||||||
interfaceIndex := rand.Int() % len(interfaces)
|
t.SetInterface(i)
|
||||||
|
t.SetInterfaceType(tasks.InterfaceToType(i))
|
||||||
|
|
||||||
for _, t := range surveyTasks {
|
doneChan := make(chan bool, 1)
|
||||||
|
quitChan := make(chan bool, 1)
|
||||||
|
feedbackChan := make(chan task.ValidationFeedback, 10)
|
||||||
|
|
||||||
t.SetInterface(interfaces[interfaceIndex])
|
if validated, ok := i.(task.ValidatedInterface); ok {
|
||||||
t.SetInterfaceType(tasks.InterfaceToType(interfaces[interfaceIndex]))
|
validated.SetChannels(feedbackChan, quitChan)
|
||||||
|
}
|
||||||
|
|
||||||
doneChan := make(chan bool, 1)
|
if err := t.Initialize(ctx); err != nil {
|
||||||
quitChan := make(chan bool, 1)
|
return fmt.Errorf("failed to initialize task: %w", err)
|
||||||
feedbackChan := make(chan task.ValidationFeedback, 10)
|
}
|
||||||
|
|
||||||
if validated, ok := interfaces[interfaceIndex].(task.ValidatedInterface); ok {
|
if err := t.IntroduceTask(); err != nil {
|
||||||
validated.SetChannels(feedbackChan, quitChan)
|
return returnIfUserQuit(err, "failed to display task introduction screen")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.SetChannels(feedbackChan, doneChan, quitChan)
|
||||||
|
|
||||||
|
go t.StartValidationLoop(ctx)
|
||||||
|
|
||||||
|
interfaceDone := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
interfaceDone <- t.StartInterface(ctx, t.Config)
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-doneChan:
|
||||||
|
close(quitChan)
|
||||||
|
<-interfaceDone
|
||||||
|
fmt.Println("Task completed successfully!")
|
||||||
|
|
||||||
|
case err := <-interfaceDone:
|
||||||
|
close(quitChan)
|
||||||
|
if err != nil {
|
||||||
|
return returnIfUserQuit(err, "failed to start task interface")
|
||||||
}
|
}
|
||||||
|
fmt.Println("Task incomplete - you exited early")
|
||||||
|
}
|
||||||
|
|
||||||
if err := t.Initialize(ctx); err != nil {
|
if err := t.StartQuestionnaire(); err != nil {
|
||||||
return fmt.Errorf("failed to initialize task: %w", err)
|
return returnIfUserQuit(err, "failed to start questionnaire")
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if err := t.IntroduceTask(); err != nil {
|
func taskLoop(ctx context.Context, surveyTasks []*task.Task, interfaces map[string]task.Interface) error {
|
||||||
return returnIfUserQuit(err, "failed to display task introduction screen")
|
var ifaceNames []string
|
||||||
}
|
for name := range interfaces {
|
||||||
|
ifaceNames = append(ifaceNames, name)
|
||||||
|
}
|
||||||
|
|
||||||
t.SetChannels(feedbackChan, doneChan, quitChan)
|
rand.Shuffle(len(ifaceNames), func(i, j int) {
|
||||||
|
ifaceNames[i], ifaceNames[j] = ifaceNames[j], ifaceNames[i]
|
||||||
|
})
|
||||||
|
|
||||||
go t.StartValidationLoop(ctx)
|
for i, task := range surveyTasks {
|
||||||
|
idx := i % len(ifaceNames)
|
||||||
|
selected := interfaces[ifaceNames[idx]]
|
||||||
|
|
||||||
interfaceDone := make(chan error, 1)
|
if err := runTask(ctx, task, selected); err != nil {
|
||||||
go func() {
|
return err
|
||||||
interfaceDone <- t.StartInterface(ctx, t.Config)
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-doneChan:
|
|
||||||
close(quitChan)
|
|
||||||
<-interfaceDone
|
|
||||||
fmt.Println("Task completed successfully!")
|
|
||||||
|
|
||||||
case err := <-interfaceDone:
|
|
||||||
close(quitChan)
|
|
||||||
if err != nil {
|
|
||||||
return returnIfUserQuit(err, "failed to start task interface")
|
|
||||||
}
|
|
||||||
fmt.Println("Task incomplete - you exited early")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := t.StartQuestionnaire(); err != nil {
|
|
||||||
return returnIfUserQuit(err, "failed to start questionnaire")
|
|
||||||
}
|
|
||||||
|
|
||||||
interfaceIndex++
|
|
||||||
if interfaceIndex >= len(interfaces) {
|
|
||||||
interfaceIndex = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ var (
|
|||||||
SecondaryColor = lipgloss.AdaptiveColor{Light: "#ff6f61", Dark: "#ff6347"}
|
SecondaryColor = lipgloss.AdaptiveColor{Light: "#ff6f61", Dark: "#ff6347"}
|
||||||
AccentColor = lipgloss.AdaptiveColor{Light: "#6a5acd", Dark: "#9370db"}
|
AccentColor = lipgloss.AdaptiveColor{Light: "#6a5acd", Dark: "#9370db"}
|
||||||
Background = lipgloss.AdaptiveColor{Light: "#ffffff", Dark: "#1e1e1e"}
|
Background = lipgloss.AdaptiveColor{Light: "#ffffff", Dark: "#1e1e1e"}
|
||||||
TextColor = lipgloss.AdaptiveColor{Light: "#000000", Dark: "#ffffff"}
|
TextColor = lipgloss.AdaptiveColor{Light: "#252525b7", Dark: "#ffffff"}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -21,8 +21,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TitleStyle = lipgloss.NewStyle().Foreground(PrimaryColor).Bold(true)
|
TitleStyle = lipgloss.NewStyle().Foreground(PrimaryColor).Bold(true)
|
||||||
DescriptionStyle = lipgloss.NewStyle().Foreground(TextColor).Italic(true)
|
TextStyle = lipgloss.NewStyle().Foreground(TextColor)
|
||||||
DetailStyle = lipgloss.NewStyle().Foreground(SecondaryColor)
|
HelpStyle = lipgloss.NewStyle().Align(lipgloss.Center).Foreground(AccentColor)
|
||||||
HelpStyle = lipgloss.NewStyle().Align(lipgloss.Center).Foreground(AccentColor)
|
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user