foliage/app/Foliage/RemoteAsset.hs

53 lines
1.7 KiB
Haskell
Raw Normal View History

2022-05-16 09:39:53 +03:00
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE TypeFamilies #-}
module Foliage.RemoteAsset
2022-09-22 19:54:35 +03:00
( fetchRemoteAsset,
addFetchRemoteAssetRule,
2022-05-16 09:39:53 +03:00
)
where
import Data.ByteString qualified as BS
import Data.Char (isAlpha)
import Data.List (dropWhileEnd)
import Data.Maybe (fromMaybe)
import Development.Shake
import Development.Shake.Classes
import Development.Shake.FilePath
import Development.Shake.Rule
import System.Directory (createDirectoryIfMissing)
import System.FilePath.Posix qualified as Posix
type Url = String
newtype RemoteAsset = RemoteAsset Url
deriving (Show, Eq)
deriving (Hashable, Binary, NFData) via Url
type instance RuleResult RemoteAsset = FilePath
2022-09-22 19:54:35 +03:00
fetchRemoteAsset :: Url -> Action FilePath
fetchRemoteAsset = apply1 . RemoteAsset
2022-05-16 09:39:53 +03:00
2022-09-22 19:54:35 +03:00
addFetchRemoteAssetRule :: FilePath -> Rules ()
addFetchRemoteAssetRule cacheDir = addBuiltinRule noLint noIdentity run
2022-05-16 09:39:53 +03:00
where
run :: BuiltinRun RemoteAsset FilePath
run (RemoteAsset url) old _mode = do
let scheme : rest = Posix.splitPath url
scheme' = dropWhileEnd (not . isAlpha) scheme
path = cacheDir </> joinPath (scheme' : rest)
-- parse etag from store
let oldETag = fromMaybe BS.empty old
newETag <-
withTempFile $ \fp -> do
liftIO $ BS.writeFile fp oldETag
liftIO $ createDirectoryIfMissing True (takeDirectory path)
cmd_ Shell ["curl", "--silent", "--location", "--etag-compare", fp, "--etag-save", fp, "--output", path, url]
liftIO $ BS.readFile fp
let changed = if newETag == oldETag then ChangedNothing else ChangedRecomputeDiff
return $ RunResult {runChanged = changed, runStore = newETag, runValue = path}