Open codygman opened 9 years ago
Not bad! A few comments:
Control.Foldl.head
instead of listToMaybe
like I mentioned in the other threaddie
instead of error
(Maybe we need a combinator for this)run
for the rsync
command, too, for consistencyecho
instead of print
inproc
instead of inshell
Other than that, though, this is a really useful example. I will add this to an examples
directory
Thanks for the feedback! I was going to try and use turtle alone to rewrite this:
https://github.com/andreafabrizi/Dropbox-Uploader/blob/master/dropShell.sh
But making a repl in Turtle wrapping bash seems weird and potentially difficult. The reason was I wanted to test replacing pieces of a shell library and seeing how it worked out.
I'm struggling to figure out what the Turtle equivalent of this shell code would be:
(source: https://github.com/andreafabrizi/Dropbox-Uploader/blob/master/dropShell.sh#L335)
while (true); do
#Reading command from shell
read -e -p "$username@Dropbox:$CWD$ " input
#Tokenizing command
eval tokens=($input)
cmd=${tokens[0]}
arg1=${tokens[1]}
arg2=${tokens[2]}
#Saving command in the history file
history -s "$input"
history -w "$SHELL_HISTORY"
case $cmd in
ls)
sh_ls "$arg1"
;;
Mainly I'm not sure what input is or where it's coming from, though I'm guessing somewhere else in the script.
I'd like to (and think it would be fun to) convert the linux steam install script that famously deleted someone’s entire root directory because of an uninitialized environmental variable.
It would also be good PR for Turtle and even the "fiercest' pragmatists would acknowledge it solved a real world task. link if you're curious:
https://github.com/indrora/steam_latest/blob/master/scripts/steam.sh
I'm very familiar with that Steam bug :)
I can translate what the script is doing. read -e -p "$username@Dropbox:CWD$ " input
is basically saying:
"$username@Dropbox:$CWD$ "
input
The equivalent of this in turtle
would roughly be:
example userName shellHistory = forever (do
Right dirTxt <- fmap toText pwd
echo (format (s%"@Dropbox:"%s%"$ ") userName dirTxt)
Just (input@[cmd, arg1, arg2]) <- readline
proc "history" ["-s", input]
proc "history" ["-w", shellHistory]
case cmd of
"ls" -> ... )
I skipped over proper error handling. A more robust script would handle errors with more descriptive error messages.
Also, it just occurred to me that it might be worth providing a Format
specifier for FilePath
s. In other words, something like this:
fp :: Format r (FilePath -> r)
So then you could just write:
dir <- pwd
echo (format (s%"@Dropbox:"%fp%"$ ") userName dir)
@Gabriel439 Just to make sure we aren't duplicating work, I wanted to let you know I'm working on a PR with examples with the same style as bos/wreq.
Alright
Just wanted to +1 this. It would be great to have even more small stand-alone examples, possibly just a link to different gists on the wiki, or however people like to share their scripts.
+1 from me too: I am finding the learning curve bit steep (thinking in terms of shell).
It could also just be on the wiki or a separate git repo but having lots of different real examples would be most helpful to pick up the idioms.
(my first real use of turtle:- feedback very welcome)
@juhp: You can simplify your code a little bit like this:
checkPkg top p = do
True <- testdir $ branchDir "epel7"
True <- testfile $ specfile "epel7"
arch <- rpmspecSrc "%{arch}" $ specfile_ "epel7"
guard (arch == "noarch")
el7 <- rpmspecSrc nvr (specfile_ "epel7")
(_, out) <- procStrict "koji" ["latest-pkg", "--quiet", "epel7", p] empty
guard (out /= "")
cur:_ <- return (Data.Text.words out)
guard (cur == el7 <> ".el7")
True <- testfile $ specfile "f20"
f20 <- rpmspecSrc nvr (specfile_ "f20")
if (el7 < f20)
then echo (el7 <> " < F20 " <> f20)
else do
f21 <- rpmspecSrc nvr (specfile_ "f21")
guard (el7 < f21)
echo (el7 <> "< F21 " <> f21)
Also, instead of:
main = sh $ do
top <- pwd
arguments >>= mapM_ (checkPkg top)
... you can do:
main = sh $ do
top <- pwd
args <- arguments
arg <- select args
checkPkg top arg
In fact, you could just inline the definition of checkPkg
into your main after this change
Alright, so I polished up @codygman's original script and added it to a newly formed examples/
directory in this commit: 43a0f2371c5145ae8341cf5a32018f1e69230d46
I'll update this thread as I go
Thanks! :-)
Update: I put your suggestions into https://pagure.io/haskell-sig/blob/master/f/scripts/el7merge.hs
Nothing like a full example to pull all the concepts you just learned together. I give you this code so you can see review the code (and see what mistakes a new user of your library made) and to possibly include for others to learn from.
I know some repositories have a examples subdirectory. This could even fit on a Tutorials.DatabaseBackup example documentation page or something?
code: