Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/src/batch_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ func executeBatchSpec(ctx context.Context, opts executeBatchSpecOpts) (err error
Client: opts.client,
})

ffs, err := svc.DetermineFeatureFlags(ctx)
lr, ffs, err := svc.DetermineLicenseAndFeatureFlags(ctx)
if err != nil {
return err
}
Expand Down Expand Up @@ -521,7 +521,7 @@ func executeBatchSpec(ctx context.Context, opts executeBatchSpecOpts) (err error
execUI.CreatingBatchSpec()
id, url, err := svc.CreateBatchSpec(ctx, namespace.ID, rawSpec, ids)
if err != nil {
return execUI.CreatingBatchSpecError(err)
return execUI.CreatingBatchSpecError(lr.MaxUnlicensedChangesets, err)
}
previewURL := cfg.Endpoint + url
execUI.CreatingBatchSpecSuccess(previewURL)
Expand Down
2 changes: 1 addition & 1 deletion cmd/src/batch_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Examples:
Client: cfg.apiClient(apiFlags, flagSet.Output()),
})

ffs, err := svc.DetermineFeatureFlags(ctx)
_, ffs, err := svc.DetermineLicenseAndFeatureFlags(ctx)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/src/batch_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Examples:
Client: cfg.apiClient(flags.api, flagSet.Output()),
})

ffs, err := svc.DetermineFeatureFlags(ctx)
_, ffs, err := svc.DetermineLicenseAndFeatureFlags(ctx)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/src/batch_repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Examples:
Client: client,
})

ffs, err := svc.DetermineFeatureFlags(ctx)
_, ffs, err := svc.DetermineLicenseAndFeatureFlags(ctx)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/src/batch_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Examples:
Client: cfg.apiClient(apiFlags, flagSet.Output()),
})

ffs, err := svc.DetermineFeatureFlags(ctx)
_, ffs, err := svc.DetermineLicenseAndFeatureFlags(ctx)
if err != nil {
return err
}
Expand Down
5 changes: 5 additions & 0 deletions internal/batches/license.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package batches

type LicenseRestrictions struct {
MaxUnlicensedChangesets int
}
36 changes: 22 additions & 14 deletions internal/batches/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ func New(opts *Opts) *Service {
// The reason we ask for batchChanges here is to surface errors about trying to use batch
// changes in an unsupported environment sooner, since the version check is typically the
// first thing we do.
const sourcegraphVersionQuery = `query SourcegraphVersion {
const getInstanceInfo = `query InstanceInfo {
site {
productVersion
}
maxUnlicensedChangesets
batchChanges(first: 1) {
nodes {
id
Expand All @@ -55,32 +56,39 @@ const sourcegraphVersionQuery = `query SourcegraphVersion {
}
`

// getSourcegraphVersion queries the Sourcegraph GraphQL API to get the
// current version of the Sourcegraph instance.
func (svc *Service) getSourcegraphVersion(ctx context.Context) (string, error) {
// getSourcegraphVersionAndMaxChangesetsCount queries the Sourcegraph GraphQL API to get the
// current version and max unlicensed changesets count for the Sourcegraph instance.
func (svc *Service) getSourcegraphVersionAndMaxChangesetsCount(ctx context.Context) (string, int, error) {
var result struct {
Site struct {
MaxUnlicensedChangesets int
Site struct {
ProductVersion string
}
}

ok, err := svc.client.NewQuery(sourcegraphVersionQuery).Do(ctx, &result)
ok, err := svc.client.NewQuery(getInstanceInfo).Do(ctx, &result)
if err != nil || !ok {
return "", err
return "", 0, err
}

return result.Site.ProductVersion, err
return result.Site.ProductVersion, result.MaxUnlicensedChangesets, err
}

// DetermineFeatureFlags fetches the version of the configured Sourcegraph and
// returns the enabled features.
func (svc *Service) DetermineFeatureFlags(ctx context.Context) (*batches.FeatureFlags, error) {
version, err := svc.getSourcegraphVersion(ctx)
// DetermineLicenseAndFeatureFlags returns the enabled features and license restrictions
// configured for the Sourcegraph instance.
func (svc *Service) DetermineLicenseAndFeatureFlags(ctx context.Context) (*batches.LicenseRestrictions, *batches.FeatureFlags, error) {
version, mc, err := svc.getSourcegraphVersionAndMaxChangesetsCount(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to query Sourcegraph version to check for available features")
return nil, nil, errors.Wrap(err, "failed to query Sourcegraph version and license info for instance")
}

lr := &batches.LicenseRestrictions{
MaxUnlicensedChangesets: mc,
}

ffs := &batches.FeatureFlags{}
return ffs, ffs.SetFromVersion(version)
return lr, ffs, ffs.SetFromVersion(version)

}

const applyBatchChangeMutation = `
Expand Down
2 changes: 1 addition & 1 deletion internal/batches/ui/exec_ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type ExecUI interface {

CreatingBatchSpec()
CreatingBatchSpecSuccess(previewURL string)
CreatingBatchSpecError(err error) error
CreatingBatchSpecError(maxUnlicensedCS int, err error) error

PreviewBatchSpec(previewURL string)

Expand Down
2 changes: 1 addition & 1 deletion internal/batches/ui/json_lines.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (ui *JSONLines) CreatingBatchSpecSuccess(batchSpecURL string) {
})
}

func (ui *JSONLines) CreatingBatchSpecError(err error) error {
func (ui *JSONLines) CreatingBatchSpecError(_ int, err error) error {
logOperationFailure(batcheslib.LogEventOperationCreatingBatchSpec, &batcheslib.CreatingBatchSpecMetadata{})
return err
}
Expand Down
14 changes: 7 additions & 7 deletions internal/batches/ui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ func (ui *TUI) CreatingBatchSpecSuccess(previewURL string) {
batchCompletePending(ui.pending, "Creating batch spec on Sourcegraph")
}

func (ui *TUI) CreatingBatchSpecError(err error) error {
return prettyPrintBatchUnlicensedError(ui.Out, err)
func (ui *TUI) CreatingBatchSpecError(maxUnlicensedCS int, err error) error {
return prettyPrintBatchUnlicensedError(ui.Out, maxUnlicensedCS, err)
}

func (ui *TUI) DockerWatchDogWarning(err error) {
Expand Down Expand Up @@ -307,7 +307,7 @@ func (ui *TUI) RemoteSuccess(url string) {
// is, then a better message is output. Regardless, the return value of this
// function should be used to replace the original error passed in to ensure
// that the displayed output is sensible.
func prettyPrintBatchUnlicensedError(out *output.Output, err error) error {
func prettyPrintBatchUnlicensedError(out *output.Output, maxUnlicensedCS int, err error) error {
// Pull apart the error to see if it's a licensing error: if so, we should
// display a friendlier and more actionable message than the usual GraphQL
// error output.
Expand All @@ -321,19 +321,19 @@ func prettyPrintBatchUnlicensedError(out *output.Output, err error) error {
// verbose mode, but let the original error bubble up rather
// than this one.
out.Verbosef("Unexpected error parsing the GraphQL error: %v", cerr)
} else if code == "ErrBatchChangesUnlicensed" {
} else if code == "ErrBatchChangesUnlicensed" || code == "ErrBatchChangesOverLimit" {
// OK, let's print a better message, then return an
// exitCodeError to suppress the normal automatic error block.
// Note that we have hand wrapped the output at 80 (printable)
// characters: having automatic wrapping some day would be nice,
// but this should be sufficient for now.
block := out.Block(output.Line("🪙", output.StyleWarning, "Batch Changes is a paid feature of Sourcegraph. All users can create sample"))
block.WriteLine(output.Linef("", output.StyleWarning, "batch changes with up to 10 changesets without a license. Contact Sourcegraph"))
block.WriteLine(output.Linef("", output.StyleWarning, "batch changes with up to %v changesets without a license. Contact Sourcegraph", maxUnlicensedCS))
block.WriteLine(output.Linef("", output.StyleWarning, "sales at %shttps://about.sourcegraph.com/contact/sales/%s to obtain a trial", output.StyleSearchLink, output.StyleWarning))
block.WriteLine(output.Linef("", output.StyleWarning, "license."))
block.Write("")
block.WriteLine(output.Linef("", output.StyleWarning, "To proceed with this batch change, you will need to create 5 or fewer"))
block.WriteLine(output.Linef("", output.StyleWarning, "changesets. To do so, you could try adding %scount:5%s to your", output.StyleSearchAlertProposedQuery, output.StyleWarning))
block.WriteLine(output.Linef("", output.StyleWarning, "To proceed with this batch change, you will need to create %v or fewer", maxUnlicensedCS))
block.WriteLine(output.Linef("", output.StyleWarning, "changesets. To do so, you could try adding %scount:%v%s to your", output.StyleSearchAlertProposedQuery, maxUnlicensedCS, output.StyleWarning))
block.WriteLine(output.Linef("", output.StyleWarning, "%srepositoriesMatchingQuery%s search, or reduce the number of changesets in", output.StyleReset, output.StyleWarning))
block.WriteLine(output.Linef("", output.StyleWarning, "%simportChangesets%s.", output.StyleReset, output.StyleWarning))
block.Close()
Expand Down