@@ -10,6 +10,7 @@ import (
1010 "os"
1111 "os/exec"
1212 "strings"
13+ "text/template"
1314 "time"
1415
1516 "github.com/hashicorp/go-multierror"
@@ -57,6 +58,8 @@ func runSteps(ctx context.Context, wc *WorkspaceCreator, repo *graphql.Repositor
5758 return nil , errors .Wrap (err , "git commit failed" )
5859 }
5960
61+ results := make ([]StepResult , len (steps ))
62+
6063 for i , step := range steps {
6164 logger .Logf ("[Step %d] docker run %s %q" , i + 1 , step .Container , step .Run )
6265
@@ -89,8 +92,18 @@ func runSteps(ctx context.Context, wc *WorkspaceCreator, repo *graphql.Repositor
8992 }
9093 hostTemp := fp .Name ()
9194 defer os .Remove (hostTemp )
92- if _ , err := fp .WriteString (step .Run ); err != nil {
93- return nil , errors .Wrapf (err , "writing to temporary file %q" , hostTemp )
95+
96+ stepContext := StepContext {Repository : repo }
97+ if i > 0 {
98+ stepContext .PreviousStep = results [i - 1 ]
99+ }
100+ tmpl , err := parseStepRun (stepContext , step .Run )
101+ if err != nil {
102+ return nil , errors .Wrap (err , "parsing step run" )
103+ }
104+
105+ if err := tmpl .Execute (fp , stepContext ); err != nil {
106+ return nil , errors .Wrap (err , "executing template" )
94107 }
95108 fp .Close ()
96109
@@ -137,10 +150,22 @@ func runSteps(ctx context.Context, wc *WorkspaceCreator, repo *graphql.Repositor
137150 }
138151
139152 logger .Logf ("[Step %d] complete in %s" , i + 1 , elapsed )
140- }
141153
142- if _ , err := runGitCmd ("add" , "--all" ); err != nil {
143- return nil , errors .Wrap (err , "git add failed" )
154+ if _ , err := runGitCmd ("add" , "--all" ); err != nil {
155+ return nil , errors .Wrap (err , "git add failed" )
156+ }
157+
158+ statusOut , err := runGitCmd ("status" , "--porcelain" )
159+ if err != nil {
160+ return nil , errors .Wrap (err , "git status failed" )
161+ }
162+
163+ changes , err := parseGitStatus (statusOut )
164+ if err != nil {
165+ return nil , errors .Wrap (err , "parsing git status output" )
166+ }
167+
168+ results [i ] = StepResult {Changes : changes }
144169 }
145170
146171 // As of Sourcegraph 3.14 we only support unified diff format.
@@ -157,6 +182,67 @@ func runSteps(ctx context.Context, wc *WorkspaceCreator, repo *graphql.Repositor
157182 return diffOut , err
158183}
159184
185+ func parseStepRun (stepCtx StepContext , run string ) (* template.Template , error ) {
186+ t := template .New ("step-run" ).Delims ("${{" , "}}" )
187+
188+ funcMap := template.FuncMap {
189+ "repository_name" : func () string { return stepCtx .Repository .Name },
190+ }
191+
192+ funcMap ["modified_files" ] = stepCtx .PreviousStep .ModifiedFiles
193+
194+ t .Funcs (funcMap )
195+
196+ return t .Parse (run )
197+ }
198+
199+ type StepContext struct {
200+ PreviousStep StepResult
201+ Repository * graphql.Repository
202+ }
203+
204+ type StepChanges struct {
205+ Modified []string
206+ Added []string
207+ Deleted []string
208+ }
209+
210+ type StepResult struct {
211+ Changes StepChanges
212+ }
213+
214+ func (r StepResult ) ModifiedFiles () string { return strings .Join (r .Changes .Modified , " " ) }
215+ func (r StepResult ) AddedFiles () string { return strings .Join (r .Changes .Added , " " ) }
216+ func (r StepResult ) DeletedFiles () string { return strings .Join (r .Changes .Deleted , " " ) }
217+
218+ func parseGitStatus (out []byte ) (StepChanges , error ) {
219+ result := StepChanges {}
220+
221+ stripped := strings .TrimSpace (string (out ))
222+ if len (stripped ) == 0 {
223+ return result , nil
224+ }
225+
226+ for _ , line := range strings .Split (stripped , "\n " ) {
227+ if len (line ) < 4 {
228+ return result , fmt .Errorf ("git status line has unrecognized format: %q" , line )
229+ }
230+
231+ file := line [3 :len (line )]
232+
233+ switch line [0 ] {
234+ case 'M' :
235+ result .Modified = append (result .Modified , file )
236+ case 'A' :
237+ result .Added = append (result .Added , file )
238+ case 'D' :
239+ result .Deleted = append (result .Deleted , file )
240+ }
241+ }
242+
243+ return result , nil
244+ }
245+
160246func probeImageForShell (ctx context.Context , image string ) (shell , tempfile string , err error ) {
161247 // We need to know two things to be able to run a shell script:
162248 //
0 commit comments