Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Template Support #49

Merged
merged 19 commits into from
Jun 22, 2017
Merged

[WIP] Template Support #49

merged 19 commits into from
Jun 22, 2017

Conversation

KevinGimbel
Copy link
Collaborator

This pull requests adds a template functionality to fakedata. The specs and some discussion can be seen in #45.

The new template functionality supports CLI pipes (demo asciinema here) and reading in a template file (demo asciinema here).

As of now this pull request is marked as Work in Progress (WIP) because work is not yet done.

This commit adds the abillity to use cli pipes to pipe templates into
`fakedata`. It also adds all generators as named functions to the
template funcMap.

// ParseTemplate takes a path to a template file as argument. It parses the template file and executes it on
// os.Stdout.
func ParseTemplate(path string, limit int) (err error) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@lucapette do you have an idea how we could test this function? It needs a file on disk. Should we provide a file and if so, where would we place it? Together with the golden files for the integration tests?

@KevinGimbel
Copy link
Collaborator Author

@lucapette could you do a review and answer my question regarding testing with template files? Beside the test I'm happy with the current implementation. I think it works quite well and can be merged into master.

@lucapette
Copy link
Owner

@KevinGimbel I have very limited access to the internet for a few days more. I'm sorry this is waiting for me. I'll do my best to review it as soon as I can!

@KevinGimbel
Copy link
Collaborator Author

@lucapette good to know! I'll start writing the docs if I get the time to do so and maybe change a few bits in the implementation here and there.

@KevinGimbel
Copy link
Collaborator Author

I switched from using html/template to text/template. The html/template package has build-in escaping etc. for working with HTML files, but that is actually a disadvantage for us.

When you have < in a custom template it gets escaped and can produce issues, e.g.:

echo "#{{ Int 1 100}} {{ Name }} <{{ Email }}>" | fakedata

will produce the following output:

#45, Gaylord Phillips &lt;[email protected]>

You can see that < has turned to &lt; because it was escaped.


As far as I can see there is not much difference between html/template and text/template beside the added security/escaping when working wit real HTML templates. In my opinion it's safer to use text/template for our use case.

@lucapette
Copy link
Owner

@KevinGimbel something is wrong with commenting (as I did answer the question about testing with templates).

At first sight, there's only the minor things I've commented (probably it's a good idea to merge master here as there's a conflict).

@lucapette
Copy link
Owner

@KevinGimbel OK I've just realised there's something else I didnt' notice. The parse methods are printing too (which makes the naming somehow a bit wrong), the problem with that is that now we have the same loop in multiple places. I don't really mind the duplication (as it's really little code) but I think the code would benefit from reorganizing things in a way that the parse methods and the GenerateRow return "something to loop *limitFlag times on and print to stdout". If that's not clear (I'm short on time/connection sadly...), we can postpone that and I can take care of it after merge. I'm almost "thinking out loud" right now :)

@KevinGimbel
Copy link
Collaborator Author

@lucapette I think I understand what you mean with the double loop/print and how to better handle it - I'll give this some thought.

As for the merge with master: Yes! I agree it's about time to update this branch with the latest changes from master. I'll do this as soon as I find the time.

@KevinGimbel
Copy link
Collaborator Author

I merged master into this feature branch and resolved the conflicts in main.go.

Next I will re-think the function naming / implementation to make it more readable since ParseTemplate also executes the template.

@KevinGimbel
Copy link
Collaborator Author

Of course I forgot to adjust the golden file(s) for integration tests. 🙄

Test should now succeed.

@KevinGimbel
Copy link
Collaborator Author

The template feature is now documented inside the README.md file. Could you proof read what I wrote? Anything missing? @lucapette @jorinvo

@KevinGimbel
Copy link
Collaborator Author

I re-wrote the ParseTemplate and ParseTemplateFromPipe to only parse the tempalte and return (template *template.Template, error). The previously private method executeTemplate is now exported and takes a (parsed) template as well as a limit and then loops and writes to os.Stdout. (See 1a00f08)

@lucapette
Copy link
Owner

@KevinGimbel the README additions look good to me at first sight! I think it's a great starting point for the rewriting of the README I plan to do as soon as all the work in progress we have right now lands into master.

The build is still red (errcheck is always checking on us! I like that :)). Apart from the red build, there are just a couple of minor things that I pointed out in comments I'd like to address before we merge (I can take care of it of course if you don't want to/don't have time).

This is going to be a great feature! 😍

@KevinGimbel
Copy link
Collaborator Author

Apart from the red build, there are just a couple of minor things that I pointed out in comments

In your previous comments or did you add new comments? When I look at the commits I don't see any new comments.

main.go Outdated
@@ -49,13 +51,20 @@ func generatorsHelp() string {
return buffer.String()
}

func isPipe() bool {
stat, _ := os.Stdin.Stat()
Copy link
Owner

Choose a reason for hiding this comment

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

why wouldn't we check the error here? (Honest question, I don't know the answer)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I didn't check during testing if the method works and then forgot to handle it. I'll add error checking and exit if there is an error with reading pipes (makes sense).

main.go Outdated
func main() {
var (
generatorsFlag = flag.BoolP("generators", "g", false, "lists available generators")
limitFlag = flag.IntP("limit", "l", 10, "limits rows up to n")
formatFlag = flag.StringP("format", "f", "", "generators rows in f format. Available formats: csv|tab|sql")
versionFlag = flag.BoolP("version", "v", false, "shows version information")
tableFlag = flag.StringP("table", "t", "TABLE", "table name of the sql format")
templateFlag = flag.StringP("template", "", "", "Use template as input")
Copy link
Owner

Choose a reason for hiding this comment

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

I think I'd add -T as a shortcut

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do! I tried -t but that's the one for --table. -T should work.

main.go Outdated
tmp = t
}
// Execute a template if there is one
if tmp != nil {
Copy link
Owner

Choose a reason for hiding this comment

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

maybe let's call tmp tmpl? tmp always reminds me of temporary and I think (my guess though) it's a common association

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree that tmp sounds more like temporary. However, tmpl throws a misspell warning with the Go tools (and with my IDE). Maybe we need to go with t? I'm currently not sure if misspells break ci or not.

if i%2 != 0 {
return true
}
return false
Copy link
Owner

Choose a reason for hiding this comment

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

return i%2 !=0 should do it right? (I didn't check though)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yah that should work. No idea why I went with if here. 😂

@lucapette
Copy link
Owner

@KevinGimbel I think I still don't really know how to use the review feature here. I have to study it a bit. So what I did is adding again all the comments I left (plus some other minor things). It's all small things but I think worth tackling.

I remember we discussed adding integration tests here (the feature calls for that kind of testing in my view) but I'm not sure what's the status of that. Do you still want to take care of that? If not we can still merge this and then I take care of it in a separate pull request (I'm fine with both options so no strings attached).

@KevinGimbel
Copy link
Collaborator Author

@lucapette

I think I still don't really know how to use the review feature here. I have to study it a bit. So what I did is adding again all the comments I left (plus some other minor things). It's all small things but I think worth tackling.

It's worth the time! GitHub's Review tool is pretty good in my opinion. Now I see all your comments and I've answered them.

I remember we discussed adding integration tests here (the feature calls for that kind of testing in my view) but I'm not sure what's the status of that. Do you still want to take care of that?

I agree it screams for integration tests but I have no idea how I would add them and how I would test generation with templates, etc.

If not we can still merge this and then I take care of it in a separate pull request (I'm fine with both options so no strings attached).

However you want to handle it. I need to read up on integration tests before I can implement them because I've never done it on my own - I assume I'd add tests to the cli tests and some golden files, but I have seriously no idea how I cans/should tests the templates.

@KevinGimbel
Copy link
Collaborator Author

@lucapette I fixed some things in 2992b97

  • use -T as template shortcode
  • renamed tmp variable to tmpl
  • remove if/else from Odd and Even funcs
  • handle error in isPipe

Additionally:

  • Handle file read error in File template func
  • Add test for non-existing file

From my point of view only the Integration tests needs to be done, otherwise the template feature is ready. 🎉

@lucapette
Copy link
Owner

@KevinGimbel thank you for all the changes! It looks great now!

I suggest we don't merge it before we're able to add integration tests. I already started working on it so I will push them directly to this branch and ping you when I'm done.

Can't wait to land this feature!

@KevinGimbel
Copy link
Collaborator Author

@lucapette Exciting! I can't wait either, it's been a lot of fun working on this. :)

@lucapette lucapette removed the wip label Jun 22, 2017
@lucapette lucapette added this to the v1.0.0 milestone Jun 22, 2017
@lucapette
Copy link
Owner

@KevinGimbel I finally found some time to work on the feature. I tried to simplify the API as much as I could (therefore did some code removing) and introduced the integration tests we talked about. I'm satisfied with the coverage and the current status of the feature so I'm going to merge it as it is now 🎉

It's going to be hard to make this work with #48 but I can't wait to give that a try!

@lucapette lucapette merged commit 8c4a8f3 into master Jun 22, 2017
@lucapette lucapette deleted the feat/45/templateGenerator branch April 6, 2022 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants