-- Copyright (C) 2017 Red Hat, Inc. -- -- This file is part of bdcs-api. -- -- bdcs-api is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- bdcs-api is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with bdcs-api. If not, see . {-| Workspace functions - The workspace is a temporary storage location for Recipes. The workspace files are stored under the ./git/workspace/\ directory using the recipe's toml filename as created by 'recipeTomlFilename'. Recipes written to the workspace are not committed to git, and are overwritten on the next call to 'workspaceWrite' -} module BDCS.API.Workspace(workspaceRead, workspaceWrite, workspaceDelete, workspaceDir, WorkspaceError(..)) where import BDCS.API.Recipe(Recipe(..), parseRecipe, recipeTOML, recipeTomlFilename) import BDCS.API.Utils(maybeThrow) import Control.Conditional(ifM, whenM) import qualified Control.Exception as CE import qualified Data.Text as T import qualified Data.Text.IO as TIO import GI.Gio(fileGetPath) import qualified GI.Ggit as Git import System.Directory(createDirectoryIfMissing, doesFileExist, removeFile) import System.FilePath.Posix(()) -- | Workspace Errors data WorkspaceError = RepoLocationError -- ^ There was a problem getting the path to the repository | ParseRecipeError String -- ^ There was an error parsing the recipe, details will be included deriving (Eq, Show) instance CE.Exception WorkspaceError -- | Create the branch's workspace path -- -- [@repo@]: Open git repository -- [@branch@]: Branch name workspaceDir :: Git.Repository -> T.Text -> IO FilePath workspaceDir repo branch = do location <- Git.repositoryGetLocation repo >>= maybeThrow RepoLocationError path <- fileGetPath location >>= maybeThrow RepoLocationError return $ path "workspace" T.unpack branch -- | Read a 'Recipe' from the branch's workspace -- -- [@repo@]: Open git repository -- [@branch@]: Branch name -- [@recipe_name@]: The name, not the filename, of the recipe to read -- -- Can throw 'WorkspaceError' workspaceRead :: Git.Repository -> T.Text -> T.Text -> IO (Maybe Recipe) workspaceRead repo branch recipe_name = do dir <- workspaceDir repo branch createDirectoryIfMissing True dir let filename = dir T.unpack (recipeTomlFilename $ T.unpack recipe_name) ifM (doesFileExist filename) (Just <$> readRecipe filename) (return Nothing) where readRecipe :: FilePath -> IO Recipe readRecipe filename = do toml_in <- TIO.readFile filename let erecipe = parseRecipe toml_in case erecipe of Left e -> CE.throwIO $ ParseRecipeError e Right recipe -> return recipe -- | Write a 'Recipe' to the branch's workspace -- -- [@repo@]: Open git repository -- [@branch@]: Branch name -- [@recipe@]: The 'Recipe' to write to the workspace workspaceWrite :: Git.Repository -> T.Text -> Recipe -> IO () workspaceWrite repo branch recipe = do dir <- workspaceDir repo branch createDirectoryIfMissing True dir let toml_out = T.unpack $ recipeTOML recipe let filename = dir T.unpack (recipeTomlFilename (rName recipe)) writeFile filename toml_out -- | Delete the recipe from the branch's workspace -- -- [@repo@]: Open git repository -- [@branch@]: Branch name -- [@recipe_name@]: The name, not the filename, of the recipe to read -- -- Can throw a WorkspaceError workspaceDelete :: Git.Repository -> T.Text -> T.Text -> IO () workspaceDelete repo branch recipe_name = do dir <- workspaceDir repo branch let filename = dir T.unpack (recipeTomlFilename $ T.unpack recipe_name) whenM (doesFileExist filename) (removeFile filename)