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

Add readFile template func #2008

Closed
wants to merge 1 commit into from
Closed

Add readFile template func #2008

wants to merge 1 commit into from

Conversation

bep
Copy link
Member

@bep bep commented Mar 21, 2016

This is Work in progress, but works fine. Would love input on the name, but I have gone for simplicity, so it is all or nothing (no read line 10-20 etc.).

"readFile": func(i interface{}) (string, error) {
// TODO(bep): Stupid type assertion, see https://github.com/spf13/afero/issues/76
return readFile(afero.NewBasePathFs(hugofs.SourceFs, viper.GetString("WorkingDir")).(*afero.BasePathFs), cast.ToString(i))
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't this happen in readFile? Also, if an inline func can't fit on a single line, I'd prefer to move the complexity to a named func.

Copy link
Member Author

Choose a reason for hiding this comment

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

As I said, this is work in progress. This construction is to make it testable (just switch the FS) -- but I wasn't entirely happy about it, so I'm still thinking.

@bep bep force-pushed the readFile branch 3 times, most recently from 1d157c2 to 97677b5 Compare March 22, 2016 16:11
@bep bep changed the title WIP: Add readFile template func Add readFile template func Mar 22, 2016
@bep
Copy link
Member Author

bep commented Mar 22, 2016

Needed by #2010

@bep
Copy link
Member Author

bep commented Mar 22, 2016

@moorereason I have fixed re. your comment ... but the fix introduced some other changes :-)

@bep bep force-pushed the readFile branch 2 times, most recently from cfb862c to 7cde8e6 Compare March 24, 2016 21:37
@bep
Copy link
Member Author

bep commented Mar 24, 2016

@spf13 do you have any objections/input on this one?

@moorereason
Copy link
Contributor

@bep,
Can you split the hugofs changes into a separate PR? And I would like to see an explanation in your commit message as to why you refactored hugofs. It's not completely obvious to me what problem is solved by the refactor.

@bep
Copy link
Member Author

bep commented Mar 25, 2016

Can you split the hugofs changes into a separate PR?

This PR depends on that to compile, it IS the core of this PR -- and reimplementing the logic that already exists in Afero isn't a path I'm going. I can try to split the commits it it's not too much work.

The Afero filesystems are brilliant. Hugo's way of adding a dozen of global variables for the different filesystems was a mistake. In readFile (and also in some other places in Hugo today) we need a way to restrict the access inside the working dir. We could use ioutil.ReadFile and implement the path checking, checking the base path and the dots ("..") etc. But it is obviously better to use an Afero BasePathFs combined with a ReadOnlyFs. We could create a use-once-filesystem and handle the initialization ourselves, but since this is also useful to others and the initialization depends on some other global state (which would mean to create a new file system on every invocation), we might as well do it properly and encapsulate the predefined set of filesystems. This change also leads the way, if needed, to encapsulate the file systems in a struct, making it possible to have several file system sets in action at once (parallel multilanguage site building? With Moore's law and all...)

This also includes a refactor of the hugofs package and its usage.

The motivation for that is:

The Afero filesystems are brilliant. Hugo's way of adding a dozen of global variables for the different filesystems was a mistake. In readFile (and also in some other places in Hugo today) we need a way to restrict the access inside the working dir. We could use ioutil.ReadFile and implement the path checking, checking the base path and the dots ("..") etc. But it is obviously better to use an Afero BasePathFs combined witha ReadOnlyFs. We could create a use-once-filesystem and handle the initialization ourselves, but since this is also useful to others and the initialization depends on some other global state (which would mean to create a new file system on every invocation), we might as well do it properly and encapsulate the predefined set of filesystems. This change also leads the way, if needed, to encapsulate the file systems in a struct, making it possible to have several file system sets in action at once (parallel multilanguage site building? With Moore's law and all...)

Fixes gohugoio#1551
@spf13
Copy link
Contributor

spf13 commented Mar 29, 2016

@bep This looks great. The addition of the helper hugofs.Init* functions is really nice and clean.

I agree with @moorereason that this is really two commits, 1. the hugofs cleanup, 2. the readFile function. If it's not a lot of trouble it would be cleaner to have two commits (still one PR).

I'm not sure I totally understand why your preference for Function & SetFunction vs Variable. I don't have a problem with either approach, but find them very similar and only semantically different. Can you help me to understand better why you felt the Function approach was better here?

Feel free to split and merge or just merge if it's tough to split.

I also like readFile and think it's a great idea and really powerful when combined with things like markdownify, etc. I think the name works well also.

@bep
Copy link
Member Author

bep commented Mar 30, 2016

I'm not sure I totally understand why your preference for Function & SetFunction vs Variable. I don't have a problem with either approach, but find them very similar and only semantically different.

Variables access cannot have any side effects. And the names are better. You could argue that SetSomething should just set the something and nothing else, and I agree, but this is, in my eyes, a natural first step in getting rid of the filesystem globals and replace all the functions with NewFilesystems{source, destination) or similar and access them by methods.

We've had a few subtle but serious bugs where we had a mix of different file systems in play. The tests have been setting the source file system global, but didn't care too much about the destination ... In the site build chain, the file systems have been initialized at some point, then much later, depending on a flag or some other magic, the source system has been changed to something else ... making it hard to look at some file operation and decide: Will that file be read from disk?

I'm all for the pragmatic approach of using global variables if it makes the life much easier or if it is a resource that is static by nature (one should think file systems fall into the latter category, but Afero changed that) -- in Hugo we've taken it a little bit too far: MainSite, Viper, SourceFs, DestinationFS, Template ... Other?

Not too bad, but it makes the code hard too follow and the tests a little bit shaky and maybe not perfectly realistic at all times.

@spf13
Copy link
Contributor

spf13 commented Mar 30, 2016

@bep
Thanks. That explanation helps a lot and makes a lot of sense.

@bep
Copy link
Member Author

bep commented Mar 30, 2016

@spf13 keywords here are also maybe encapsulation and immutability. With the change in this PR the access to the file systems are encapsulated, but they are still mutable, however in a more controlled fashion.

@bep
Copy link
Member Author

bep commented Mar 31, 2016

Merged in 4f66f79

@bep bep closed this Mar 31, 2016
@bep bep deleted the readFile branch April 18, 2017 09:19
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants