1// Copyright 2018 syzkaller project authors. All rights reserved.
2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4package vcs
5
6import (
7	"fmt"
8	"io"
9	"os"
10	"path/filepath"
11
12	"github.com/google/syzkaller/pkg/osutil"
13)
14
15type fuchsia struct {
16	vm     string
17	dir    string
18	zircon *git
19}
20
21func newFuchsia(vm, dir string) *fuchsia {
22	return &fuchsia{
23		vm:     vm,
24		dir:    dir,
25		zircon: newGit("fuchsia", vm, filepath.Join(dir, "zircon")),
26	}
27}
28
29func (ctx *fuchsia) Poll(repo, branch string) (*Commit, error) {
30	if repo != "https://fuchsia.googlesource.com" || branch != "master" {
31		// fuchsia ecosystem is hard-tailored to the main repo.
32		return nil, fmt.Errorf("fuchsia: can only check out https://fuchsia.googlesource.com/master")
33	}
34	if _, err := runSandboxed(ctx.dir, "./.jiri_root/bin/jiri", "update"); err != nil {
35		if err := ctx.initRepo(); err != nil {
36			return nil, err
37		}
38	}
39	return ctx.zircon.HeadCommit()
40}
41
42func (ctx *fuchsia) initRepo() error {
43	if err := os.RemoveAll(ctx.dir); err != nil {
44		return fmt.Errorf("failed to remove repo dir: %v", err)
45	}
46	tmpDir := ctx.dir + ".tmp"
47	if err := osutil.MkdirAll(tmpDir); err != nil {
48		return fmt.Errorf("failed to create repo dir: %v", err)
49	}
50	defer os.RemoveAll(tmpDir)
51	if err := osutil.SandboxChown(tmpDir); err != nil {
52		return err
53	}
54	cmd := "curl -s 'https://fuchsia.googlesource.com/scripts/+/master/bootstrap?format=TEXT' |" +
55		"base64 --decode | bash -s topaz"
56	if _, err := runSandboxed(tmpDir, "bash", "-c", cmd); err != nil {
57		return err
58	}
59	return os.Rename(filepath.Join(tmpDir, "fuchsia"), ctx.dir)
60}
61
62func (ctx *fuchsia) CheckoutBranch(repo, branch string) (*Commit, error) {
63	return nil, fmt.Errorf("not implemented for fuchsia")
64}
65
66func (ctx *fuchsia) CheckoutCommit(repo, commit string) (*Commit, error) {
67	return nil, fmt.Errorf("not implemented for fuchsia")
68}
69
70func (ctx *fuchsia) SwitchCommit(commit string) (*Commit, error) {
71	return nil, fmt.Errorf("not implemented for fuchsia")
72}
73
74func (ctx *fuchsia) HeadCommit() (*Commit, error) {
75	return nil, fmt.Errorf("not implemented for fuchsia")
76}
77
78func (ctx *fuchsia) ListRecentCommits(baseCommit string) ([]string, error) {
79	return ctx.zircon.ListRecentCommits(baseCommit)
80}
81
82func (ctx *fuchsia) ExtractFixTagsFromCommits(baseCommit, email string) ([]FixCommit, error) {
83	return ctx.zircon.ExtractFixTagsFromCommits(baseCommit, email)
84}
85
86func (ctx *fuchsia) Bisect(bad, good string, trace io.Writer, pred func() (BisectResult, error)) (*Commit, error) {
87	return nil, fmt.Errorf("not implemented for fuchsia")
88}
89
90func (ctx *fuchsia) PreviousReleaseTags(commit string) ([]string, error) {
91	return nil, fmt.Errorf("not implemented for fuchsia")
92}
93