yamlkeysdiff-0.5.1: src/YamlKeysDiff/Opts.hs
-- Copyright (c) 2015 Antoine Catton
--
-- This file is part of YAMLKeysDiff and is distributed under EUPLv1.1,
-- see the LICENSE file for more information. If a LICENSE file wasn't
-- provided with this piece of software, you will find a copy at:
-- <http://ec.europa.eu/idabc/eupl.html>
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
module YamlKeysDiff.Opts where
import System.Console.GetOpt
import Data.Map as Map
import qualified Data.Set as Set
import Data.Maybe (fromJust)
import qualified Data.List as List
import qualified YamlKeysDiff.Formatting as Formatting
import YamlKeysDiff.Diff (DiffLine)
data Flag = Copied
| Help
| IgnoreCase
| Normal
| SideBySide
| Unified
| Version
deriving (Show, Ord, Eq)
options :: [OptDescr Flag]
options =
[ Option ['i'] ["ignore-case"] (NoArg IgnoreCase) "ignore keys' case"
, Option ['v'] ["version"] (NoArg Version) "show version number"
, Option ['u'] ["unified"] (NoArg Unified) "unified diff"
, Option ['y'] ["side-by-side"] (NoArg SideBySide) "side by side diff"
, Option ['n'] ["normal"] (NoArg Normal) "normal diff"
-- FIXME: This is not how it's supposed to be done
, Option ['h'] ["help"] (NoArg Help) "display this message"
]
getFileArgs :: [String] -> IO (String, String)
getFileArgs args =
case args of
[a, b] -> return (a, b)
_ -> ioError (userError "You need to specify two files to compute the diff from")
getOptions :: String -> [String] -> IO ([Flag], [String])
getOptions progName argv =
case getOpt Permute options argv of
(o, n, []) -> return (o, n)
(_, _, errs) -> ioError (userError (concat errs ++ usage progName))
usage :: String -> String
usage progName =
let header = "Usage: " ++ progName ++ " [OPTIONS...] FILES..." in
usageInfo header options
defaultFormattingFlag :: Flag
defaultFormattingFlag = Normal
formattingFunctions = Map.fromList
[ (Normal, Formatting.normalFormatting)
, (SideBySide, Formatting.sideBySideFormatting)
, (Unified, Formatting.unifiedFormatting)
]
getFormattingFunction :: [Flag] -> IO ([DiffLine] -> String)
getFormattingFunction flags =
let formattingFlags = Map.keysSet formattingFunctions
flags' = Set.fromList flags
specifiedFormattingFlags = Set.intersection flags' formattingFlags
getFunction flag = fromJust $ Map.lookup flag formattingFunctions
in if Set.null specifiedFormattingFlags then
return $ getFunction $ defaultFormattingFlag
else if Set.size specifiedFormattingFlags == 1 then
return $ getFunction $ Set.elemAt 0 specifiedFormattingFlags
else ioError (userError "Multiple format flags specified")