module clpm import _SystemArray from StdFunc import flip, o import StdFile import StdList import StdOverloaded import StdString import StdTuple import Control.Applicative import Control.Monad import Data.Error from Data.Func import $ import Data.Functor import Data.Maybe import Data.Tuple from Text import instance + String import Text.JSON import System.CommandLine import System.Directory import System.File import CLPM.Package import CLPM.Repository import CLPM.Util CLPM_VERSION :== (0,1,0) :: Action = NoAction | Install | Make :: Arguments = { package_file :: String , action :: Action //, repository :: String , clm_options :: [String] , show_help :: Bool } instance zero Arguments where zero = { package_file = PACKAGE_FILE , action = NoAction //, repository = REPOSITORY , clm_options = [] , show_help = False } Start w # (io,w) = stdio w # ((missed, args), w) = appFst (parseArgs zero o tl) $ getCommandLine w | not (isEmpty missed) # io = foldr (flip (<<<)) io ["Unknown option: " + m + "\r\n" \\ m <- missed] = snd $ fclose io w | args.show_help = snd $ fclose (io <<< HELP_TEXT) w # (pkg,w) = readPackage args.package_file w | isError pkg # io = io <<< fromError pkg <<< "\r\n" # (_,w) = fclose io w = w # (Ok pkg) = pkg # (io,w) = do args pkg io w # (_,w) = fclose io w = w do :: Arguments Package *File *World -> *(*File, *World) do args pkg io w = case args.action of NoAction = (io,w) Install = cmd_install pkg io w Make = cmd_make args.clm_options pkg io w cmd_install :: Package *File *World -> *(*File, *World) cmd_install pkg io w # (e,w) = fileExists MODULE_DIR w # w = if e w (snd $ createDirectory MODULE_DIR w) # (repo,w) = getRepository REPOSITORY w | isError repo = (io <<< fromError repo <<< "\r\n", w) # (Ok repo) = repo # solv = resolveDependencies repo pkg | isError solv = (io <<< fromError solv <<< "\r\n", w) # (Ok solv) = solv # io = io <<< "Installing dependencies:\r\n" = installAll solv io w where installAll :: [(Dependency, Version)] *File *World -> *(*File, *World) installAll [] f w = (f,w) installAll [(d,v):ds] f w #! f = f <<< "Installing " <<< depName d <<< ":" <<< toString v <<< "...\r\n" #! (err,w) = install d v w | isError err = (f <<< fromError err <<< "\r\n", w) #! f = f <<< fromOk err <<< "\r\n" = installAll ds f w cmd_make :: [String] Package *File *World -> *(*File, *World) cmd_make opts pkg io w | isNothing pkg.main = (io <<< "This package does not have a main module.\r\n", w) # (ps,w) = getRecursivePaths pkg w | isError ps = (io <<< fromError ps <<< "\r\n", w) # ps = fromOk ps # cmd = foldl (+) "clm" [" -I " + p \\ p <- ps] + foldl (+) "" [" " + f \\ f <- optionsToFlags pkg.options ++ opts] + " " + fromJust pkg.main + " -o " + fromJust pkg.main #! io = io <<< cmd <<< "\r\n" #! (r,w) = syscall cmd w = (io,setReturnCode (if (r==0) 0 -1) w) parseArgs :: (Arguments [String] -> ([String], Arguments)) parseArgs = pa [] where pa :: [String] Arguments [String] -> ([String], Arguments) pa miss args [] = (miss, args) pa miss args ["-h":rest] = pa miss {args & show_help = True} rest pa miss args ["--help":rest] = pa miss {args & show_help = True} rest pa miss args ["-p":name:rest] = pa miss {args & package_file = name} rest //pa miss args ["-r":repo:rest] = pa miss {args & repository = repo} rest pa miss args ["-c":opt:rest] = pa miss {args & clm_options = args.clm_options ++ [opt]} rest pa miss args ["install":rest] = pa miss {args & action = Install} rest pa miss args ["make":rest] = pa miss {args & action = Make} rest pa miss args [a:rest] = pa [a:miss] args rest HELP_TEXT =: "CLPM - A Clean Package Manager - v" + toString CLPM_VERSION + "\r\n\r\n" + "Usage: clpm [option]\r\n\r\n" + foldl (+) "Commands:\r\n" [pad 2 12 cmd + desc + "\r\n" \\ (cmd,desc) <- cmds] + "\r\n" + foldl (+) "Options:\r\n" [pad 2 12 opt + desc + "\r\n" \\ (opt,desc) <- opts] where cmds = [ ("make", "Build package using clm") , ("install", "Install package dependencies") ] opts = [ ("-c ", "Add OPT to the clm arguments") , ("-h, --help", "Print this help text") , ("-p ", "Use FILE as package file instead of package.json") //, ("-r ", // "Use HOST as repository provider instead of " + REPOSITORY) ] pad :: Int Int String -> String pad l r s | size s > r = p l + s + "\r\n" + p (l + r) | otherwise = p l + s + p (r - size s) where p i = toString $ repeatn i ' '