module Aura.Build
( installPkgFiles
, buildPackages
) where
import Aura.Core
import Aura.IO
import Aura.Languages
import Aura.MakePkg
import Aura.Packages.AUR (clone)
import Aura.Pacman (pacman)
import Aura.Settings
import Aura.Shell (chown)
import Aura.Types
import Aura.Utils
import Control.Monad.Trans.Except
import Data.Hashable (hash)
import RIO
import RIO.Directory
import RIO.FilePath
import qualified RIO.NonEmpty as NEL
import RIO.Partial (fromJust)
import qualified RIO.Set as S
import qualified RIO.Text as T
import RIO.Time
import System.Process.Typed
srcPkgStore :: FilePath
srcPkgStore = "/var/cache/aura/src"
installPkgFiles :: NonEmpty PackagePath -> RIO Env ()
installPkgFiles files = do
ss <- asks settings
liftIO $ checkDBLock ss
liftIO . pacman $ ["-U"] <> map (T.pack . ppPath) (toList files) <> asFlag (commonConfigOf ss)
buildPackages :: NonEmpty Buildable -> RIO Env (NonEmpty PackagePath)
buildPackages bs = mapMaybeA build (NEL.toList bs) >>= maybe bad (pure . fold1) . NEL.nonEmpty
where
bad :: RIO Env a
bad = throwM $ Failure buildFail_10
build :: Buildable -> RIO Env (Maybe (NonEmpty PackagePath))
build p = do
logDebug $ "Building: " <> display (pnName $ bName p)
ss <- asks settings
notify ss (buildPackages_1 $ bName p) *> hFlush stdout
result <- build' ss p
either buildFail (pure . Just) result
build' :: Settings -> Buildable -> RIO Env (Either Failure (NonEmpty PackagePath))
build' ss b = do
let pth = buildPathOf $ buildConfigOf ss
liftIO $ createDirectoryIfMissing True pth
setCurrentDirectory pth
buildDir <- liftIO $ randomDirName b
liftIO $ createDirectoryIfMissing True buildDir
setCurrentDirectory buildDir
runExceptT $ do
bs <- ExceptT $ cloneRepo b usr
liftIO $ setCurrentDirectory bs
liftIO $ overwritePkgbuild ss b
pNames <- ExceptT . liftIO $ makepkg ss usr
paths <- liftIO $ traverse (moveToCachePath ss) pNames
liftIO . when (S.member AllSource . makepkgFlagsOf $ buildConfigOf ss) $
makepkgSource usr >>= traverse_ moveToSourcePath
pure paths
where
usr :: User
usr = fromMaybe (User "桜木花道") . buildUserOf $ buildConfigOf ss
randomDirName :: Buildable -> IO FilePath
randomDirName b = do
pwd <- getCurrentDirectory
UTCTime _ dt <- getCurrentTime
let nh = hash . pnName $ bName b
vh = hash $ bVersion b
v = abs $ nh + vh + floor dt
dir = T.unpack (pnName $ bName b) <> "-" <> show v
pure $ pwd </> dir
cloneRepo :: Buildable -> User -> RIO Env (Either Failure FilePath)
cloneRepo pkg usr = do
currDir <- liftIO getCurrentDirectory
logDebug $ "Currently in: " <> displayShow currDir
scriptsDir <- liftIO $ chown usr currDir [] *> clone pkg
case scriptsDir of
Nothing -> pure . Left . Failure . buildFail_7 $ bName pkg
Just sd -> chown usr sd ["-R"] $> Right sd
overwritePkgbuild :: Settings -> Buildable -> IO ()
overwritePkgbuild ss p = when (switch ss HotEdit || switch ss UseCustomizepkg) $
writeFileBinary "PKGBUILD" . pkgbuild $ bPkgbuild p
buildFail :: Failure -> RIO Env (Maybe a)
buildFail (Failure err) = do
ss <- asks settings
scold ss err
withOkay ss buildFail_6 buildFail_5 $ pure Nothing
moveToCachePath :: Settings -> FilePath -> IO PackagePath
moveToCachePath ss p = copy $> fromJust (packagePath newName)
where newName = pth </> takeFileName p
pth = either id id . cachePathOf $ commonConfigOf ss
copy = runProcess . setStderr closed . setStdout closed
$ proc "cp" ["--reflink=auto", p, newName]
moveToSourcePath :: FilePath -> IO FilePath
moveToSourcePath p = renameFile p newName $> newName
where newName = srcPkgStore </> takeFileName p