Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  ninja.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package local

import (
 "bufio"
 "bytes"
 "context"
 "errors"
 "fmt"
 "io"
 "io/ioutil"
 "os/exec"
 "strings"
 "time"

 "tools/treble/build/report/app"
)

// Performance degrades running multiple CLIs
const (
 MaxNinjaCliWorkers       = 4
 DefaultNinjaTimeout      = "100s"
 DefaultNinjaBuildTimeout = "30m"
)

// Separate out the executable to allow tests to override the results
type ninjaExec interface {
 Command(ctx context.Context, target string) (*bytes.Buffer, error)
 Input(ctx context.Context, target string) (*bytes.Buffer, error)
 Query(ctx context.Context, target string) (*bytes.Buffer, error)
 Path(ctx context.Context, target string, dependency string) (*bytes.Buffer, error)
 Paths(ctx context.Context, target string, dependency string) (*bytes.Buffer, error)
 Deps(ctx context.Context) (*bytes.Buffer, error)
 Build(ctx context.Context, target string) (*bytes.Buffer, error)
}

// Parse data

// Add all lines to a given array removing any leading whitespace
func linesToArray(s *bufio.Scanner, arr *[]string) {
 for s.Scan() {
  line := strings.TrimSpace(s.Text())
  *arr = append(*arr, line)
 }
}

// parse -t commands
func parseCommand(target string, data *bytes.Buffer) (*app.BuildCommand, error) {
 out := &app.BuildCommand{Target: target, Cmds: []string{}}
 s := bufio.NewScanner(data)
 // This tool returns all the commands needed to build a target.
 // When running against a target like droid the default capacity
 // will be overrun.   Extend the capacity here.
 const capacity = 1024 * 1024
 buf := make([]byte, capacity)
 s.Buffer(buf, capacity)
 linesToArray(s, &out.Cmds)
 return out, nil
}

// parse -t inputs
func parseInput(target string, data *bytes.Buffer) (*app.BuildInput, error) {
 out := &app.BuildInput{Target: target, Files: []string{}}
 s := bufio.NewScanner(data)
 linesToArray(s, &out.Files)
 return out, nil
}

// parse -t query
func parseQuery(target string, data *bytes.Buffer) (*app.BuildQuery, error) {
 out := &app.BuildQuery{Target: target, Inputs: []string{}, Outputs: []string{}}
 const (
  unknown = iota
  inputs
  outputs
 )
 state := unknown
 s := bufio.NewScanner(data)
 for s.Scan() {
  line := strings.TrimSpace(s.Text())
  if strings.HasPrefix(line, "input:") {
   state = inputs
  } else if strings.HasPrefix(line, "outputs:") {
   state = outputs
  } else {
   switch state {
   case inputs:
    out.Inputs = append(out.Inputs, line)
   case outputs:
    out.Outputs = append(out.Outputs, line)
   }
  }
 }
 return out, nil
}

// parse -t path
func parsePath(target string, dependency string, data *bytes.Buffer) (*app.BuildPath, error) {
 out := &app.BuildPath{Target: target, Dependency: dependency, Paths: []string{}}
 s := bufio.NewScanner(data)
 linesToArray(s, &out.Paths)
 return out, nil
}

// parse -t paths
func parsePaths(target string, dependency string, data *bytes.Buffer) ([]*app.BuildPath, error) {
 out := []*app.BuildPath{}
 s := bufio.NewScanner(data)
 for s.Scan() {
  path := strings.Fields(s.Text())
  out = append(out, &app.BuildPath{Target: target, Dependency: dependency, Paths: path})
 }
 return out, nil
}

// parse build output
func parseBuild(target string, data *bytes.Buffer, success bool) *app.BuildCmdResult {
 out := &app.BuildCmdResult{Name: target, Output: []string{}}
 s := bufio.NewScanner(data)
 out.Success = success
 linesToArray(s, &out.Output)
 return out
}

// parse deps command
func parseDeps(data *bytes.Buffer) (*app.BuildDeps, error) {
 out := &app.BuildDeps{Targets: make(map[string][]string)}
 s := bufio.NewScanner(data)
 curTarget := ""
 var deps []string
 for s.Scan() {
  line := strings.TrimSpace(s.Text())
  // Check if it's a new target
  tokens := strings.Split(line, ":")
  if len(tokens) > 1 {
   if curTarget != "" {
    out.Targets[curTarget] = deps
   }
   deps = []string{}
   curTarget = tokens[0]
  } else if line != "" {
   deps = append(deps, line)
  }

 }
 if curTarget != "" {
  out.Targets[curTarget] = deps
 }
 return out, nil
}

//
// Command line interface to ninja binary.
//
// This file implements the ninja.Ninja interface by querying
// the build graph via the ninja binary.  The mapping between
// the interface and the binary are as follows:
//    Command()   -t commands
//    Input()     -t inputs
//    Query()     -t query
//    Path()      -t path
//    Paths()     -t paths
//    Deps()      -t deps
//
//

type ninjaCmd struct {
 cmd string
 db  string

 clientMode   bool
 timeout      time.Duration
 buildTimeout time.Duration
}

func (n *ninjaCmd) runTool(ctx context.Context, tool string, targets []string) (out *bytes.Buffer, err error) {

 args := []string{"-f", n.db}

 if n.clientMode {
  args = append(args, []string{
   "-t", "client",
   "-c", tool}...)
 } else {
  args = append(args, []string{"-t", tool}...)
 }
 args = append(args, targets...)
 data := []byte{}
 err, _ = runPipe(ctx, n.timeout, n.cmd, args, func(r io.Reader) {
  data, _ = ioutil.ReadAll(r)
 })
 return bytes.NewBuffer(data), err

}
func (n *ninjaCmd) Command(ctx context.Context, target string) (*bytes.Buffer, error) {
 return n.runTool(ctx, "commands", []string{target})
}
func (n *ninjaCmd) Input(ctx context.Context, target string) (*bytes.Buffer, error) {
 return n.runTool(ctx, "inputs", []string{target})
}
func (n *ninjaCmd) Query(ctx context.Context, target string) (*bytes.Buffer, error) {
 return n.runTool(ctx, "query", []string{target})
}
func (n *ninjaCmd) Path(ctx context.Context, target string, dependency string) (*bytes.Buffer, error) {
 return n.runTool(ctx, "path", []string{target, dependency})
}
func (n *ninjaCmd) Paths(ctx context.Context, target string, dependency string) (*bytes.Buffer, error) {
 return n.runTool(ctx, "paths", []string{target, dependency})
}
func (n *ninjaCmd) Deps(ctx context.Context) (*bytes.Buffer, error) {
 return n.runTool(ctx, "deps", []string{})
}

func (n *ninjaCmd) Build(ctx context.Context, target string) (*bytes.Buffer, error) {

 args := append([]string{
  "-f", n.db,
  target})
 data := []byte{}
 err, _ := runPipe(ctx, n.buildTimeout, n.cmd, args, func(r io.Reader) {
  data, _ = ioutil.ReadAll(r)
 })

 return bytes.NewBuffer(data), err
}

// Command line ninja
type ninjaCli struct {
 n ninjaExec
}

// ninja -t commands
func (cli *ninjaCli) Command(ctx context.Context, target string) (*app.BuildCommand, error) {
 raw, err := cli.n.Command(ctx, target)
 if err != nil {
  return nil, err
 }
 return parseCommand(target, raw)
}

// ninja -t inputs
func (cli *ninjaCli) Input(ctx context.Context, target string) (*app.BuildInput, error) {
 raw, err := cli.n.Input(ctx, target)
 if err != nil {
  return nil, err
 }
 return parseInput(target, raw)
}

// ninja -t query
func (cli *ninjaCli) Query(ctx context.Context, target string) (*app.BuildQuery, error) {
 raw, err := cli.n.Query(ctx, target)
 if err != nil {
  return nil, err
 }
 return parseQuery(target, raw)
}

// ninja -t path
func (cli *ninjaCli) Path(ctx context.Context, target string, dependency string) (*app.BuildPath, error) {
 raw, err := cli.n.Path(ctx, target, dependency)
 if err != nil {
  return nil, err
 }
 return parsePath(target, dependency, raw)
}

// ninja -t paths
func (cli *ninjaCli) Paths(ctx context.Context, target string, dependency string) ([]*app.BuildPath, error) {
 raw, err := cli.n.Paths(ctx, target, dependency)
 if err != nil {
  return nil, err
 }
 return parsePaths(target, dependency, raw)
}

// ninja -t deps
func (cli *ninjaCli) Deps(ctx context.Context) (*app.BuildDeps, error) {
 raw, err := cli.n.Deps(ctx)
 if err != nil {
  return nil, err
 }
 return parseDeps(raw)
}

// Build given target
func (cli *ninjaCli) Build(ctx context.Context, target string) *app.BuildCmdResult {
 raw, err := cli.n.Build(ctx, target)
 return parseBuild(target, raw, err == nil)

}

// Wait for server
func (cli *ninjaCli) WaitForServer(ctx context.Context, maxTries int) error {
 // Wait for server to response to an empty input request
 fmt.Printf("Waiting for server.")
 for i := 0; i < maxTries; i++ {
  _, err := cli.Input(ctx, "")
  if err == nil {
   fmt.Printf("\nConnected\n")
   return nil
  }
  fmt.Printf(".")
  time.Sleep(time.Second)
 }
 fmt.Printf(" failed\n")
 return errors.New("Failed to connect")
}
func NewNinjaCli(cmd string, db string, timeout, buildTimeout time.Duration, client bool) *ninjaCli {
 cli := &ninjaCli{n: &ninjaCmd{cmd: cmd, db: db, timeout: timeout, buildTimeout: buildTimeout, clientMode: client}}
 return cli
}

type ninjaServer struct {
 cmdName string
 db      string
 ctx     *exec.Cmd
}

// Run server
func (srv *ninjaServer) Start(ctx context.Context) error {
 args := []string{"-f", srv.db, "-t", "server"}
 srv.ctx = exec.CommandContext(ctx, srv.cmdName, args[0:]...)
 err := srv.ctx.Start()
 if err != nil {
  return err
 }
 srv.ctx.Wait()
 return nil
}
func (srv *ninjaServer) Kill() {
 if srv.ctx != nil {
  srv.ctx.Process.Kill()
 }
}
func NewNinjaServer(cmd string, db string) *ninjaServer {
 return &ninjaServer{cmdName: cmd, db: db}
}

[Dauer der Verarbeitung: 0.26 Sekunden, vorverarbeitet 2026-06-27]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik