blob: 4ef4eb6b0bcb403e1fcdd702d96ef14dafa50e85 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"errors"
"flag"
"fmt"
"os"
"strings"
"text/template"
"go.fuchsia.dev/jiri"
"go.fuchsia.dev/jiri/cmdline"
"go.fuchsia.dev/jiri/project"
)
// Flags for cmdManifest.
var manifestFlags struct {
// ElementName is a flag specifying the name= of the <import> or <project>
// to search for in the manifest file.
ElementName string
// Template is a string template from pkg/text/template specifying which
// fields to display. The invoker of Jiri is expected to form this template
// themselves.
Template string
}
var cmdManifest = &cmdline.Command{
Runner: jiri.RunnerFunc(runManifest),
Name: "manifest",
Short: "Reads <import>, <project> or <package> information from a manifest file",
Long: `Reads <import>, <project> or <package> information from a manifest file.
A template matching the schema defined in pkg/text/template is used to fill
in the requested information. Some examples:
Read project's 'remote' attribute:
manifest -element=$PROJECT_NAME -template="{{.Remote}}"
Read import's 'path' attribute:
manifest -element=$IMPORT_NAME -template="{{.Path}}"
Read packages's 'version' attribute:
manifest -element=$PACKAGE_NAME -template="{{.Version}}"
`,
ArgsName: "<manifest>",
ArgsLong: "<manifest> is the manifest file.",
}
func init() {
setManifestFlags(&cmdManifest.Flags)
}
// setManifestFlags sets command-line flags for the manifest command.
func setManifestFlags(f *flag.FlagSet) {
f.StringVar(&manifestFlags.ElementName, "element", "", "Name of the <project>, <import> or <package>.")
f.StringVar(&manifestFlags.Template, "template", "", "The template for the fields to display.")
}
// Run executes the ManifestCommand.
func runManifest(jirix *jiri.X, args []string) error {
if len(args) != 1 {
return jirix.UsageErrorf("Wrong number of args")
}
manifestPath := args[0]
if manifestFlags.ElementName == "" {
return errors.New("-element is required")
}
if manifestFlags.Template == "" {
return errors.New("-template is required")
}
// Create the template to fill in.
tmpl, err := template.New("").Parse(manifestFlags.Template)
if err != nil {
return fmt.Errorf("failed to parse -template: %s", err)
}
return readManifest(jirix, manifestPath, tmpl)
}
func readManifest(jirix *jiri.X, manifestPath string, tmpl *template.Template) error {
manifest, err := project.ManifestFromFile(jirix, manifestPath)
if err != nil {
return err
}
elementName := strings.ToLower(manifestFlags.ElementName)
// Check if any <project> elements match the given element name.
for _, project := range manifest.Projects {
if strings.ToLower(project.Name) == elementName {
return tmpl.Execute(os.Stdout, &project)
}
}
// Check if any <import> elements match the given element name.
for _, imprt := range manifest.Imports {
if strings.ToLower(imprt.Name) == elementName {
return tmpl.Execute(os.Stdout, &imprt)
}
}
// Check if any <package> elements match the given element name.
for _, pkg := range manifest.Packages {
if strings.ToLower(pkg.Name) == elementName {
return tmpl.Execute(os.Stdout, &pkg)
}
}
// Found nothing.
return fmt.Errorf("found no project/import/package named %s", manifestFlags.ElementName)
}