@@ -7,7 +7,11 @@ import (
77 "strings"
88
99 "github.com/sourcegraph/sourcegraph/lib/errors"
10+ "github.com/sourcegraph/sourcegraph/lib/output"
11+ "google.golang.org/protobuf/proto"
1012
13+ "github.com/sourcegraph/sourcegraph/lib/codeintel/lsif/protocol/reader"
14+ "github.com/sourcegraph/sourcegraph/lib/codeintel/lsiftyped"
1115 "github.com/sourcegraph/sourcegraph/lib/codeintel/upload"
1216
1317 "github.com/sourcegraph/src-cli/internal/api"
@@ -84,11 +88,13 @@ func init() {
8488//
8589// On success, the global lsifUploadFlags object will be populated with valid values. An
8690// error is returned on failure.
87- func parseAndValidateLSIFUploadFlags (args []string ) error {
91+ func parseAndValidateLSIFUploadFlags (args []string ) ( * output. Output , error ) {
8892 if err := lsifUploadFlagSet .Parse (args ); err != nil {
89- return err
93+ return nil , err
9094 }
9195
96+ out := lsifUploadOutput ()
97+
9298 // extract only the -insecure-skip-verify flag so we dont get 'flag provided but not defined'
9399 var insecureSkipVerifyFlag []string
94100 for _ , s := range args {
@@ -102,11 +108,15 @@ func parseAndValidateLSIFUploadFlags(args []string) error {
102108 // and maybe we'll use some in the future
103109 lsifUploadFlags .apiFlags = api .NewFlags (apiClientFlagSet )
104110 if err := apiClientFlagSet .Parse (insecureSkipVerifyFlag ); err != nil {
105- return err
111+ return nil , err
112+ }
113+
114+ if err := handleLSIFTyped (out ); err != nil {
115+ return nil , err
106116 }
107117
108118 if inferenceErrors := inferMissingLSIFUploadFlags (); len (inferenceErrors ) > 0 {
109- return errorWithHint {
119+ return nil , errorWithHint {
110120 err : inferenceErrors [0 ].err , hint : strings .Join ([]string {
111121 fmt .Sprintf (
112122 "Unable to determine %s from environment. Check your working directory or supply -%s={value} explicitly" ,
@@ -118,17 +128,93 @@ func parseAndValidateLSIFUploadFlags(args []string) error {
118128 }
119129
120130 if err := validateLSIFUploadFlags (); err != nil {
121- return err
131+ return nil , err
122132 }
123133
124- return nil
134+ return out , nil
135+ }
136+
137+ // lsifUploadOutput returns an output object that should be used to print the progres
138+ // of requests made during this upload. If -json, -no-progress, or -trace>0 is given,
139+ // then no output object is defined.
140+ //
141+ // For -no-progress and -trace>0 conditions, emergency loggers will be used to display
142+ // inferred arguments and the URL at which processing status is shown.
143+ func lsifUploadOutput () (out * output.Output ) {
144+ if lsifUploadFlags .json || lsifUploadFlags .noProgress || lsifUploadFlags .verbosity > 0 {
145+ return nil
146+ }
147+
148+ return output .NewOutput (flag .CommandLine .Output (), output.OutputOpts {
149+ Verbose : true ,
150+ })
125151}
126152
127153type argumentInferenceError struct {
128154 argument string
129155 err error
130156}
131157
158+ func handleLSIFTyped (out * output.Output ) error {
159+ if strings .HasSuffix (lsifUploadFlags .file , ".lsif-typed" ) {
160+ // The user explicitly passed in a -file flag that points to an LSIF Typed index.
161+ inputFile := lsifUploadFlags .file
162+ outputFile := strings .TrimSuffix (inputFile , "-typed" )
163+ lsifUploadFlags .file = outputFile
164+ return convertLSIFTypedToLSIFGraph (out , inputFile , outputFile )
165+ }
166+
167+ if _ , err := os .Stat (lsifUploadFlags .file ); err == nil {
168+ // Do nothing, the provided -flag flag points to an existing
169+ // file that does not have the file extension `*.lsif-typed`.
170+ return nil
171+ }
172+
173+ lsifTypedFile := lsifUploadFlags .file + "-typed"
174+ if _ , err := os .Stat (lsifTypedFile ); os .IsNotExist (err ) {
175+ // The inferred path of the sibling `*.lsif-typed` file does not exist.
176+ return nil
177+ }
178+
179+ // The provided -file flag points to an `*.lsif` file that doesn't exist
180+ // so we convert the sibling `*.lsif-typed` file (which we confirmed exists).
181+ return convertLSIFTypedToLSIFGraph (out , lsifTypedFile , lsifUploadFlags .file )
182+ }
183+
184+ // Reads the LSIF Typed encoded input file and writes the corresponding LSIF
185+ // Graph encoded output file.
186+ func convertLSIFTypedToLSIFGraph (out * output.Output , inputFile , outputFile string ) error {
187+ out .Writef ("%s Converting %s into %s" , output .EmojiInfo , inputFile , outputFile )
188+ tmp , err := os .Create (outputFile )
189+ if err != nil {
190+ return err
191+ }
192+ defer tmp .Close ()
193+
194+ data , err := os .ReadFile (inputFile )
195+ if err != nil {
196+ panic (err )
197+ }
198+ index := lsiftyped.Index {}
199+ err = proto .Unmarshal (data , & index )
200+ if err != nil {
201+ panic (errors .Wrapf (err , "failed to parse protobuf file '%s'" , inputFile ))
202+ }
203+ els , err := reader .ConvertTypedIndexToGraphIndex (& index )
204+ if err != nil {
205+ panic (errors .Wrapf (err , "failed reader.ConvertTypedIndexToGraphIndex" ))
206+ }
207+ err = reader .WriteNDJSON (reader .ElementsToJsonElements (els ), tmp )
208+ if err != nil {
209+ panic (err )
210+ }
211+ err = tmp .Close ()
212+ if err != nil {
213+ return err
214+ }
215+ return nil
216+ }
217+
132218// inferMissingLSIFUploadFlags updates the flags values which were not explicitly
133219// supplied by the user with default values inferred from the current git state and
134220// filesystem.
0 commit comments