xref: /aosp_15_r20/external/boringssl/src/util/pregenerate/task.go (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker// Copyright (c) 2024, Google Inc.
2*8fb009dcSAndroid Build Coastguard Worker//
3*8fb009dcSAndroid Build Coastguard Worker// Permission to use, copy, modify, and/or distribute this software for any
4*8fb009dcSAndroid Build Coastguard Worker// purpose with or without fee is hereby granted, provided that the above
5*8fb009dcSAndroid Build Coastguard Worker// copyright notice and this permission notice appear in all copies.
6*8fb009dcSAndroid Build Coastguard Worker//
7*8fb009dcSAndroid Build Coastguard Worker// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8*8fb009dcSAndroid Build Coastguard Worker// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9*8fb009dcSAndroid Build Coastguard Worker// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10*8fb009dcSAndroid Build Coastguard Worker// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11*8fb009dcSAndroid Build Coastguard Worker// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12*8fb009dcSAndroid Build Coastguard Worker// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13*8fb009dcSAndroid Build Coastguard Worker// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14*8fb009dcSAndroid Build Coastguard Worker
15*8fb009dcSAndroid Build Coastguard Workerpackage main
16*8fb009dcSAndroid Build Coastguard Worker
17*8fb009dcSAndroid Build Coastguard Workerimport (
18*8fb009dcSAndroid Build Coastguard Worker	"bytes"
19*8fb009dcSAndroid Build Coastguard Worker	"os"
20*8fb009dcSAndroid Build Coastguard Worker	"os/exec"
21*8fb009dcSAndroid Build Coastguard Worker	"path"
22*8fb009dcSAndroid Build Coastguard Worker	"path/filepath"
23*8fb009dcSAndroid Build Coastguard Worker)
24*8fb009dcSAndroid Build Coastguard Worker
25*8fb009dcSAndroid Build Coastguard Workertype Task interface {
26*8fb009dcSAndroid Build Coastguard Worker	// Destination returns the destination path for this task, using forward
27*8fb009dcSAndroid Build Coastguard Worker	// slashes and relative to the source directory. That is, use the "path"
28*8fb009dcSAndroid Build Coastguard Worker	// package, not "path/filepath".
29*8fb009dcSAndroid Build Coastguard Worker	Destination() string
30*8fb009dcSAndroid Build Coastguard Worker
31*8fb009dcSAndroid Build Coastguard Worker	// Run computes the output for this task. It should be written to the
32*8fb009dcSAndroid Build Coastguard Worker	// destination path.
33*8fb009dcSAndroid Build Coastguard Worker	Run() ([]byte, error)
34*8fb009dcSAndroid Build Coastguard Worker}
35*8fb009dcSAndroid Build Coastguard Worker
36*8fb009dcSAndroid Build Coastguard Workertype SimpleTask struct {
37*8fb009dcSAndroid Build Coastguard Worker	Dst     string
38*8fb009dcSAndroid Build Coastguard Worker	RunFunc func() ([]byte, error)
39*8fb009dcSAndroid Build Coastguard Worker}
40*8fb009dcSAndroid Build Coastguard Worker
41*8fb009dcSAndroid Build Coastguard Workerfunc (t *SimpleTask) Destination() string  { return t.Dst }
42*8fb009dcSAndroid Build Coastguard Workerfunc (t *SimpleTask) Run() ([]byte, error) { return t.RunFunc() }
43*8fb009dcSAndroid Build Coastguard Worker
44*8fb009dcSAndroid Build Coastguard Workerfunc NewSimpleTask(dst string, runFunc func() ([]byte, error)) *SimpleTask {
45*8fb009dcSAndroid Build Coastguard Worker	return &SimpleTask{Dst: dst, RunFunc: runFunc}
46*8fb009dcSAndroid Build Coastguard Worker}
47*8fb009dcSAndroid Build Coastguard Worker
48*8fb009dcSAndroid Build Coastguard Workertype PerlasmTask struct {
49*8fb009dcSAndroid Build Coastguard Worker	Src, Dst string
50*8fb009dcSAndroid Build Coastguard Worker	Args     []string
51*8fb009dcSAndroid Build Coastguard Worker}
52*8fb009dcSAndroid Build Coastguard Worker
53*8fb009dcSAndroid Build Coastguard Workerfunc (t *PerlasmTask) Destination() string { return t.Dst }
54*8fb009dcSAndroid Build Coastguard Workerfunc (t *PerlasmTask) Run() ([]byte, error) {
55*8fb009dcSAndroid Build Coastguard Worker	base := path.Base(t.Dst)
56*8fb009dcSAndroid Build Coastguard Worker	out, err := os.CreateTemp("", "*."+base)
57*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
58*8fb009dcSAndroid Build Coastguard Worker		return nil, err
59*8fb009dcSAndroid Build Coastguard Worker	}
60*8fb009dcSAndroid Build Coastguard Worker	defer os.Remove(out.Name())
61*8fb009dcSAndroid Build Coastguard Worker
62*8fb009dcSAndroid Build Coastguard Worker	args := make([]string, 0, 2+len(t.Args))
63*8fb009dcSAndroid Build Coastguard Worker	args = append(args, filepath.FromSlash(t.Src))
64*8fb009dcSAndroid Build Coastguard Worker	args = append(args, t.Args...)
65*8fb009dcSAndroid Build Coastguard Worker	args = append(args, out.Name())
66*8fb009dcSAndroid Build Coastguard Worker	cmd := exec.Command(*perlPath, args...)
67*8fb009dcSAndroid Build Coastguard Worker	cmd.Stderr = os.Stderr
68*8fb009dcSAndroid Build Coastguard Worker	cmd.Stdout = os.Stdout
69*8fb009dcSAndroid Build Coastguard Worker	if err := cmd.Run(); err != nil {
70*8fb009dcSAndroid Build Coastguard Worker		return nil, err
71*8fb009dcSAndroid Build Coastguard Worker	}
72*8fb009dcSAndroid Build Coastguard Worker
73*8fb009dcSAndroid Build Coastguard Worker	data, err := os.ReadFile(out.Name())
74*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
75*8fb009dcSAndroid Build Coastguard Worker		return nil, err
76*8fb009dcSAndroid Build Coastguard Worker	}
77*8fb009dcSAndroid Build Coastguard Worker
78*8fb009dcSAndroid Build Coastguard Worker	// On Windows, perl emits CRLF line endings. Normalize this so that the tool
79*8fb009dcSAndroid Build Coastguard Worker	// can be run on Windows too.
80*8fb009dcSAndroid Build Coastguard Worker	data = bytes.ReplaceAll(data, []byte("\r\n"), []byte("\n"))
81*8fb009dcSAndroid Build Coastguard Worker	return data, nil
82*8fb009dcSAndroid Build Coastguard Worker}
83