tighten / jigsaw

Simple static sites with Laravel’s Blade.
https://jigsaw.tighten.com
MIT License
2.14k stars 182 forks source link

Build error on .git file in collection folder #488

Closed majorminors closed 4 years ago

majorminors commented 4 years ago

expected behaviour

If .git is present in a collection folder, the build process ignores it.

actual behaviour

If .git is present in a collection folder, the build process does not finish.

detail and notes

I've abstracted my articles to a separate git repo, and pulled them into the jigsaw project as a git submodule. I just noticed that the local build seems to error and I am assuming this is because it doesn't like the .git in the source/_articles directory. See the printout from npm run watch:

 DONE  Compiled successfully in 14269ms                                                                                                                                               21:48:00

       Asset      Size    Chunks             Chunk Names
 /js/main.js  1.31 MiB  /js/main  [emitted]  /js/main
css/main.css  1.45 MiB  /js/main  [emitted]  /js/main

In CollectionDataLoader.php line 104:

  No matching collection item handler for file: .git.  

build [--pretty PRETTY] [-c|--cache [CACHE]] [--] [<env>]

[Browsersync] Access URLs:
 -------------------------------------
       Local: http://localhost:3000
    External: http://192.168.0.23:3000
 -------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 -------------------------------------
[Browsersync] Serving files from: build_local/

Assuming this isn't something I've broken, let me know if there's anything I can do to help troubleshoot.

Warm regards,

Dorian

bakerkretzmar commented 4 years ago

Interesting, I don't know if we've ever come across this use case before. It should be a straightforward fix, we're already filtering out files that start with _ so just checking for . too will probably do it. I'll take a closer look this week.

majorminors commented 4 years ago

Oh fabulous. I looked myself to see if I could fix it, but I'm not super familiar with PHP, so I couldn't make much out of the CollectionDataLoader.php file. Apologies.

bakerkretzmar commented 4 years ago

Actually, can you try filtering out .git directly? Something like this:

'filter' => function ($item) {
    return $item->filename != '.git';
}
majorminors commented 4 years ago

Same error.

Although, just noticing how I'm dealing with the filename parameter for path: 'path' => '{collection}/{filename}', Do I need to wrap it?

bakerkretzmar commented 4 years ago

I'm trying to reproduce this locally and when there's a .git directory everything works fine, but if I make a file called .git I get your error. Can you make sure the specific path causing that error is in fact a valid Git directory?

If it is can you post your whole config for that collection so I can keep troubleshooting?

Thanks.

majorminors commented 4 years ago

It's not a directory. I believe newer versions of git collate submodule git directories at the root under /.git/modules. The .git file in the submodule directory just contains a reference to that location e.g.:

#/source/_articles/.git
gitdir: ../../.git/modules/source/_articles

Here's my config:

<?php

return [
    'baseUrl' => '',
    'production' => false,
    'siteName' => 'The Armchair Collective',
    'siteDescription' => 'Turning scholarship into wisdom we can use',
    'siteAuthor' => 'Dorian Minors',

    // collections
    'collections' => [
        'articles' => [ // this is a submodule
            'author' => 'Dorian Minors', // Default author, if not provided in an article
            'sort' => '-date',
            'path' => '{collection}/{filename}',
            'description' => 'excerpt',
        ],
        'missives' => [ // this is also a submodule
            'sort' => '-date',
            'path' => '{collection}/{filename}',
        ],
        //'authors' => [
        //    'path' => '{collection}/{filename}', // author article collation on author template page
        //],
        'series' => [
            'path' => '{collection}/{filename}',
            'articles' => function ($page, $allArticles) {
                return $allArticles->filter(function ($article) use ($page) {
                    return $article->series ? in_array($page->getFilename(), $article->series, true) : false;
                });
            },
        ],
        'themes' => [
            'path' => '{collection}/{filename}',
            'articles' => function ($page, $allArticles) {
                return $allArticles->filter(function ($article) use ($page) {
                    return $article->themes ? in_array($page->getFilename(), $article->themes, true) : false;
                });
            },
        ],
        'projects' => [
            'path' => '{collection}/{filename}',
            'articles' => function ($page, $allArticles) {
                return $allArticles->filter(function ($article) use ($page) {
                    return $article->projects ? in_array($page->getFilename(), $article->projects, true) : false;
                });
            },
        ],
    ],

    // helpers
    'getDate' => function ($page) {
        return Datetime::createFromFormat('U', $page->date);
    },
    'getExcerpt' => function ($page, $length = 255) {
        if ($page->excerpt) {
            return $page->excerpt;
        }

        $content = preg_split('/<!-- more -->/m', $page->getContent(), 2);
        $cleaned = trim(
            strip_tags(
                preg_replace(['/<pre>[\w\W]*?<\/pre>/', '/<h\d>[\w\W]*?<\/h\d>/'], '', $content[0]),
                '<code>'
            )
        );

        if (count($content) > 1) {
            return $content[0];
        }

        $truncated = substr($cleaned, 0, $length);

        if (substr_count($truncated, '<code>') > substr_count($truncated, '</code>')) {
            $truncated .= '</code>';
        }

        return strlen($cleaned) > $length
            ? preg_replace('/\s+?(\S+)?$/', '', $truncated) . '...'
            : $cleaned;
    },
    'isActive' => function ($page, $path) {
        return ends_with(trimPath($page->getPath()), trimPath($path));
    },
];
bakerkretzmar commented 4 years ago

Thanks a lot! I didn't realize submodules worked that way and I assumed it was supposed to be a directory. The .git file is definitely the issue.

I'll look at adding a check to ignore files starting with . (or maybe just named .git), I just want to make sure there's no way it'll break existing sites. @damiani thoughts?