packages feed

shelly 1.6.2.3 → 1.6.2.4

raw patch · 2 files changed

+179/−1 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

+ README.md view
@@ -0,0 +1,177 @@+# Shelly++Shelly provides a single module for convenient systems programming in Haskell.++* is aimed at convenience and getting things done rather than being a demonstration of elegance.+* has detailed and useful error messages+* maintains its own environment, making it thread-safe+* is modern, using Text and system-filepath/system-fileio+* has low memory usage+  * `run_` and other underscore variants that don't return stdout+  * `runFoldLines` to run a fold operation over each line rather than loading all of stdout into memory+  * `runHandle` and `runHandles` for complete control over handles++Looking to put your Haskell learning to immediate practical use? You don't have to create artifical intelligence, try just automating some of your boring tasks.++The focus of this library on convenience combined with good error messages should make shelly approachable for newer users of Haskell.+I have published [an introductory article to scripting with shelly, targeted towards those not familiar with Haskell](http://www.linux-magazin.de/Online-Artikel/Shell-scripting-with-type-safety-using-Haskell/). There is a paid version in German from Linux Magazin.+That article uses the version `shelly < 1.0` which uses lazy text. `shelly > 1.0` uses strict text.++++## More shelly packages++The [shelly-extra](http://hackage.haskell.org/package/shelly-extra) package has some additional functionality that requires additional dependencies, currently including a convenient concurrency/futures implementation. If you are following along the above article you need to install it.+++## Examples++* [Yesod development installer](https://github.com/yesodweb/scripts/blob/master/install.hs)+* [cabal-meta, a haskell install tool](https://github.com/yesodweb/cabal-meta/blob/master/main.hs)+* [antigen-hs, a zsh plugin manager](https://github.com/Tarrasch/antigen-hs)+++### Blog Posts++* [Shelly automation with Literate Haskell](http://www.scholarslab.org/dh-developer/shell-programming-in-haskell-converting-s5-slides-to-pdf/)+++### Testimonials++* [a beginning Haskeller does automation](http://www.reddit.com/r/haskell/comments/w86gu/my_current_job_task_is_boring_so_i_wrote_a_simple/)++### Help++* [google group for Haskell shell scripting](https://groups.google.com/forum/#!forum/haskell-shell-scripting)++## Alternatives++### Haskell shell scripting libarires+++* [HSH](http://hackage.haskell.org/package/HSH) - A good alternative if you want to mixup usage of String and ByteString rather than just use Text.+* [HsShellScript](http://hackage.haskell.org/packages/archive/hsshellscript/3.1.0/doc/html/HsShellScript.html) - Has extensive low-level shell capabilities.+* [shell-conduit](http://hackage.haskell.org/package/shell-conduit) - efficient streaming via conduits. Makes some portability sacrifices by+  * encouraging one to just use the shell instead of cross-platform Haskell code+  * encouraging one to use a convenience function that searches the PATH at compile-time+* [shell-monad](http://hackage.haskell.org/package/shell-monad) - compile Haskell code down to shell script. This is a different approach from all the rest of the libraries. Writing your script is not as user-friendly as the other Haskell libraries, but it nicely solves the deployment issue.+* [turtle](http://hackage.haskell.org/package/turtle) - In some sense a [redesign of Shelly designed for beginner-friendliness](http://www.reddit.com/r/haskell/comments/2u6b8m/use_haskell_for_shell_scripting/co5ucq9)++HSH and HsShellScript (unlike Shelly currently) implement very efficient mechanisms for piping/redirecting in the system.+turtle, like Shelly offers folding as a way to efficiently deal with a stream.++None of the alternatives to Shelly offer command tracing.+For some this is an absolutely critical feature, particularly given that Haskell does not yet offer up stack traces.+++### Haskell supplements++* [FileManip](hackage.haskell.org/package/FileManip) - more efficient file finding code (uses Lazy IO). Shelly's finders are currently being re-worked++### Shell commands with richer input/output++Shelly does not change the nature of shell scripting (text in, text out).+If you want something more revolutionary you might try these:++* [Plush](https://github.com/mzero/plush) shell with nice GUI. Written in Haskell. Actively developed, unlike [TermKit](https://github.com/unconed/TermKit/)+* PowerShell is proably the best known.+* [Haskell project](https://github.com/pkamenarsky/ytools) using typed JSON+* [untyped JSON](https://github.com/benbernard/RecordStream)+++## Usage++Shelly's main goal is ease of use.+There should be a primitive for every shell operation you need so you can easily build abstractions, so there are many of the usual file and environment operations.++There are 2 main entry points for running arbitrary commands: `run` and `cmd`.+They take a FilePath as their first argument. `run` takes a [Text] as its second argument.+`cmd` takes a variadic number of arguments, and they can be either Text or FilePath.++Fun Example: shows an infectious script: it uploads itself to a server and runs itself over ssh.+Of course, the development machine may need to be exactly the same OS as the server.++I recommend using the boilerplate at the top of this example in your projects.++~~~~~ {.haskell}+    {-# LANGUAGE OverloadedStrings #-}+    {-# LANGUAGE ExtendedDefaultRules #-}+    {-# OPTIONS_GHC -fno-warn-type-defaults #-}+    import Shelly+    import Data.Text as T+    default (T.Text)++    main = shelly $ verbosely $ do+      host <- run "uname" ["-n"]+      if T.stripEnd host === "local-machine"+        then do d <- cmd "date"+                c <- escaping False $ cmd "git" "log -1 | head -1 | awk '{print $2}'"+                appendfile "log/deploy.log" $ T.intercalate " - " [T.stripEnd d, c]+                uploads ["deploy"]+                shPairs_ "my-server" [("./deploy", [])]+        else do+              cmd "./script/angel"++    -- same path on remote host+    -- will create directories+    uploads :: [Text] -> Sh ()+    uploads locals login = rsync $ ["--relative"] ++ locals ++ [login]++    rsync args = run_ "rsync" $ ["--delete", "-avz", "--no-g"] ++ args+~~~~~++### Variadic arguments to cmd++Yes, as seen above you can write variadic functions in Haskell quite easily, you just can't compose them as easily.+I find `cmd` to be more convenient, but I often use `run` and `command` variants when I am building up abstractions.+Building up abstractions with cmd will require type signatures.++    -- easy signature, but only allows one argument+    let cabal = cmd "cabal" :: Text -> Sh Text++    -- more complex signature that allows partial application of cmd+    let cabal = cmd "cabal" :: Shelly.ShellCmd result => result++++### Escaping++By default, all commands are shell escaped.+If you want the shell to interpret special characters such as `*`, just use `escaping False $ do ...` ++### Using Text and FilePath together++Shelly's usage of system-filepath means you may need to convert between Text and FilePath sometimes.+This should be infrequent though because++* `cmd` will convert FilePath to Text+* The `</>` and `<.>` combinators convert String/Text into a FilePath automatically++Manual conversion is done through `toTextIgnore` or `toTextWarn`.+++### Thread-safe working directory and relative paths++`cd` does not change the process working directory (essentially a global variable), but instead changes the shelly state (which is thread safe).+All of the Shelly API takes this into account, internally shelly converts all paths to absolute paths. You can turn a relative path into an absolute with `absPath` or `canonic` or you can make a path relative to the Shelly working directory with `relPath`.+++### Good error messages++Haskell's #1 weakness for IO code is a lack of stack traces.+Shelly gives you something different: detailed logging.+In most cases this should be more useful than a stack trace.+Shelly keeps a log of API usage and saves it to a .shelly directory on failure.+If you use `shellyNoDir`, the log will instead be printed to stderr.+This is in addition to the `verbosely` settings that will print out commands and their output as the program is running.+Shelly's own error messages are detailed and in some cases it will catch Haskell exceptions and re-throw them with better messages.++If you make your own primitive functions that don't use the existing Shelly API, you can create a wrapper in the Sh monad that use `trace` or `tag` to log what they are doing.+You can turn tracing off (not generally recommended) by setting `tracing False`.+++## Future plans++* improved SSH API+* more efficient piping/redirecting (issue #18)+* more efficient find functions (issue #23)
shelly.cabal view
@@ -1,6 +1,6 @@ Name:       shelly -Version:     1.6.2.3+Version:     1.6.2.4 Synopsis:    shell-like (systems) programming in Haskell  Description: Shelly provides convenient systems programming in Haskell,@@ -38,6 +38,7 @@                     test/data/zshrc                     test/data/nonascii.txt                     test/testall+                    README.md  Library   Exposed-modules: Shelly, Shelly.Lifted, Shelly.Pipe