Skip to content

Conversation

stephenprater
Copy link
Contributor

What changes does this PR introduce?

This introduces two special variables {{.CHECKSUM}} and {{.TIMESTAMP}} to status commands, to enable the checking of "up-to-dateness" of remote artifacts.

Any background context you want to provide?

Generally, when you use sources - you also use generates - if the generates artifacts is newer than the sources, then the your task is out of date and needs to be re-run. This works as long as you have direct access to the generated artifacts - but some tasks produce "remote artifacts" that don't live on the same file system as your sources (AMIs, Docker Images, Kubernetes Deploys) - status already supports sh based status checks - so we expanded this to evaluate remote artifacts.

Which ever method you choose to fingerprint your sources will be exposed as a template variable to status shell commands.

Currently, the expectation is that you would use sources and generates together and then status separately. The expectation going forward would be that sources could be used with either status or generates to evaluate the status of the task. status and generates are still mutually exclusive.

Where should the reviewer start?

The test is a little artificial in that it echos the value of the checksum rather than actually doing something with it - but it demonstrates how the feature could be used.

Has this been manually tested? How?

This is part of our private fork.

Copy link
Member

@andreynering andreynering left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @stephenprater,

Pretty good work, thanks for opening this pull request. 🙂

I did a couple of comments. The most challenging one is the suggestion to change .TIMESTAMP from a string to a plain time.Time struct, which may require changes on how Task handles variables (which are just strings currently) to accept interface{}s.

Don't hesitate to ask if you need help or guidance help.

docs/usage.md Outdated
- test -f directory/file2.txt
```

Normally, you would use either `status` or `sources` in combination with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the "Prevent unnecessary work" section is becaming big, perhaps we could separate it into subsections (using ### for subtitles) for sources/generates vs. status vs. preconditions.

What do you think?

return fmt.Sprintf("%x", h.Sum(nil)), nil
}

// Value implements the Chcker Interface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Value implements the Chcker Interface
// Value implements the Checker interface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, missing documentation comments for Kind() functions.

variables.go Outdated

if len(origTask.Status) > 0 {

e := &Executor{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use the existing Executor instance instead of instantiating another one?

variables.go Outdated
return nil, err
}

vars[strings.ToUpper(checker.Kind())] = taskfile.Var{Static: value}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should this whole if block to the bottom of the function. Otherwise the TIMESTAMP and CHECKSUM variables will be available to the stuff parsed below, but not to those parse above, which would be a bit confusing. 🙂

Alternatively, we could clone the vars map to prevent that.

variables.go Outdated

vars[strings.ToUpper(checker.Kind())] = taskfile.Var{Static: value}

statusTemplater := templater.Templater{Vars: vars}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless the clone vars, we don't need to instantiate another templater since maps are pass-by-reference.

status.go Outdated
}

func (e *Executor) getStatusChecker(t *taskfile.Task) (status.Checker, error) {
func (e *Executor) GetStatusChecker(t *taskfile.Task) (status.Checker, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't necessarily need to make this function exported, since it's only called inside this package anyway.

return "0", nil
}

return fmt.Sprintf("%d", sourcesMaxTime.Unix()), nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... something to discuss here:

We could possibly pass the time.Time struct to the template instead of converting it to string.

In that case, users would have to use {{.TIMESTAMP | unix}} to get the user timestamp, or {{.TIMESTAMP | "2006-01-02"}} to format it to the format they want to use.

This would need to be documented, and the return of Value() would be changed to (interface{}, error).

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am 100% on board with that.

[ "{{.TIMESTAMP}}" -gt "$({{.DATE_CMD}} --date $last_ami_date +"%s")" ] 

Here's part of my actual invocation - where I have to parse a Date string from AWS into a unix timestamp while also templating in a system dependent invocation of date. Yeah - I'd rather do that in go templates for sure.

Copy link
Contributor Author

@stephenprater stephenprater left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All great feedback. I'm definitely down for changing the type signature of Value.

return "0", nil
}

return fmt.Sprintf("%d", sourcesMaxTime.Unix()), nil
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am 100% on board with that.

[ "{{.TIMESTAMP}}" -gt "$({{.DATE_CMD}} --date $last_ami_date +"%s")" ] 

Here's part of my actual invocation - where I have to parse a Date string from AWS into a unix timestamp while also templating in a system dependent invocation of date. Yeah - I'd rather do that in go templates for sure.

@andreynering
Copy link
Member

Hi @stephenprater,

Sorry for asking, but just to make sure we're on the same page... Do you plan to do the necessary fixes or do you prefer me to work on it?

If the latter, can you make sure this checkbox is checked?

Screen Shot 2019-08-11 at 22 38 31

Thanks!

@stephenprater
Copy link
Contributor Author

stephenprater commented Aug 12, 2019 via email

@andreynering
Copy link
Member

@stephenprater Don't hurry, take your time, we all have busy lives. I was just checking in. 😉

Thanks!

@andreynering
Copy link
Member

Can you please move the target branch from master to v3 and merge v3 into this branch? We shouldn't have any conflicts. Thanks!

stephenprater and others added 4 commits August 25, 2019 09:39
Co-Authored-By: Andrey Nering <andrey.nering@gmail.com>
…tatus * upstream/v3: v3.0.0-preview1 Update v3 changelog Only have colored output on v3 Add --color=false flag to disable colored output Update documentation about sprig Update CHANGELOG Migrate from sprig to slim-sprig Fix build after merging master Use colors for some output messages
@stephenprater stephenprater force-pushed the report-timestamp-to-status branch from 3951956 to 9aa9033 Compare August 25, 2019 20:17
@stephenprater
Copy link
Contributor Author

stephenprater commented Aug 25, 2019

@andreynering Sorry for the delay - the company I was doing this work for is doing some restructuring (notably, restructuring me and most of the employees out of a job). I made the changes you requested in terms of code review and took a stab at making the Checker#Value method use the empty interface.

I had some trouble getting this to work without adding an additional "kind" of variable. Since the "static" variables are recursively replaced by their own values, I couldn't figure out how to allow the Replace function to accept both a "template string" and an empty interface as the value. My solution was to add another "Variable Kind" - Live - which is basically a real Go value exposed to the templating system, that never recursively replaces itself.

The strMap cache in the templater needed it's typing relaxed as well, since it's no longer strictly a string -> string map, but could be string -> (pretty much anything).

* master: Update CHANGELOG Small improvements to go-task#228 Fix a typo Fix Checksum.IsUpToDate Remove directory check Update glob.go Separate error handlings for readability Re-run the task if generated files do not exist
@stephenprater stephenprater force-pushed the report-timestamp-to-status branch from 9aa9033 to 6b0935d Compare August 25, 2019 20:47
@andreynering
Copy link
Member

Hi @stephenprater,

I'm really sorry to know that. All the luck on the search for a new job!

Thanks for the updates, I'll review again once possible.

@andreynering andreynering changed the base branch from master to v3 August 25, 2019 21:04
@andreynering andreynering changed the base branch from v3 to master September 2, 2019 00:51
@andreynering andreynering changed the base branch from master to v3 September 2, 2019 00:51
@andreynering andreynering added this to the v3 milestone Sep 2, 2019
@andreynering andreynering added the v3 label Sep 2, 2019
andreynering added a commit that referenced this pull request Sep 14, 2019
andreynering added a commit that referenced this pull request Sep 14, 2019
@andreynering andreynering merged commit 1a33f91 into go-task:v3 Sep 14, 2019
@andreynering
Copy link
Member

Hi @stephenprater,

This is now merged on the v3 branch.

I did a few improvements here and here.

Thanks a lot for the contribution and patience. It's much appreciated! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants