| 88 | } |
| 89 | |
| 90 | func runVerify(cmd *cobra.Command, args []string) error { |
| 91 | taskID, err := resolveVerifyTaskID(args) |
| 92 | if err != nil { |
| 93 | return err |
| 94 | } |
| 95 | |
| 96 | flags := GetGlobalFlags() |
| 97 | scanDir := ResolveScanDir(nil) |
| 98 | |
| 99 | taskScanner := scanner.NewScanner(scanDir, flags.Verbose, flags.IgnoreDirs) |
| 100 | result, err := taskScanner.Scan() |
| 101 | if err != nil { |
| 102 | return fmt.Errorf("scan failed: %w", err) |
| 103 | } |
| 104 | |
| 105 | warnDuplicateIDs(result.Tasks) |
| 106 | |
| 107 | task := findExactMatch(taskID, result.Tasks) |
| 108 | if task == nil { |
| 109 | return fmt.Errorf("task not found: %s", taskID) |
| 110 | } |
| 111 | |
| 112 | if len(task.Verify) == 0 { |
| 113 | fmt.Println("No verification checks defined for this task.") |
| 114 | return nil |
| 115 | } |
| 116 | |
| 117 | if errs := model.ValidateVerifySteps(task.Verify); len(errs) > 0 { |
| 118 | return fmt.Errorf("invalid verify steps:\n %s", strings.Join(errs, "\n ")) |
| 119 | } |
| 120 | |
| 121 | projectRoot := resolveProjectRoot() |
| 122 | opts := verify.Options{ |
| 123 | ProjectRoot: projectRoot, |
| 124 | DryRun: verifyDryRun, |
| 125 | FailFast: !verifyAll, |
| 126 | Timeout: time.Duration(verifyTimeout) * time.Second, |
| 127 | Verbose: flags.Verbose, |
| 128 | LogFunc: func(format string, args ...any) { |
| 129 | if !flags.Quiet { |
| 130 | fmt.Fprintf(os.Stderr, format+"\n", args...) |
| 131 | } |
| 132 | }, |
| 133 | } |
| 134 | |
| 135 | vResult := verify.Run(task.Verify, opts) |
| 136 | |
| 137 | switch verifyFormat { |
| 138 | case "json": |
| 139 | return WriteJSON(os.Stdout, vResult) |
| 140 | case "table": |
| 141 | printVerifyTable(vResult) |
| 142 | default: |
| 143 | return ValidateFormat(verifyFormat, []string{"table", "json"}) |
| 144 | } |
| 145 | |
| 146 | if vResult.HasFailures() { |
| 147 | return ErrVerifyFailed |