shake-plus
Re-export of Shake using well-typed paths and ReaderT.
https://gitlab.com/shake-plus/shake-plus
Version on this page: | 0.1.10.0 |
LTS Haskell 23.5: | 0.3.4.0@rev:1 |
Stackage Nightly 2024-12-09: | 0.3.4.0@rev:1 |
Latest on Hackage: | 0.3.4.0@rev:1 |
shake-plus-0.1.10.0@sha256:3b7be8579f10134b42de66fc500eae466d5658bbbabacb98b70a142327ce1a69,2296
Module documentation for 0.1.10.0
- Development
- Development.Shake
- Development.Shake.Plus
- Development.Shake.Plus.Cache
- Development.Shake.Plus.Command
- Development.Shake.Plus.Config
- Development.Shake.Plus.Core
- Development.Shake.Plus.Database
- Development.Shake.Plus.Directory
- Development.Shake.Plus.Env
- Development.Shake.Plus.File
- Development.Shake.Plus.FileRules
- Development.Shake.Plus.Loaders
- Development.Shake.Plus.Oracle
- Development.Shake.Plus.Temp
- Development.Shake.Plus
- Development.Shake
Shake+ - Super Powered Shake
Attempt at a batteries included Shake. We reexport replacements for the main utility functions of Shake with the following adjustments whereever possible.
- Well-typed paths using the path
- New type classes
MonadAction
,MonadUnliftAction
andMonadRules
with concreteReaderT
transformers:RAction r a = RAction (ReaderT r Action a)
andShakePlus r a = ShakePlus (ReaderT r Rules a)
Text
instead ofString
wherever it is appropriate.within
style variants of the standard file and directory operations that in some cases return or acceptWithin b (Path Rel File)
values to keep tags of parent directories.
This is an early release and some things may be missing or broken, but so far the conveniences have been worth it. Some notes on the approach are detailed below.
Paths
Using the path library is kind of a
no brainer. I lose a lot of time to problems that could be avoided by using
this library, so it’s everywhere. The names for these functions shadow the
existing names, so you may want to import qualified Development.Shake
while
this library progresses if you have other FilePath
based Shake rules that
you want to mix into your build.
The standard Development.Shake.FilePath
functions for directory manipulation
are not re-exported in full, and you should use the functions in the path
library (such as replaceExtension
) and other path-based libraries. This will
probably change.
FilePattern
s are kept as-is, as Path
is strongly normalizing it makes
sense to keep these as Strings
.
RAction
The ReaderT r Action a
transformer (called RAction
) is similar to the
RIO type and should be used
similarly. In fact, you can reuse the logging functions from RIO
within any
RAction
block, which is one of the main motivators for having an Action
which is also a MonadReader
. If you need to reuse an existing shake
Action
in an RAction
, use liftAction
.
Using Within
One common complaint about Shake is having to keep track of source and output
directories and translating FilePath
s when using the input to an Action
,
leading to lots of repetition of the form (sourceFolder </>) . (-<.> ".ext") . dropDirectory1
which is prone to breakage. Using Path
helps this to some
degree, but in some cases is even more annoying because lots of Path
functions use MonadThrow
, leading to lots of monadic steps inside an
RAction
.
To alleviate this somewhat, we use Within b (Path Rel File)
as a standard
pattern for representing a file within a directory. Within
is a type
available in the within package
that is simply a newtype wrapper over an Env
comonad with the environment
specialized to Path b Dir
. We provide variants of the file operations and
rules that typically accept or return Path
s or contain callbacks that expect
paths and change these to Within
values. These functions are generally
suffixed within
. Here is the variant of getDirectoryFiles
that
produces Within
values.
getDirectoryFilesWithin' :: MonadAction m => Path b Dir -> [FilePattern] -> m [Within b (Path Rel File)]
You can convert to and from this within-style using within
and fromWithin
.
let x = $(mkRelFile "a.txt") `within` $(mkRelDir "foo") -- Within Rel (Path Rel File)
fromWithin x -- produces a `Path Rel File`
and you can assert that an existing path lies in a directory by using asWithin
, which throws
if the directory is not a proper prefix of the Path
.
$(mkRelFile "foo/a.txt") `asWithin` $(mkRelDir "foo") -- fine
$(mkRelFile "a.txt") `asWithin` $(mkRelDir "foo") -- throws error
Filerules such as (%>)
have within-style variants that accept an (Path b Dir) FilePattern
on the left and carry that env to the callback.
(%^>) :: (Partial, MonadReader r m, MonadRules m) => Within Rel FilePattern -> (Within Rel (Path Rel File) -> RAction r ()) -> m ()
You change the underlying filepath with fmap
or mapM
, whilst you can move
to a new parent directory by using localDir
, or localDirM
which is defined
in the Within
library for when the map between parent directories may throw.
The Within
library also contains more functions and instances for more
precise changes between output and source directories.
runShakePlus
The main entry point to this library is the runShakePlus
function, which
collapses a ReaderT r Rules ()
to a Rules ()
and passes the environment to
each underlying RAction
. The r
s in ShakePlus
and the underlying
RAction
s have to match. A typical setup might look like this.
let r = --setup env here
shake shakeOptions $ do
-- include some regular shake rules.
runShakePlus r $ do
-- some shake-plus rules.
Changes
Changelog for shake-plus
v0.1.10.0
- Add unlifted versions of
parallel
,forP
andpar
.
v0.1.9.0
- Add lower bound to aeson.
- Remove hashable dependency.
v0.1.8.0
- Reexport
Development.Shake.Classes
andDevelopment.Shake.RuleResult
.
v0.1.7.0
- Add
runSimpleShakePlus
for quickrunning with args and a log function.
v0.1.6.0
- Re-export
Path
andWithin
.
v0.1.5.0
- Add
getDirectoryFilesWithinIO
andgetDirectoryFilesWithinIO'
v0.1.4.0
- Re-export
Development.Shake.shakeArgs
.
v0.1.3.0
- Re-export
Development.Shake.Command
with liftedcommand
andcommand_
.
v0.1.2.0
- Add
copyFileWithin'
andcopyFileChangedWithin
.
v0.1.1.0
- Make
Within
style functions more consistent in that they actually takeWithin
values across the board. - Make
batchLoad
functions more consistent and usable. need
andwant
variants now take anyTraversable
.
v0.1.0.0
- Update to
within-0.1.1.0
which changes the data type to anEnv
comonad. - Drop the
loadSortFilterApply
loader functions in favour of a simplerbatchLoad
set of functions which accepts a loading function which can be cached. - Add enough documentation to get started.
v0.0.2.1
- Add functions based on Within to better keep track of source and target directories.
- Reexport more shake functions to remove need to import vanilla shake qualified.
- Add convenience functions
loadSortFilterApply
andloadSortFilterApplyW
for batch loading viaMonadAction
. - Add more of the API surface with
Path
andWithin
including variants ofneed
,want
readFile
,writeFile
.
v0.0.1.0
- Initial sketch of shake-plus with reexported functions. Mostly oracles,
filepaths and directory functions using
Path, and
MonadAction
,MonadUnliftAction
andMonadRules
withReaderT
transformers in a similar style to RIO