1 {-# LANGUAGE DeriveGeneric #-}
2 {-# LANGUAGE OverloadedStrings #-}
4 -- I do not know haskell, this code is probably shit
6 module AddProgram where
9 import Data.Aeson.Encode.Pretty
10 import Data.Aeson.Types
11 import qualified Data.ByteString.Lazy as B
12 import Data.List.Extra
14 import qualified Data.Text as T
18 import GHC.Float (double2Float)
20 import System.Console.Haskeline
21 import System.Environment (getEnv)
25 import Text.Printf (printf)
29 supportLevel :: SupportLevel,
32 deriving (Generic, Show)
34 instance ToJSON File where
35 toEncoding (File path supportLevel help) = pairs ("path" .= path <> "movable" .= supportLevel <> "help" .= help)
37 data Program = Program
41 deriving (Generic, Show)
43 instance ToJSON Program where
44 toEncoding = genericToEncoding defaultOptions
46 save :: Program -> IO ()
48 let path = ("./programs/" ++ (T.unpack (name program)) ++ ".json")
49 B.writeFile path (encodePretty program)
51 data SupportLevel = Unsupported | Alias | EnvVars | Supported
52 deriving (Generic, Show)
54 instance ToJSON SupportLevel where
55 toEncoding Unsupported = toEncoding ( Bool False )
56 toEncoding _ = toEncoding ( Bool True )
58 getTemplate :: SupportLevel -> String
59 getTemplate Unsupported = "Currently unsupported.\n\n_Relevant issue:_ https://github.com/user/repo/issues/nr\n"
60 getTemplate EnvVars = "Export the following environment variables:\n\n```bash\n\n```"
61 getTemplate Alias = "Alias PROGRAM to use a custom configuration location:\n\n```bash\nalias PROGRAM=PROGRAM --config \"$XDG_CONFIG_HOME\"/PROGRAM/config\n```\n"
62 getTemplate Supported = "Supported since _VERSION_.\n\nYou can move the file to _XDG_CONFIG_HOME/PROGRAM/CONFIG.\n"
65 getHelp :: SupportLevel -> IO String
66 getHelp supportLevel = do
67 id <- toString <$> Data.UUID.V4.nextRandom
68 editor <- appendFile ("/tmp/xdg-ninja." ++ id ++ ".md") (getTemplate supportLevel) >> (getEnv "EDITOR")
69 (_, _, _, p) <- createProcess (shell (editor ++ " /tmp/xdg-ninja." ++ id ++ ".md"))
72 ExitSuccess -> readFile ("/tmp/xdg-ninja." ++ id ++ ".md")
73 ExitFailure a -> return ""
75 getProp :: T.Text -> T.Text -> IO String
76 getProp prompt placeholder = do
77 let string_prompt = T.unpack prompt
78 let string_placholder = T.unpack placeholder
79 x <- runInputT defaultSettings (getInputLineWithInitial string_prompt (string_placholder, ""))
84 data Answer = Yes | No | Unknown
86 stringToBool :: String -> Answer
87 stringToBool s = case lower s of
96 promptBool :: T.Text -> T.Text -> T.Text -> IO Bool
97 promptBool prompt prompt_unrecognised placeholder = do
98 x <- getProp prompt placeholder
99 case stringToBool x of
102 Unknown -> printf "%s\n" prompt_unrecognised >> promptBool prompt prompt_unrecognised placeholder
104 getSupportLevel :: IO SupportLevel
106 movable <- promptBool (blue "Can the file be moved? (y/n) ") (red "Please provide a valid answer.") "y"
109 envVars <- promptBool (blue "Do you have to export environment variables? (y/n) ") (red "Please provide a valid answer.") "y"
113 alias <- promptBool (blue "Do you have to set an alias? (y/n) ") (red "Please provide a valid answer.") "y"
116 else return Supported
117 else return Unsupported
121 path <- getProp (blue "Path to file: ") "$HOME/."
122 supportLevel <- getSupportLevel
123 help <- getHelp supportLevel
124 return File {path = path, supportLevel = supportLevel, help = help}
126 getFiles :: [File] -> IO [File]
128 if Data.List.Extra.null files
131 getFiles (newFile : files)
133 new <- promptBool (green "Add another file? (y/n) ") (red "Please provide a valid answer.") ""
137 getFiles (newFile : files)
140 getProgram :: IO Program
142 name <- printf "%s\n" (T.unpack (bold (cyan "XDG-ninja Configuration Wizard")))
143 >> printf "%s\n" (T.unpack (faint (italic (cyan "First, tell me what program you're creating a configuration for."))))
144 >> getProp (yellow "Program name: ") ""
145 files <- printf "%s\n" (T.unpack (faint (italic (cyan "Alright, now let's configure which files belong to this program."))))
146 >> printf "%s\n" (T.unpack (faint (italic (cyan "I'm going to ask you for the path to the file, please use $HOME instead of ~."))))
147 >> printf "%s\n" (T.unpack (faint (italic (cyan "I'll then ask you wether or not this file can be moved to a different directory."))))
148 >> printf "%s\n" (T.unpack (faint (italic (cyan "Finally, your editor is going to open a markdown document. Enter instructions on moving the file in question, then save and close."))))
150 return Program {name = T.pack name, files = files}
154 program <- getProgram
155 do_save <- promptBool (green "Save? (y/n) ") (red "Please provide a valid answer.") ""