1

Shake uses various forms of matching, filepath against pattern. Is there one which can be used to exclude a pattern?

Example: I have three directories a, b, c (somewhere in directory x) and each needs html files. There is a rule

(dir <> "//*.html") %> \out -> do -- deal with a and b

which should only deal with the directories a and b and a similar rule to process the files in c.

Is there a way (perhaps using ?>) to separate the two rules for one

(\f -> "x" prefixOf f && not "x/c" prefixOf f) <> "//*.html")
(\f -> "x/x" prefixOf f ) <> "//*.html")

and the other similarly?

The recommended approach to use xx.a.html and xx.b.html is here not possible, because files are processed with other programs which expect the regular html extension.

Alternatively

user855443
  • 2,596
  • 3
  • 25
  • 37

2 Answers2

2

The rule:

pattern %> action

Is equivalent to:

(pattern ?==) ?> action

So you can write:

(\x -> "//*.html" ?== x && not ("c//*.html" ?== x) ?> action

To match rules matching //*.html, but not c//*.html.

More generally, there is no requirement to use the FilePattern ?== operator at all, so arbitrary matching predicates can be used instead.

Neil Mitchell
  • 9,090
  • 1
  • 27
  • 85
  • I have now two rules (\x -> ((bakedD <> "//*.html") ?== x) && (not ((staticD <> "//*.html") ?== x))) ?> \out -> do ... (staticD > "//*.html" ) %> \out -> do ... where `staticD = bakedD > staticDirName` and have overlap with a file `baked <> /SSGdesign/index.html`. what is wrong? (sorry for poor presentation, how to improve?) – user855443 Mar 07 '19 at 22:22
  • There was a `/` in the first rule. Now I have a `Rules may not be recursive` error. Working on it... – user855443 Mar 08 '19 at 09:10
  • is `(bakedD <> "//*.html")` and `(bakedD) > "//*.html")` equivalent? – user855443 Mar 08 '19 at 09:23
  • 1
    I recommend using `**/*.html` and avoiding `//` entirely - partly because it fights horribly with the `>` operator. They aren't equivalent, and the second doesn't remotely do what you expect. A future version of Shake will eliminate `//` entirely. – Neil Mitchell Mar 08 '19 at 09:29
0

With the advice (especially the hint about using **/*.html) I have it working. The path bakedD is a prefix of staticD and the first rule deals only with files in bakedD which are not in staticD, the other only with these:

(\x -> ((bakedD <> "**/*.html") ?== x) 
     && not  ((staticD <> "**/*.html") ?== x)) ?> \out -> do
            let md =   doughD </>  (makeRelative bakedD $ out -<.> "md")
            runErr2action $ bakeOneFileFPs  md  doughD templatesD out

(staticD <> "**/*.html" ) %> \out -> do
        copyFileChanged (replaceDirectory out doughD) out

There is no overlap between the two rules.

I hope this is useful for others with the same type of issue.

user855443
  • 2,596
  • 3
  • 25
  • 37