From 39674a60757bf3cd00a266e6169466185d9bb875 Mon Sep 17 00:00:00 2001 From: Dmitrii Kovanikov Date: Sat, 23 Feb 2019 22:07:59 +0800 Subject: [PATCH] [#1] Implement core library idea (#2) Resolves #1 --- .travis.yml | 10 ++------ shellmet.cabal | 12 +++++---- src/Shellmet.hs | 66 +++++++++++++++++++++++++++++++++++++++++++++--- stack-8.2.2.yaml | 4 --- stack-8.4.4.yaml | 4 --- 5 files changed, 72 insertions(+), 24 deletions(-) delete mode 100644 stack-8.2.2.yaml delete mode 100644 stack-8.4.4.yaml diff --git a/.travis.yml b/.travis.yml index ae4d2d5..8aed183 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ language: haskell git: depth: 5 -cabal: "2.0" +cabal: "2.4" cache: directories: @@ -17,13 +17,7 @@ matrix: - ghc: 8.2.2 - ghc: 8.4.4 - ghc: 8.6.3 - - - ghc: 8.2.2 - env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.2.2.yaml" - - - ghc: 8.4.4 - env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml" - + - ghc: 8.6.3 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack.yaml" diff --git a/shellmet.cabal b/shellmet.cabal index 7d5cdeb..5a0a37a 100644 --- a/shellmet.cabal +++ b/shellmet.cabal @@ -2,7 +2,7 @@ cabal-version: 2.0 name: shellmet version: 0.0.0 synopsis: Out of the shell solution for scripting in Haskell -description: Out of the shell solution for scripting in Haskell +description: Shellmet provides easy and convenient way to call shell commands from Haskell programs homepage: https://github.com/kowainik/shellmet bug-reports: https://github.com/kowainik/shellmet/issues license: MPL-2.0 @@ -14,7 +14,9 @@ category: Shell, Command Line build-type: Simple extra-doc-files: README.md , CHANGELOG.md -tested-with: GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.3 +tested-with: GHC == 8.2.2 + GHC == 8.4.4 + GHC == 8.6.3 source-repository head type: git @@ -23,10 +25,10 @@ source-repository head library hs-source-dirs: src exposed-modules: Shellmet - build-depends: base >= 4.10.1.0 && < 4.13 - + , process ^>= 1.6.3 + , text ^>= 1.2.3 ghc-options: -Wall -Wincomplete-uni-patterns @@ -58,7 +60,7 @@ test-suite shellmet-test build-depends: base >= 4.10.1.0 && < 4.13 , shellmet - + ghc-options: -Wall -threaded diff --git a/src/Shellmet.hs b/src/Shellmet.hs index 475baa4..b38cd74 100644 --- a/src/Shellmet.hs +++ b/src/Shellmet.hs @@ -1,6 +1,66 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} + +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE TypeFamilies #-} + +{- | This module contains neat utilities to be able to work with +shell commands in generic and simple way using just strings. +-} + module Shellmet - ( someFunc + ( ($|) + , ($?) ) where -someFunc :: IO () -someFunc = putStrLn ("someFunc" :: String) +import Control.Exception (catch) +import Data.String (IsString (..)) +import Data.Text (Text) +import System.Process (callCommand, readProcess, showCommandForUser) + +import qualified Data.Text as T + + +{- | This instance is needed to provide functionality to call commands by using +simple string literals in 'IO' monad. + +>>> "ls" ["-1"] +⚙ ls -1 +CHANGELOG.md +CONTRIBUTING.md +dist-newstyle +LICENSE +README.md +shellmet.cabal +src +stack.yaml +test +-} +instance (a ~ [Text], b ~ IO ()) => IsString (a -> b) where + fromString :: String -> [Text] -> IO () + fromString cmd args = do + let cmdStr = showCommandForUser cmd (map T.unpack args) + putStrLn $ "⚙ " ++ cmdStr + callCommand cmdStr + +{- | Run shell command with given options and return stripped stdout of the +executed command. + +>>> "echo" $| ["Foo", "Bar"] +"Foo Bar" +-} +infix 5 $| +($|) :: FilePath -> [Text] -> IO Text +cmd $| args = T.strip . T.pack <$> readProcess cmd (map T.unpack args) "" + +{- | Do some IO actions when processed failed with error. + +>>> "exit" ["0"] $? putStrLn "Command failed" +⚙ exit 0 + +>>> "exit" ["1"] $? putStrLn "Command failed" +⚙ exit 1 +Command failed +-} +infixl 4 $? +($?) :: IO () -> IO () -> IO () +action $? handler = action `catch` \(_ :: IOError) -> handler diff --git a/stack-8.2.2.yaml b/stack-8.2.2.yaml deleted file mode 100644 index 0fa5687..0000000 --- a/stack-8.2.2.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: lts-11.22 - -ghc-options: - "$locals": -fhide-source-paths diff --git a/stack-8.4.4.yaml b/stack-8.4.4.yaml deleted file mode 100644 index f26773f..0000000 --- a/stack-8.4.4.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: lts-12.25 - -ghc-options: - "$locals": -fhide-source-paths