11package main
22
33import (
4+ "encoding/base64"
45 "flag"
56 "fmt"
6- "text/template"
7- "os"
7+ "regexp"
8+ "strconv"
9+
10+ "github.com/sourcegraph/src-cli/internal/cmderrors"
811)
912
1013// searchJobFragment is a GraphQL fragment that defines the fields to be queried
@@ -51,6 +54,8 @@ The commands are:
5154 delete deletes a search job by ID
5255 get gets a search job by ID
5356 list lists search jobs
57+ logs outputs the logs for a search job by ID
58+ results outputs the results for a search job by ID
5459
5560Use "src search-jobs [command] -h" for more information about a command.
5661`
@@ -71,22 +76,12 @@ Use "src search-jobs [command] -h" for more information about a command.
7176 })
7277}
7378
74- // printSearchJob formats and prints a search job to stdout using the provided format template.
75- // Returns an error if the template parsing or execution fails.
76- func printSearchJob (job * SearchJob , format string ) error {
77- tmpl , err := template .New ("searchJob" ).Parse (format )
78- if err != nil {
79- return err
80- }
81- return tmpl .Execute (os .Stdout , job )
82- }
83-
8479// SearchJob represents a search job with its metadata, including the search query,
8580// execution state, creator information, timestamps, URLs, and repository statistics.
8681type SearchJob struct {
87- ID string
88- Query string
89- State string
82+ ID string
83+ Query string
84+ State string
9085 Creator struct {
9186 Username string
9287 }
@@ -96,9 +91,55 @@ type SearchJob struct {
9691 URL string
9792 LogURL string
9893 RepoStats struct {
99- Total int
100- Completed int
101- Failed int
102- InProgress int
94+ Total int
95+ Completed int
96+ Failed int
97+ InProgress int
98+ }
99+ }
100+
101+ type SearchJobID struct {
102+ number uint64
103+ }
104+
105+ func ParseSearchJobID (input string ) (* SearchJobID , error ) {
106+ // accept either:
107+ // - the numeric job id (non-negative integer)
108+ // - the plain text SearchJob:<integer> form of the id
109+ // - the base64-encoded "SearchJob:<integer>" string
110+
111+ if input == "" {
112+ return nil , cmderrors .Usage ("must provide a search job ID" )
113+ }
114+
115+ // Try to decode if it's base64 first
116+ if decoded , err := base64 .StdEncoding .DecodeString (input ); err == nil {
117+ input = string (decoded )
103118 }
119+
120+ // Match either "SearchJob:<integer>" or "<integer>"
121+ re := regexp .MustCompile (`^(?:SearchJob:)?(\d+)$` )
122+ matches := re .FindStringSubmatch (input )
123+ if matches == nil {
124+ return nil , fmt .Errorf ("invalid ID format: must be a non-negative integer, 'SearchJob:<integer>', or that string base64-encoded" )
125+ }
126+
127+ number , err := strconv .ParseUint (matches [1 ], 10 , 64 )
128+ if err != nil {
129+ return nil , fmt .Errorf ("invalid ID format: must be a 64-bit non-negative integer" )
130+ }
131+
132+ return & SearchJobID {number : number }, nil
133+ }
134+
135+ func (id * SearchJobID ) String () string {
136+ return fmt .Sprintf ("SearchJob:%d" , id .Number ())
137+ }
138+
139+ func (id * SearchJobID ) Canonical () string {
140+ return base64 .StdEncoding .EncodeToString ([]byte (id .String ()))
141+ }
142+
143+ func (id * SearchJobID ) Number () uint64 {
144+ return id .number
104145}
0 commit comments