URI: 
       Fix concat with fingerprint regression - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 3be2c25351b421a26ee1ff2a38cbab00280c0583
   DIR parent 5e660947757023434dd7a1ec8b8239c0577fd501
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Thu,  5 Sep 2019 18:03:00 +0200
       
       Fix concat with fingerprint regression
       
       In Hugo 0.58 we optimized the transformers that only adjusted metadata, e.g. the fingerprint.
       
       This depended on the source readers implementing `io.ReadSeeker`.
       
       The reader produced by `concat` did that, but the implementation was buggy.
       
       This commit fixes that.
       
       Fixes #6309
       
       Diffstat:
         M hugolib/resource_chain_test.go      |      19 ++++++++++++++++++-
         M resources/resource_factories/bundl… |      32 +++++++++++++++++++------------
         A resources/resource_factories/bundl… |      41 +++++++++++++++++++++++++++++++
       
       3 files changed, 79 insertions(+), 13 deletions(-)
       ---
   DIR diff --git a/hugolib/resource_chain_test.go b/hugolib/resource_chain_test.go
       @@ -284,7 +284,7 @@ Edited content.
                }
        }
        
       -func TestResourceChain(t *testing.T) {
       +func TestResourceChains(t *testing.T) {
                t.Parallel()
        
                c := qt.New(t)
       @@ -389,6 +389,23 @@ T3: Content: {{ $combinedJs.Content }}|{{ $combinedJs.RelPermalink }}
        ;
        (function F {})()`)
                        }},
       +
       +                {"concat and fingerprint", func() bool { return true }, func(b *sitesBuilder) {
       +                        b.WithTemplates("home.html", `
       +{{ $a := "A" | resources.FromString "a.txt"}}
       +{{ $b := "B" | resources.FromString "b.txt"}}
       +{{ $c := "C" | resources.FromString "c.txt"}}
       +{{ $combined := slice $a $b $c | resources.Concat "bundle/concat.txt" }}
       +{{ $fingerprinted := $combined | fingerprint }}
       +Fingerprinted: {{ $fingerprinted.RelPermalink }}
       +`)
       +                }, func(b *sitesBuilder) {
       +
       +                        b.AssertFileContent("public/index.html", "Fingerprinted: /bundle/concat.b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78.txt")
       +                        b.AssertFileContent("public/bundle/concat.b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78.txt", "ABC")
       +
       +                }},
       +
                        {"fromstring", func() bool { return true }, func(b *sitesBuilder) {
                                b.WithTemplates("home.html", `
        {{ $r := "Hugo Rocks!" | resources.FromString "rocks/hugo.txt" }}
   DIR diff --git a/resources/resource_factories/bundler/bundler.go b/resources/resource_factories/bundler/bundler.go
       @@ -15,7 +15,6 @@
        package bundler
        
        import (
       -        "bytes"
                "fmt"
                "io"
                "path"
       @@ -43,6 +42,19 @@ type multiReadSeekCloser struct {
                sources []hugio.ReadSeekCloser
        }
        
       +func toReaders(sources []hugio.ReadSeekCloser) []io.Reader {
       +        readers := make([]io.Reader, len(sources))
       +        for i, r := range sources {
       +                readers[i] = r
       +        }
       +        return readers
       +}
       +
       +func newMultiReadSeekCloser(sources ...hugio.ReadSeekCloser) *multiReadSeekCloser {
       +        mr := io.MultiReader(toReaders(sources)...)
       +        return &multiReadSeekCloser{mr, sources}
       +}
       +
        func (r *multiReadSeekCloser) Read(p []byte) (n int, err error) {
                return r.mr.Read(p)
        }
       @@ -54,6 +66,9 @@ func (r *multiReadSeekCloser) Seek(offset int64, whence int) (newOffset int64, e
                                return
                        }
                }
       +
       +        r.mr = io.MultiReader(toReaders(r.sources)...)
       +
                return
        }
        
       @@ -98,31 +113,24 @@ func (c *Client) Concat(targetPath string, r resource.Resources) (resource.Resou
                                        rcsources = append(rcsources, rc)
                                }
        
       -                        var readers []io.Reader
       -
                                // Arbitrary JavaScript files require a barrier between them to be safely concatenated together.
                                // Without this, the last line of one file can affect the first line of the next file and change how both files are interpreted.
                                if resolvedm.MainType == media.JavascriptType.MainType && resolvedm.SubType == media.JavascriptType.SubType {
       -                                readers = make([]io.Reader, 2*len(rcsources)-1)
       +                                readers := make([]hugio.ReadSeekCloser, 2*len(rcsources)-1)
                                        j := 0
                                        for i := 0; i < len(rcsources); i++ {
                                                if i > 0 {
       -                                                readers[j] = bytes.NewBufferString("\n;\n")
       +                                                readers[j] = hugio.NewReadSeekerNoOpCloserFromString("\n;\n")
                                                        j++
                                                }
                                                readers[j] = rcsources[i]
                                                j++
                                        }
       -                        } else {
       -                                readers = make([]io.Reader, len(rcsources))
       -                                for i := 0; i < len(rcsources); i++ {
       -                                        readers[i] = rcsources[i]
       -                                }
       +                                return newMultiReadSeekCloser(readers...), nil
                                }
        
       -                        mr := io.MultiReader(readers...)
       +                        return newMultiReadSeekCloser(rcsources...), nil
        
       -                        return &multiReadSeekCloser{mr: mr, sources: rcsources}, nil
                        }
        
                        composite, err := c.rs.New(
   DIR diff --git a/resources/resource_factories/bundler/bundler_test.go b/resources/resource_factories/bundler/bundler_test.go
       @@ -0,0 +1,41 @@
       +// Copyright 2019 The Hugo Authors. All rights reserved.
       +//
       +// Licensed under the Apache License, Version 2.0 (the "License");
       +// you may not use this file except in compliance with the License.
       +// You may obtain a copy of the License at
       +// http://www.apache.org/licenses/LICENSE-2.0
       +//
       +// Unless required by applicable law or agreed to in writing, software
       +// distributed under the License is distributed on an "AS IS" BASIS,
       +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       +// See the License for the specific language governing permissions and
       +// limitations under the License.
       +
       +package bundler
       +
       +import (
       +        "testing"
       +
       +        "github.com/gohugoio/hugo/helpers"
       +
       +        qt "github.com/frankban/quicktest"
       +        "github.com/gohugoio/hugo/common/hugio"
       +)
       +
       +func TestMultiReadSeekCloser(t *testing.T) {
       +        c := qt.New(t)
       +
       +        rc := newMultiReadSeekCloser(
       +                hugio.NewReadSeekerNoOpCloserFromString("A"),
       +                hugio.NewReadSeekerNoOpCloserFromString("B"),
       +                hugio.NewReadSeekerNoOpCloserFromString("C"),
       +        )
       +
       +        for i := 0; i < 3; i++ {
       +                s1 := helpers.ReaderToString(rc)
       +                c.Assert(s1, qt.Equals, "ABC")
       +                _, err := rc.Seek(0, 0)
       +                c.Assert(err, qt.IsNil)
       +        }
       +
       +}