golang.org/x/build@v0.0.0-20240506185731-218518f32b70/internal/task/dlcl.go (about)

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package task
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"go/format"
    11  	"path"
    12  	"strings"
    13  	"text/template"
    14  	"time"
    15  
    16  	"golang.org/x/build/gerrit"
    17  	"golang.org/x/build/internal/workflow"
    18  )
    19  
    20  // MailDLCL mails a golang.org/dl CL that adds commands for the
    21  // specified Go version.
    22  //
    23  // The version string must use the same format as Go tags. For example:
    24  //   - "go1.21rc2" for a pre-release
    25  //   - "go1.21.0" for a major Go release
    26  //   - "go1.21.1" for a minor Go release
    27  //
    28  // On success, the ID of the change is returned, like "dl~1234".
    29  func (t *VersionTasks) MailDLCL(ctx *workflow.TaskContext, major int, kind ReleaseKind, version string, reviewers []string, dryRun bool) (changeID string, _ error) {
    30  	var files = make(map[string]string) // Map key is relative path, and map value is file content.
    31  
    32  	// Generate main.go files for versions from the template.
    33  	var buf bytes.Buffer
    34  	if err := dlTmpl.Execute(&buf, struct {
    35  		Year    int
    36  		Version string // "go1.21rc2"
    37  		DocLink string // "https://go.dev/doc/go1.21"
    38  	}{
    39  		Year:    time.Now().UTC().Year(),
    40  		Version: version,
    41  		DocLink: docLink(major, kind, version),
    42  	}); err != nil {
    43  		return "", fmt.Errorf("dlTmpl.Execute: %v", err)
    44  	}
    45  	gofmted, err := format.Source(buf.Bytes())
    46  	if err != nil {
    47  		return "", fmt.Errorf("could not gofmt: %v", err)
    48  	}
    49  	files[path.Join(version, "main.go")] = string(gofmted)
    50  	ctx.Printf("file %q (command %q):\n%s", path.Join(version, "main.go"), "golang.org/dl/"+version, gofmted)
    51  
    52  	// Create a Gerrit CL using the Gerrit API.
    53  	if dryRun {
    54  		return "(dry-run)", nil
    55  	}
    56  	changeInput := gerrit.ChangeInput{
    57  		Project: "dl",
    58  		Subject: "dl: add " + version,
    59  		Branch:  "master",
    60  	}
    61  	return t.Gerrit.CreateAutoSubmitChange(ctx, changeInput, reviewers, files)
    62  }
    63  
    64  func docLink(major int, kind ReleaseKind, ver string) string {
    65  	if kind == KindMinor {
    66  		return fmt.Sprintf("https://go.dev/doc/devel/release#%v", ver)
    67  	}
    68  
    69  	host := "go.dev"
    70  	if kind == KindBeta || kind == KindRC {
    71  		host = "tip.golang.org"
    72  	}
    73  	return fmt.Sprintf("https://%v/doc/go1.%d", host, major)
    74  }
    75  
    76  var dlTmpl = template.Must(template.New("").Funcs(template.FuncMap{
    77  	"short": func(v string) string { return strings.TrimPrefix(v, "go") },
    78  }).Parse(`// Copyright {{.Year}} The Go Authors. All rights reserved.
    79  // Use of this source code is governed by a BSD-style
    80  // license that can be found in the LICENSE file.
    81  
    82  // The {{.Version}} command runs the go command from Go {{.Version|short}}.
    83  //
    84  // To install, run:
    85  //
    86  //	$ go install golang.org/dl/{{.Version}}@latest
    87  //	$ {{.Version}} download
    88  //
    89  // And then use the {{.Version}} command as if it were your normal go
    90  // command.
    91  //
    92  // See the release notes at {{.DocLink}}.
    93  //
    94  // File bugs at https://go.dev/issue/new.
    95  package main
    96  
    97  import "golang.org/dl/internal/version"
    98  
    99  func main() {
   100  	version.Run("{{.Version}}")
   101  }
   102  `))