|
| 1 | +{-# LANGUAGE OverloadedStrings #-} |
| 2 | + |
| 3 | +module GitSub (run, parseRootCommand) where |
| 4 | + |
| 5 | +import Data.List hiding (intercalate) |
| 6 | +import Data.Monoid |
| 7 | +import Data.Text as T hiding (intercalate, unlines) |
| 8 | +import Filesystem.Path.CurrentOS as Path (FilePath, encodeString, |
| 9 | + toText, valid) |
| 10 | + |
| 11 | +import GitSub.CmdParsers |
| 12 | +import GitSub.Submodule (parseSubmodules) |
| 13 | +import Options.Applicative |
| 14 | +import Prelude hiding (FilePath) |
| 15 | +import System.Process (readCreateProcess, shell) |
| 16 | + |
| 17 | +run :: Command -> IO () |
| 18 | +run gitSubCommand = case gitSubCommand of |
| 19 | + List -> runList |
| 20 | + Add url path -> runAdd url path |
| 21 | + Remove path -> runRemove path |
| 22 | + Move from to -> runMove from to |
| 23 | + |
| 24 | +runList :: IO () |
| 25 | +runList = do |
| 26 | + submodulesStr <- readFile ".gitmodules" |
| 27 | + let submodules = parseSubmodules submodulesStr |
| 28 | + case submodules of |
| 29 | + Left _ -> printText ".gitmodules not found." |
| 30 | + Right subs -> putStrLn . unlines $ show <$> subs |
| 31 | + |
| 32 | +runAdd :: String -> FilePath -> IO () |
| 33 | +runAdd url path = |
| 34 | + if valid path |
| 35 | + then do |
| 36 | + result <- runShell $ "git submodule add " ++ url ++ " " ++ encodeString path |
| 37 | + print result |
| 38 | + else printText "invalid path argument" |
| 39 | + |
| 40 | +runRemove :: FilePath -> IO () |
| 41 | +runRemove path = do |
| 42 | + runShell removeCached |
| 43 | + runShell removeGitmodulesEntry |
| 44 | + runShell removeGitConfigEntry |
| 45 | + runShell gitStage |
| 46 | + printText $ "Submodules entries for " <> path' <> " were deleted." |
| 47 | + printText "The changes have been staged for you." |
| 48 | + printText "Please commit the changes to complete the submodule removal." |
| 49 | + where removeCached = gitRmCached <> path' |
| 50 | + removeGitmodulesEntry = gitRmGitmodulesEntry <> path' |
| 51 | + removeGitConfigEntry = gitRmGitConfigEntry <> path' |
| 52 | + path' = cleanTxt path |
| 53 | + |
| 54 | +runMove :: FilePath -> FilePath -> IO () |
| 55 | +runMove from to = do |
| 56 | + runShell $ gitMove <> from' <> " " <> to' |
| 57 | + runShell gitStage |
| 58 | + printText $ "Submodule moved from " <> from' <> " to " <> to' |
| 59 | + printText "The changes have been staged for you." |
| 60 | + printText "Please commit the changes to complete the submodule move." |
| 61 | + where gitMove = "git mv " |
| 62 | + from' = cleanTxt from |
| 63 | + to' = cleanTxt to |
| 64 | + |
| 65 | +parseRootCommand :: IO Command |
| 66 | +parseRootCommand = |
| 67 | + showHelpOnErrorExecParser |
| 68 | + (info |
| 69 | + (helper <*> parseCommand) |
| 70 | + (fullDesc <> progDesc cliDescription <> header cliHeader)) |
| 71 | + |
| 72 | +cliDescription :: String |
| 73 | +cliDescription = "utility to manage submodules in a git repository" |
| 74 | + |
| 75 | +cliHeader :: String |
| 76 | +cliHeader = "git-sub: git submodules made easy" |
| 77 | + |
| 78 | + |
| 79 | +gitRmCached :: Text |
| 80 | +gitRmCached = "git rm --cached " |
| 81 | + |
| 82 | +gitRmGitmodulesEntry :: Text |
| 83 | +gitRmGitmodulesEntry = "git config -f .gitmodules --remove-section submodule." |
| 84 | + |
| 85 | +gitRmGitConfigEntry :: Text |
| 86 | +gitRmGitConfigEntry = "git config -f .git/config --remove-section submodule." |
| 87 | + |
| 88 | +gitStage :: Text |
| 89 | +gitStage = "git add -u" |
| 90 | + |
| 91 | +cleanTxt :: FilePath -> Text |
| 92 | +cleanTxt = removeTrailingSlash . toText |
| 93 | + where removeTrailingSlash txtPath = case txtPath of |
| 94 | + Right text -> if T.last text == '/' then T.dropEnd 1 text else text |
| 95 | + Left err -> err |
| 96 | + |
| 97 | +runShell :: (Show a) => a -> IO String |
| 98 | +runShell strCommand = readCreateProcess (shell $ show strCommand) "" |
| 99 | + |
| 100 | +printText :: Text -> IO () |
| 101 | +printText = print |
0 commit comments