diff --git a/launch.go b/launch.go index 4a55fb42..8ce072d6 100644 --- a/launch.go +++ b/launch.go @@ -1,12 +1,15 @@ package main import ( + "encoding/json" "fmt" "io" + "io/ioutil" "log" "os" "path" "regexp" + "strings" "github.com/screwdriver-cd/launcher/executor" "github.com/screwdriver-cd/launcher/git" @@ -29,6 +32,7 @@ var stat = os.Stat var gitSetup = git.Setup var open = os.Open var executorRun = executor.Run +var writeFile = ioutil.WriteFile func (s scmPath) String() string { return fmt.Sprintf("git@%s:%s/%s#%s", s.Host, s.Org, s.Repo, s.Branch) @@ -96,6 +100,21 @@ func createWorkspace(rootDir string, srcPaths ...string) (Workspace, error) { return w, nil } +func writeArtifact(aDir string, fName string, artifact interface{}) error { + data, err := json.MarshalIndent(artifact, "", strings.Repeat(" ", 4)) + if err != nil { + return fmt.Errorf("marshaling artifact: %v ", err) + } + + pathToCreate := path.Join(aDir, fName) + err = writeFile(pathToCreate, data, 0644) + if err != nil { + return fmt.Errorf("creating file %q : %v", pathToCreate, err) + } + + return nil +} + // prNumber checks to see if the job name is a pull request and returns its number func prNumber(jobName string) string { r := regexp.MustCompile("^PR-([0-9]+)$") @@ -174,6 +193,17 @@ func launch(api screwdriver.API, buildID string, rootDir string) error { // TODO: Select the specific child build by looking at the decimal value of the build number currentJob := pipelineDef.Jobs[j.Name][0] + + err = writeArtifact(w.Artifacts, "steps.json", currentJob.Commands) + if err != nil { + return fmt.Errorf("creating steps.json artifact: %v", err) + } + + err = writeArtifact(w.Artifacts, "environment.json", currentJob.Environment) + if err != nil { + return fmt.Errorf("creating environment.json artifact: %v", err) + } + err = executorRun(currentJob.Commands) if err != nil { return err diff --git a/launch_test.go b/launch_test.go index 003804b3..34c157f6 100644 --- a/launch_test.go +++ b/launch_test.go @@ -1,9 +1,12 @@ package main import ( + "encoding/json" "fmt" "io" + "io/ioutil" "os" + "path" "reflect" "strings" "testing" @@ -354,6 +357,8 @@ func TestPR(t *testing.T) { } func TestGitSetupError(t *testing.T) { + oldGitSetup := gitSetup + defer func() { gitSetup = oldGitSetup }() testBuildID := "BUILDID" testJobID := "JOBID" testSCMURL := "git@github.com:screwdriver-cd/launcher.git#master" @@ -459,6 +464,9 @@ func TestPipelineDefFromYaml(t *testing.T) { }, } + defer func() { writeFile = ioutil.WriteFile }() + writeFile = func(d string, b []byte, p os.FileMode) error { return nil } + oldOpen := open defer func() { open = oldOpen }() open = func(f string) (*os.File, error) { @@ -486,5 +494,96 @@ func TestPipelineDefFromYaml(t *testing.T) { } return nil } - launch(screwdriver.API(api), testBuildID, testRoot) + err := launch(screwdriver.API(api), testBuildID, testRoot) + + if err != nil { + t.Errorf("Launch returned error: %v", err) + } +} + +func TestWriteCommandArtifact(t *testing.T) { + sdCommand := []screwdriver.CommandDef{ + screwdriver.CommandDef{ + Name: "install", + Cmd: "npm install", + }, + } + var sdCommandUnmarshal []screwdriver.CommandDef + fName := "steps.json" + + tmp, err := ioutil.TempDir("", "ArtifactDir") + if err != nil { + t.Fatalf("Couldn't create temp dir: %v", err) + } + defer os.RemoveAll(tmp) + + err = writeArtifact(tmp, fName, sdCommand) + if err != nil { + t.Errorf("Expected error to be nil: %v", err) + } + + filePath := path.Join(tmp, fName) + + if _, err = os.Stat(filePath); err != nil { + t.Fatalf("file not found: %s", err) + } + + fileContents, err := ioutil.ReadFile(filePath) + + if err != nil { + t.Fatalf("reading file error: %v", err) + } + + err = json.Unmarshal(fileContents, &sdCommandUnmarshal) + + if err != nil { + t.Fatalf("unmarshalling file contents: %v", err) + } + + if !reflect.DeepEqual(sdCommand, sdCommandUnmarshal) { + t.Fatalf("Did not write file correctly. Wanted %v. Got %v", sdCommand, sdCommandUnmarshal) + } +} + +func TestWriteEnvironmentArtifact(t *testing.T) { + sdEnv := map[string]string{ + "NUMBER": "3", + "NUMBER1": "4", + "BOOL": "false", + } + var sdEnvUnmarshal map[string]string + fName := "environment.json" + + tmp, err := ioutil.TempDir("", "ArtifactDir") + if err != nil { + t.Fatalf("Couldn't create temp dir: %v", err) + } + defer os.RemoveAll(tmp) + + err = writeArtifact(tmp, fName, sdEnv) + if err != nil { + t.Fatalf("Expected error to be nil: %v", err) + } + + filePath := path.Join(tmp, fName) + + if _, err = os.Stat(filePath); err != nil { + t.Fatalf("file not found: %s", err) + } + + fileContents, err := ioutil.ReadFile(filePath) + + if err != nil { + t.Fatalf("reading file error: %v", err) + } + + err = json.Unmarshal(fileContents, &sdEnvUnmarshal) + + if err != nil { + t.Fatalf("unmarshalling file contents: %v", err) + } + + if !reflect.DeepEqual(sdEnv, sdEnvUnmarshal) { + t.Fatalf("Did not write file correctly. Wanted %v. Got %v", sdEnv, sdEnvUnmarshal) + } }