arx 0.2.2 → 0.2.3
raw patch · 10 files changed
+253/−168 lines, 10 filesdep +hashablePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: hashable
API changes (from Hackage documentation)
+ System.Posix.ARX.CLI.Options: infixl 4 <@>
+ System.Posix.ARX.CLI.Options: shared :: ArgsParser Bool
+ System.Posix.ARX.TMPXTools: [shared] :: Template -> Bool
- System.Posix.ARX: TMPX :: SHDAT -> ByteString -> [(Var, Val)] -> Bool -> Bool -> TMPX
+ System.Posix.ARX: TMPX :: SHDAT -> ByteString -> [(Var, Val)] -> Bool -> Bool -> Bool -> TMPX
- System.Posix.ARX.CLI: tmpxOpen :: Word -> [(Var, Val)] -> (Bool, Bool) -> ByteSource -> IO TMPX
+ System.Posix.ARX.CLI: tmpxOpen :: Word -> [(Var, Val)] -> (Bool, Bool, Bool) -> ByteSource -> IO TMPX
- System.Posix.ARX.CLI: tmpxResolve :: ([Word], [IOStream], [IOStream], [(Var, Val)], [(Bool, Bool)], [ByteSource]) -> (Word, IOStream, [IOStream], [(Var, Val)], (Bool, Bool), ByteSource)
+ System.Posix.ARX.CLI: tmpxResolve :: ([Word], [IOStream], [IOStream], [(Var, Val)], [(Bool, Bool)], [Bool], [ByteSource]) -> (Word, IOStream, [IOStream], [(Var, Val)], (Bool, Bool), Bool, ByteSource)
- System.Posix.ARX.CLI.CLTokens: sizeBounded :: (Bounded b, Integral b) => Parser b
+ System.Posix.ARX.CLI.CLTokens: sizeBounded :: forall b. (Bounded b, Integral b) => Parser b
- System.Posix.ARX.CLI.Options: tmpx :: ArgsParser ([Word], [IOStream], [IOStream], [(Var, Val)], [(Bool, Bool)], [ByteSource])
+ System.Posix.ARX.CLI.Options: tmpx :: ArgsParser ([Word], [IOStream], [IOStream], [(Var, Val)], [(Bool, Bool)], [Bool], [ByteSource])
- System.Posix.ARX.Programs: TMPX :: SHDAT -> ByteString -> [(Var, Val)] -> Bool -> Bool -> TMPX
+ System.Posix.ARX.Programs: TMPX :: SHDAT -> ByteString -> [(Var, Val)] -> Bool -> Bool -> Bool -> TMPX
- System.Posix.ARX.TMPXTools: Template :: Bool -> Bool -> Builder -> Builder -> Builder -> Template
+ System.Posix.ARX.TMPXTools: Template :: Bool -> Bool -> Bool -> Builder -> Builder -> Builder -> Template
Files
- README +58/−52
- System/Posix/ARX/CLI.hs +12/−9
- System/Posix/ARX/CLI/Options.hs +31/−23
- System/Posix/ARX/Programs.hs +3/−2
- System/Posix/ARX/TMPXTools.hs +20/−8
- arx.cabal +3/−1
- docs/blessed/arx.man +45/−11
- docs/blessed/arx.txt +58/−52
- model-scripts/tmpx.sh +22/−9
- version +1/−1
README view
@@ -1,9 +1,9 @@ SYNOPSIS- arx (-h | -[?] | --help)- arx (-v | --version)- arx shdat (-b <size>)? (-o <output file>)? < input- arx shdat (-b <size>)? (-o <output file>)? <input file>+- arx tmpx <option,archive>* (//+ <command> (//+ <option,archive>*)?)?+ arx (-h | -[?] | --help)+ arx (-v | --version)+ arx shdat (-b <size>)? (-o <output file>)? < input+ arx shdat (-b <size>)? (-o <output file>)? <input file>++ arx tmpx <option,archive>* (//+ <command> (//+ <option,archive>*)?)? DESCRIPTION A UNIX executable is a simple thing -- a file the kernel can execute,@@ -38,12 +38,12 @@ cute them. This can be helpful when using ssh and sudo to set up an execution context; for example: - arx tmpx ... | ssh user@host.com sudo sh+ arx tmpx ... | ssh user@host.com sudo sh Scripts generated by tmpx will pass their arguments to the contained script or command. To pass arguments when piping to sh, use -s: - arx tmpx ... | ssh user@host.com sudo sh -s a b c+ arx tmpx ... | ssh user@host.com sudo sh -s a b c Some arguments to the generated script will be treated specially, namely, --extract, --no-rm and --no-run. Please see the section on@@ -85,80 +85,86 @@ temporary directory only on success, only on failure, always (the default) or never. + --shared+ Causes the temporary directory to be identified by a hash of+ the ARX archive, instead of by date and time. Different runs+ of the same archive will share the same directory. Note that+ this implies shared state and every disadvantage thereof.+ -b <size>- Please see the documentation for this option, shared with+ Please see the documentation for this option, shared with shdat, below. -o <path>- By default, the generated script is sent to STDOUT. With -o,+ By default, the generated script is sent to STDOUT. With -o, output is redirected to the given path. -e <path>- Causes the file specified to be packaged as the task to be- run. A binary executable, a Ruby script or a longish shell+ Causes the file specified to be packaged as the task to be+ run. A binary executable, a Ruby script or a longish shell script all fit here. - In addition to these options, arguments of the form VAR=VALUE are rec-- ognized as environment mappings and stored away in the script, to be+ In addition to these options, arguments of the form VAR=VALUE are rec-+ ognized as environment mappings and stored away in the script, to be sourced on execution. - Without -e, the tmpx subcommand tries to find the task to be run as a- sequence of arguments delimited by a run of slashes. The following+ Without -e, the tmpx subcommand tries to find the task to be run as a+ sequence of arguments delimited by a run of slashes. The following forms are all recognized: - arx tmpx ...some args... // ...command...- arx tmpx ...some args... // ...command... // ...more args...- arx tmpx // ...command... // ...some args...+ arx tmpx ...some args... // ...command...+ arx tmpx ...some args... // ...command... // ...more args...+ arx tmpx // ...command... // ...some args... - The slash runs must have the same number of slashes and must be the- longest continuous runs of slashes on the command line. The command+ The slash runs must have the same number of slashes and must be the+ longest continuous runs of slashes on the command line. The command will be included as-is in a Bourne shell script. SHDAT- The shdat subcommand translates binary data in to a shell script which- outputs the binary data. The data is encoded in HERE documents in such- a way that data without NULs is not changed and that data with NULs is- minimally expanded: about 1% for randomish data like compressed tar-+ The shdat subcommand translates binary data in to a shell script which+ outputs the binary data. The data is encoded in HERE documents in such+ a way that data without NULs is not changed and that data with NULs is+ minimally expanded: about 1% for randomish data like compressed tar- balls and about 10% in pathological cases. - The shdat subcommand can be given any number of paths, which will be+ The shdat subcommand can be given any number of paths, which will be concatenated in the order given. If no path is given, or if - is given, then STDIN will be read. -b <size>- The size of data chunks to place in each HERE document. The- argument is a positive integer followed by suffixes like B,- K, KiB, M and MiB, in the manner of dd, head and many other- tools. The default is 4MiB. This is unlikely to make a dif-+ The size of data chunks to place in each HERE document. The+ argument is a positive integer followed by suffixes like B,+ K, KiB, M and MiB, in the manner of dd, head and many other+ tools. The default is 4MiB. This is unlikely to make a dif- ference for you unless the generated script is intended to be run on a memory-constrained system. -o <path>- By default, the generated script is sent to STDOUT. With -o,+ By default, the generated script is sent to STDOUT. With -o, output is redirected to the given path. EXAMPLES- # Installer script that preserves failed builds.- git archive HEAD | bzip2 | arx tmpx -rm0 - // make install > go.sh- # Now install as root; but don't log in as root.- cat ./go.sh | ssh joey@hostname sudo /bin/sh+ # Installer script that preserves failed builds.+ git archive HEAD | bzip2 | arx tmpx -rm0 - // make install > go.sh+ # Now install as root; but don't log in as root.+ cat ./go.sh | ssh joey@hostname sudo /bin/sh - # Variation of the above.- git archive HEAD | bzip2 | arx tmpx -rm0 - -e ./build-script.py > go.sh+ # Variation of the above.+ git archive HEAD | bzip2 | arx tmpx -rm0 - -e ./build-script.py > go.sh - # Bundle an instance of an application with DB credentials and run it.- arx tmpx -rm! ./app.tbz ./stage-info.tgz // rake start | ssh ...+ # Bundle an instance of an application with DB credentials and run it.+ arx tmpx -rm! ./app.tbz ./stage-info.tgz // rake start | ssh ... - # Get dump of linking info for build that works here but not there.- arx tmpx ./server-build.tgz LD_DEBUG=files // ./bin/start | ssh ...+ # Get dump of linking info for build that works here but not there.+ arx tmpx ./server-build.tgz LD_DEBUG=files // ./bin/start | ssh ... - # Test out Cabal source distribution of this package:- arx tmpx // 'cd arx-* && cabal configure && cabal build' // \- -rm0 ./dist/arx-0.0.0.tar.gz | sh+ # Test out Cabal source distribution of this package:+ arx tmpx // 'cd arx-* && cabal configure && cabal build' // \+ -rm0 ./dist/arx-0.0.0.tar.gz | sh PASSING ARGUMENTS TO GENERATED SCRIPTS The scripts generated by tmpx treat some arguments as special, internal- options, to allow for inspecting them should there be a need to deter-+ options, to allow for inspecting them should there be a need to deter- mine their contents. --extract@@ -169,28 +175,28 @@ porary directory. --no-run- Unpack into a temporary directory as normal but do not run+ Unpack into a temporary directory as normal but do not run the user's command. - To prevent arguments from being specially treated, use // in the argu-+ To prevent arguments from being specially treated, use // in the argu- ment list: - a-tmpx-script.sh --no-rm // a b c --extract+ a-tmpx-script.sh --no-rm // a b c --extract In the above example, --extract will be passed to the inner command, in the same way as a, b, c. The following example causes ab, c and --no-rm to be printed one after another, each on their own line. - arx tmpx // printf "'%s\n'" '"$@"' | sh -s // ab c --no-rm+ arx tmpx // printf "'%s\n'" '"$@"' | sh -s // ab c --no-rm NOTES- The timestamp is not the common ISO 8601 format, %Y-%m-%dT%H:%M:%SZ,- because of software and build processes that attach special meaning to+ The timestamp is not the common ISO 8601 format, %Y-%m-%dT%H:%M:%SZ,+ because of software and build processes that attach special meaning to colons in pathnames. BUGS- The command line parser offers no hints or help of any kind; it fails- with the simple message "argument error". The two most common mistakes+ The command line parser offers no hints or help of any kind; it fails+ with the simple message "argument error". The two most common mistakes I make are: o Not qualifying paths with /, ./ or ../.
System/Posix/ARX/CLI.hs view
@@ -43,11 +43,11 @@ let apply i = interpret (SHDAT size) <$> inIOStream i mapM_ ((send out =<<) . apply) ins Right (Right tmpxArgs) -> do- let (size, out, tars, env, (rm0, rm1), cmd) = tmpxResolve tmpxArgs+ let (sz, out, tars, env, (rm0, rm1), shared, cmd) = tmpxResolve tmpxArgs case tmpxCheckStreams tars cmd of Nothing -> return () Just msg -> do die msg cmd' <- openByteSource cmd- let tmpx = TMPX (SHDAT size) cmd' env rm0 rm1+ let tmpx = TMPX (SHDAT sz) cmd' env rm0 rm1 shared (badAr, goodAr) <- partitionEithers <$> mapM openArchive tars (badAr /= []) `when` do (((die .) .) . blockMessage) "The file magic of some archives:"@@ -86,15 +86,18 @@ {-| Apply defaulting and overrides appropriate to 'TMPX' programs. -} tmpxResolve :: ( [Word], [IOStream], [IOStream],- [(Var, Val)], [(Bool, Bool)], [ByteSource] )+ [(Var, Val)], [(Bool, Bool)], [Bool],+ [ByteSource] ) -> ( Word, IOStream, [IOStream],- [(Var, Val)], (Bool, Bool), ByteSource )-tmpxResolve (sizes, outs, tars, env, rms, cmds) =- (size, out, tars, env, rm, cmd)+ [(Var, Val)], (Bool, Bool), Bool,+ ByteSource )+tmpxResolve (sizes, outs, tars, env, rms, shareds, cmds) =+ (size, out, tars, env, rm, shared, cmd) where size = last (defaultBlock:sizes) out = last (STDIO:outs) rm = last ((True,True):rms)+ shared = last (False:shareds) cmd = last (defaultTask:cmds) tmpxCheckStreams :: [IOStream] -> ByteSource -> Maybe ByteString@@ -108,13 +111,13 @@ | cmd == IOStream STDIO = One "as a command input" | otherwise = Zero -tmpxOpen :: Word -> [(Var, Val)] -> (Bool, Bool) -> ByteSource -> IO TMPX-tmpxOpen size env (rm0, rm1) cmd = do+tmpxOpen :: Word -> [(Var, Val)] -> (Bool, Bool, Bool) -> ByteSource -> IO TMPX+tmpxOpen size env (rm0, rm1, rm2) cmd = do text <- case cmd of ByteString b -> return (LazyB.fromChunks [b]) IOStream STDIO -> LazyB.getContents IOStream (Path b) -> LazyB.readFile (Char8.unpack b)- return (TMPX (SHDAT size) text env rm0 rm1)+ return (TMPX (SHDAT size) text env rm0 rm1 rm2) openByteSource :: ByteSource -> IO LazyB.ByteString
System/Posix/ARX/CLI/Options.hs view
@@ -39,7 +39,7 @@ f _ stuff = stuff tmpx :: ArgsParser ( [Word], [IOStream], [IOStream], [(Sh.Var, Sh.Val)],- [(Bool, Bool)], [ByteSource] )+ [(Bool, Bool)], [Bool], [ByteSource] ) tmpx = do arg "tmpx" bars <- (try . lookAhead) slashes@@ -47,35 +47,39 @@ Nothing -> flags eof Just bars -> do let eof_bars = () <$ arg bars <|> eof before <- flags eof_bars- cmd <- _6 (gather eof_bars)+ cmd <- _7 (gather eof_bars) after <- flags eof return (before ++ (cmd:after)) where flags = manyTill flag gather = (ByteString . Char8.unwords <$>) . manyTill anyArg flag = _1 blockSize <|> _2 outputFile <|> _3 ioStream- <|> _4 env <|> _5 rm <|> _6 scriptToRun- _1 = ((,Nothing,Nothing,Nothing,Nothing,Nothing) . Just <$>)- _2 = ((Nothing,,Nothing,Nothing,Nothing,Nothing) . Just <$>)- _3 = ((Nothing,Nothing,,Nothing,Nothing,Nothing) . Just <$>)- _4 = ((Nothing,Nothing,Nothing,,Nothing,Nothing) . Just <$>)- _5 = ((Nothing,Nothing,Nothing,Nothing,,Nothing) . Just <$>)- _6 = ((Nothing,Nothing,Nothing,Nothing,Nothing,) . Just <$>)- coalesce = foldr f ([], [], [], [], [], [])+ <|> _4 env <|> _5 rm <|> _6 shared+ <|> _7 scriptToRun+ _1 = ((,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing) . Just <$>)+ _2 = ((Nothing,,Nothing,Nothing,Nothing,Nothing,Nothing) . Just <$>)+ _3 = ((Nothing,Nothing,,Nothing,Nothing,Nothing,Nothing) . Just <$>)+ _4 = ((Nothing,Nothing,Nothing,,Nothing,Nothing,Nothing) . Just <$>)+ _5 = ((Nothing,Nothing,Nothing,Nothing,,Nothing,Nothing) . Just <$>)+ _6 = ((Nothing,Nothing,Nothing,Nothing,Nothing,,Nothing) . Just <$>)+ _7 = ((Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,) . Just <$>)+ coalesce = foldr f ([], [], [], [], [], [], []) where- f (Just a, _, _, _, _, _) (as, bs, cs, ds, es, fs)- = (a:as, bs, cs, ds, es, fs)- f (_, Just b, _, _, _, _) (as, bs, cs, ds, es, fs)- = (as, b:bs, cs, ds, es, fs)- f (_, _, Just c, _, _, _) (as, bs, cs, ds, es, fs)- = (as, bs, c:cs, ds, es, fs)- f (_, _, _, Just d, _, _) (as, bs, cs, ds, es, fs)- = (as, bs, cs, d:ds, es, fs)- f (_, _, _, _, Just e, _) (as, bs, cs, ds, es, fs)- = (as, bs, cs, ds, e:es, fs)- f (_, _, _, _, _, Just f) (as, bs, cs, ds, es, fs)- = (as, bs, cs, ds, es, f:fs)- f _ stuff = stuff+ f (Just a, _, _, _, _, _, _) (as, bs, cs, ds, es, fs, gs)+ = (a:as, bs, cs, ds, es, fs, gs)+ f (_, Just b, _, _, _, _, _) (as, bs, cs, ds, es, fs, gs)+ = (as, b:bs, cs, ds, es, fs, gs)+ f (_, _, Just c, _, _, _, _) (as, bs, cs, ds, es, fs, gs)+ = (as, bs, c:cs, ds, es, fs, gs)+ f (_, _, _, Just d, _, _, _) (as, bs, cs, ds, es, fs, gs)+ = (as, bs, cs, d:ds, es, fs, gs)+ f (_, _, _, _, Just e, _, _) (as, bs, cs, ds, es, fs, gs)+ = (as, bs, cs, ds, e:es, fs, gs)+ f (_, _, _, _, _, Just f, _) (as, bs, cs, ds, es, fs, gs)+ = (as, bs, cs, ds, es, f:fs, gs)+ f (_, _, _, _, _, _, Just g) (as, bs, cs, ds, es, fs, gs)+ = (as, bs, cs, ds, es, fs, g:gs)+ f _ stuff = stuff blockSize :: ArgsParser Word blockSize = do arg "-b"@@ -90,6 +94,10 @@ qPath :: ArgsParser ByteString qPath = tokCL QualifiedPath++shared :: ArgsParser Bool+shared = True <$ arg "--shared"+ rm :: ArgsParser (Bool, Bool) rm = (True, False) <$ arg "-rm0" <|> (False, True) <$ arg "-rm1"
System/Posix/ARX/Programs.hs view
@@ -59,9 +59,10 @@ [(Sh.Var, Sh.Val)] -- Environment mapping. Bool -- Destroy tmp if task runs successfully. Bool -- Destroy tmp if task exits with an error code.+ Bool -- Reuse tmp dir if available. instance ARX TMPX [(Tar, LazyB.ByteString)] where- interpret (TMPX encoder run env rm0 rm1) stuff = TMPXTools.render- (TMPXTools.Template rm0 rm1 env' run' archives)+ interpret (TMPX encoder run env rm0 rm1 rm2) stuff = TMPXTools.render+ (TMPXTools.Template rm0 rm1 rm2 env' run' archives) where archives = mconcat (uncurry archive <$> stuff) archive tar bytes = mconcat
System/Posix/ARX/TMPXTools.hs view
@@ -7,29 +7,35 @@ import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as Bytes+import Data.Char import Data.List import Data.Maybe import Data.Monoid+import Numeric + import qualified Blaze.ByteString.Builder as Blaze import Data.FileEmbed+import Data.Hashable -data Template = Template { rm0 :: Bool, {-^ Remove tmp on run success? -}- rm1 :: Bool, {-^ Remove tmp on run error? -}- env :: Blaze.Builder, {-^ Stream for env text. -}- run :: Blaze.Builder, {-^ Stream for run text. -}- dat :: Blaze.Builder {-^ Data unpacking text. -} }+data Template = Template { rm0 :: Bool, {-^ Remove tmp on run success? -}+ rm1 :: Bool, {-^ Remove tmp on run error? -}+ shared :: Bool, {-^ Share directory across runs? -}+ env :: Blaze.Builder, {-^ Stream for env text. -}+ run :: Blaze.Builder, {-^ Stream for run text. -}+ dat :: Blaze.Builder {-^ Data text. -} } instance Show Template where show Template{..} =- "Template { rm0=" ++ tf rm0 ++ " rm1=" ++ tf rm1 ++ " ... }"+ "Template { rm0=" ++ tf rm0 ++ " rm1=" ++ tf rm1 +++ " shared=" ++ tf shared ++ " ... }" where tf True = "true" tf False = "false" render :: Template -> Blaze.Builder render Template{..} = mconcat [ blaze a,- flags, + flags, blaze b, env, blaze c,@@ -38,7 +44,13 @@ dat, blaze e ] where- flags = mconcat ["rm0=",tf rm0," ; ","rm1=",tf rm1,"\n"]+ flags = mconcat [ "rm0=", tf rm0, " ; ",+ "rm1=", tf rm1, " ; ",+ "shared=", tf shared, " ; ",+ "hash=", (hexStr . hash) dat, "\n" ]+ hash = abs . Data.Hashable.hash . Blaze.toByteString+ hexStr = blaze . Bytes.pack . hex+ hex i = Numeric.showIntAtBase 16 Data.Char.intToDigit i "" blaze = Blaze.fromByteString tf True = "true" tf False = "false"
arx.cabal view
@@ -1,5 +1,5 @@ name : arx-version : 0.2.2+version : 0.2.3 category : Text license : BSD3 license-file : LICENSE@@ -77,6 +77,7 @@ , process >= 1.0 , shell-escape >= 0.1.1 , template-haskell+ , hashable exposed-modules : System.Posix.ARX System.Posix.ARX.CLI System.Posix.ARX.CLI.CLTokens@@ -111,6 +112,7 @@ , process >= 1.0 , shell-escape >= 0.1.1 , template-haskell+ , hashable extensions : FlexibleInstances FunctionalDependencies MultiParamTypeClasses
docs/blessed/arx.man view
@@ -1,4 +1,6 @@-.TH "ARX" "1" "2012-11-20" "0.2.0" "arx"+.\" Man page generated from reStructuredText.+.+.TH "ARX" "1" "%F" "0.2.2" "arx" .SH NAME arx \- archived execution .@@ -28,9 +30,9 @@ .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u ..-.\" Man page generated from reStructuredText.-. .SH SYNOPSIS+.INDENT 0.0+.INDENT 3.5 .sp .nf .ft C@@ -41,6 +43,8 @@ arx tmpx <option,archive>* (//+ <command> (//+ <option,archive>*)?)? .ft P .fi+.UNINDENT+.UNINDENT .SH DESCRIPTION .sp A UNIX executable is a simple thing \-\- a file the kernel can execute, one way@@ -58,10 +62,10 @@ .SH DEPENDENCIES .sp The \fIarx\fP tool relies on the presence of \fIsed\fP, \fItr\fP, \fIdate\fP, \fIhead\fP, \fItar\fP,-\fIhexdump\fP and \fIsh\fP. When unpacking tar archives, it may use the \fI\-j\fP or \fI\-z\fP-(\fIbzip2\fP and \fIgzip\fP, respectively) options of \fItar\fP. Scripts have been tested+\fIhexdump\fP and \fIsh\fP\&. When unpacking tar archives, it may use the \fI\-j\fP or \fI\-z\fP+(\fIbzip2\fP and \fIgzip\fP, respectively) options of \fItar\fP\&. Scripts have been tested with \fIdash\fP and the GNU tools as well as the \fIsh\fP implementation and userland-tools that are part of \fIbusybox\fP.+tools that are part of \fIbusybox\fP\&. .SH APPLICATION .sp The \fItmpx\fP subcommand of \fIarx\fP offers a variety of options for bundling code@@ -72,24 +76,32 @@ Scripts generated by \fItmpx\fP and \fIshdat\fP may be fed to \fIsh\fP over \fISTDIN\fP to execute them. This can be helpful when using \fIssh\fP and \fIsudo\fP to set up an execution context; for example:+.INDENT 0.0+.INDENT 3.5 .sp .nf .ft C arx tmpx ... | ssh user@host.com sudo sh .ft P .fi+.UNINDENT+.UNINDENT .sp Scripts generated by \fItmpx\fP will pass their arguments to the contained script or command. To pass arguments when piping to \fIsh\fP, use \fI\-s\fP:+.INDENT 0.0+.INDENT 3.5 .sp .nf .ft C arx tmpx ... | ssh user@host.com sudo sh \-s a b c .ft P .fi+.UNINDENT+.UNINDENT .sp Some arguments to the generated script will be treated specially, namely,-\fB\-\-extract\fP, \fB\-\-no\-rm\fP and \fB\-\-no\-run\fP. Please see the section on Passing+\fB\-\-extract\fP, \fB\-\-no\-rm\fP and \fB\-\-no\-run\fP\&. Please see the section on Passing Arguments, below, for more information about these options. .SH ARX COMMANDLINE PROCESSING .sp@@ -99,7 +111,7 @@ displayed and the program exits. .sp When paths are specified on an \fBarx\fP command line, they must be qualified,-starting with \fB/\fP, \fB./\fP or \fB../\fP. This simplifies the command line+starting with \fB/\fP, \fB\&./\fP or \fB\&../\fP\&. This simplifies the command line syntax, overall, without introducing troublesome ambiguities. .SH TMPX .sp@@ -115,7 +127,7 @@ bundled. .sp The temporary directory created by the script is different for each-invocation, with a name of the form \fB/tmp/tmpx\-<timestamp>\-<randomhex>\fP. The+invocation, with a name of the form \fB/tmp/tmpx\-<timestamp>\-<randomhex>\fP\&. The timestamp format is %Y.%m.%dT%H.%M.%SZ, in UTC. One happy consequence of this is that earlier jobs sort ASCIIbetically before later jobs. After execution, the temporary directory is removed (or not, depending on the \fB\-rm[10!_]\fP@@ -130,6 +142,12 @@ to be generated that deletes the temporary directory only on success, only on failure, always (the default) or never. .TP+.B \fB\-\-shared\fP+Causes the temporary directory to be identified by a hash of the ARX+archive, instead of by date and time. Different runs of the same archive+will share the same directory. Note that this implies shared state and+every disadvantage thereof.+.TP .B \fB\-b <size>\fP Please see the documentation for this option, shared with \fIshdat\fP, below. .TP@@ -151,6 +169,8 @@ Without \fB\-e\fP, the \fItmpx\fP subcommand tries to find the task to be run as a sequence of arguments delimited by a run of slashes. The following forms are all recognized:+.INDENT 0.0+.INDENT 3.5 .sp .nf .ft C@@ -159,6 +179,8 @@ arx tmpx // ...command... // ...some args... .ft P .fi+.UNINDENT+.UNINDENT .sp The slash runs must have the same number of slashes and must be the longest continuous runs of slashes on the command line. The command will be included@@ -192,6 +214,8 @@ .UNINDENT .UNINDENT .SH EXAMPLES+.INDENT 0.0+.INDENT 3.5 .sp .nf .ft C@@ -214,6 +238,8 @@ \-rm0 ./dist/arx\-0.0.0.tar.gz | sh .ft P .fi+.UNINDENT+.UNINDENT .SH PASSING ARGUMENTS TO GENERATED SCRIPTS .sp The scripts generated by \fItmpx\fP treat some arguments as special, internal@@ -239,22 +265,30 @@ .sp To prevent arguments from being specially treated, use \fB//\fP in the argument list:+.INDENT 0.0+.INDENT 3.5 .sp .nf .ft C a\-tmpx\-script.sh \-\-no\-rm // a b c \-\-extract .ft P .fi+.UNINDENT+.UNINDENT .sp In the above example, \fB\-\-extract\fP will be passed to the inner command, in-the same way as \fBa\fP, \fBb\fP, \fBc\fP. The following example causes \fBab\fP,+the same way as \fBa\fP, \fBb\fP, \fBc\fP\&. The following example causes \fBab\fP, \fBc\fP and \fB\-\-no\-rm\fP to be printed one after another, each on their own line.+.INDENT 0.0+.INDENT 3.5 .sp .nf .ft C arx tmpx // printf "\(aq%s\en\(aq" \(aq"$@"\(aq | sh \-s // ab c \-\-no\-rm .ft P .fi+.UNINDENT+.UNINDENT .SH NOTES .sp The timestamp is not the common ISO 8601 format, %Y\-%m\-%dT%H:%M:%SZ, because@@ -266,7 +300,7 @@ simple message "argument error". The two most common mistakes I make are: .INDENT 0.0 .IP \(bu 2-Not qualifying paths with \fB/\fP, \fB./\fP or \fB../\fP.+Not qualifying paths with \fB/\fP, \fB\&./\fP or \fB\&../\fP\&. .IP \(bu 2 Not specifying a subcommand (\fItmpx\fP or \fIshdat\fP). .UNINDENT
docs/blessed/arx.txt view
@@ -1,9 +1,9 @@ SYNOPSIS- arx (-h | -[?] | --help)- arx (-v | --version)- arx shdat (-b <size>)? (-o <output file>)? < input- arx shdat (-b <size>)? (-o <output file>)? <input file>+- arx tmpx <option,archive>* (//+ <command> (//+ <option,archive>*)?)?+ arx (-h | -[?] | --help)+ arx (-v | --version)+ arx shdat (-b <size>)? (-o <output file>)? < input+ arx shdat (-b <size>)? (-o <output file>)? <input file>++ arx tmpx <option,archive>* (//+ <command> (//+ <option,archive>*)?)? DESCRIPTION A UNIX executable is a simple thing -- a file the kernel can execute,@@ -38,12 +38,12 @@ cute them. This can be helpful when using ssh and sudo to set up an execution context; for example: - arx tmpx ... | ssh user@host.com sudo sh+ arx tmpx ... | ssh user@host.com sudo sh Scripts generated by tmpx will pass their arguments to the contained script or command. To pass arguments when piping to sh, use -s: - arx tmpx ... | ssh user@host.com sudo sh -s a b c+ arx tmpx ... | ssh user@host.com sudo sh -s a b c Some arguments to the generated script will be treated specially, namely, --extract, --no-rm and --no-run. Please see the section on@@ -85,80 +85,86 @@ temporary directory only on success, only on failure, always (the default) or never. + --shared+ Causes the temporary directory to be identified by a hash of+ the ARX archive, instead of by date and time. Different runs+ of the same archive will share the same directory. Note that+ this implies shared state and every disadvantage thereof.+ -b <size>- Please see the documentation for this option, shared with+ Please see the documentation for this option, shared with shdat, below. -o <path>- By default, the generated script is sent to STDOUT. With -o,+ By default, the generated script is sent to STDOUT. With -o, output is redirected to the given path. -e <path>- Causes the file specified to be packaged as the task to be- run. A binary executable, a Ruby script or a longish shell+ Causes the file specified to be packaged as the task to be+ run. A binary executable, a Ruby script or a longish shell script all fit here. - In addition to these options, arguments of the form VAR=VALUE are rec-- ognized as environment mappings and stored away in the script, to be+ In addition to these options, arguments of the form VAR=VALUE are rec-+ ognized as environment mappings and stored away in the script, to be sourced on execution. - Without -e, the tmpx subcommand tries to find the task to be run as a- sequence of arguments delimited by a run of slashes. The following+ Without -e, the tmpx subcommand tries to find the task to be run as a+ sequence of arguments delimited by a run of slashes. The following forms are all recognized: - arx tmpx ...some args... // ...command...- arx tmpx ...some args... // ...command... // ...more args...- arx tmpx // ...command... // ...some args...+ arx tmpx ...some args... // ...command...+ arx tmpx ...some args... // ...command... // ...more args...+ arx tmpx // ...command... // ...some args... - The slash runs must have the same number of slashes and must be the- longest continuous runs of slashes on the command line. The command+ The slash runs must have the same number of slashes and must be the+ longest continuous runs of slashes on the command line. The command will be included as-is in a Bourne shell script. SHDAT- The shdat subcommand translates binary data in to a shell script which- outputs the binary data. The data is encoded in HERE documents in such- a way that data without NULs is not changed and that data with NULs is- minimally expanded: about 1% for randomish data like compressed tar-+ The shdat subcommand translates binary data in to a shell script which+ outputs the binary data. The data is encoded in HERE documents in such+ a way that data without NULs is not changed and that data with NULs is+ minimally expanded: about 1% for randomish data like compressed tar- balls and about 10% in pathological cases. - The shdat subcommand can be given any number of paths, which will be+ The shdat subcommand can be given any number of paths, which will be concatenated in the order given. If no path is given, or if - is given, then STDIN will be read. -b <size>- The size of data chunks to place in each HERE document. The- argument is a positive integer followed by suffixes like B,- K, KiB, M and MiB, in the manner of dd, head and many other- tools. The default is 4MiB. This is unlikely to make a dif-+ The size of data chunks to place in each HERE document. The+ argument is a positive integer followed by suffixes like B,+ K, KiB, M and MiB, in the manner of dd, head and many other+ tools. The default is 4MiB. This is unlikely to make a dif- ference for you unless the generated script is intended to be run on a memory-constrained system. -o <path>- By default, the generated script is sent to STDOUT. With -o,+ By default, the generated script is sent to STDOUT. With -o, output is redirected to the given path. EXAMPLES- # Installer script that preserves failed builds.- git archive HEAD | bzip2 | arx tmpx -rm0 - // make install > go.sh- # Now install as root; but don't log in as root.- cat ./go.sh | ssh joey@hostname sudo /bin/sh+ # Installer script that preserves failed builds.+ git archive HEAD | bzip2 | arx tmpx -rm0 - // make install > go.sh+ # Now install as root; but don't log in as root.+ cat ./go.sh | ssh joey@hostname sudo /bin/sh - # Variation of the above.- git archive HEAD | bzip2 | arx tmpx -rm0 - -e ./build-script.py > go.sh+ # Variation of the above.+ git archive HEAD | bzip2 | arx tmpx -rm0 - -e ./build-script.py > go.sh - # Bundle an instance of an application with DB credentials and run it.- arx tmpx -rm! ./app.tbz ./stage-info.tgz // rake start | ssh ...+ # Bundle an instance of an application with DB credentials and run it.+ arx tmpx -rm! ./app.tbz ./stage-info.tgz // rake start | ssh ... - # Get dump of linking info for build that works here but not there.- arx tmpx ./server-build.tgz LD_DEBUG=files // ./bin/start | ssh ...+ # Get dump of linking info for build that works here but not there.+ arx tmpx ./server-build.tgz LD_DEBUG=files // ./bin/start | ssh ... - # Test out Cabal source distribution of this package:- arx tmpx // 'cd arx-* && cabal configure && cabal build' // \- -rm0 ./dist/arx-0.0.0.tar.gz | sh+ # Test out Cabal source distribution of this package:+ arx tmpx // 'cd arx-* && cabal configure && cabal build' // \+ -rm0 ./dist/arx-0.0.0.tar.gz | sh PASSING ARGUMENTS TO GENERATED SCRIPTS The scripts generated by tmpx treat some arguments as special, internal- options, to allow for inspecting them should there be a need to deter-+ options, to allow for inspecting them should there be a need to deter- mine their contents. --extract@@ -169,28 +175,28 @@ porary directory. --no-run- Unpack into a temporary directory as normal but do not run+ Unpack into a temporary directory as normal but do not run the user's command. - To prevent arguments from being specially treated, use // in the argu-+ To prevent arguments from being specially treated, use // in the argu- ment list: - a-tmpx-script.sh --no-rm // a b c --extract+ a-tmpx-script.sh --no-rm // a b c --extract In the above example, --extract will be passed to the inner command, in the same way as a, b, c. The following example causes ab, c and --no-rm to be printed one after another, each on their own line. - arx tmpx // printf "'%s\n'" '"$@"' | sh -s // ab c --no-rm+ arx tmpx // printf "'%s\n'" '"$@"' | sh -s // ab c --no-rm NOTES- The timestamp is not the common ISO 8601 format, %Y-%m-%dT%H:%M:%SZ,- because of software and build processes that attach special meaning to+ The timestamp is not the common ISO 8601 format, %Y-%m-%dT%H:%M:%SZ,+ because of software and build processes that attach special meaning to colons in pathnames. BUGS- The command line parser offers no hints or help of any kind; it fails- with the simple message "argument error". The two most common mistakes+ The command line parser offers no hints or help of any kind; it fails+ with the simple message "argument error". The two most common mistakes I make are: o Not qualifying paths with /, ./ or ../.
model-scripts/tmpx.sh view
@@ -2,8 +2,8 @@ set -e -u unset rm_ dir tmp=true ; run=true-rm0=true ; rm1=true # To be set by tool.-token=`date -u +%FT%TZ | tr :- ..`-`hexdump -n4 -e '"%08x"' </dev/urandom`+rm0=true ; rm1=true ; shared=false ; hash="" # To be set by tool.+token=`date -u +%FT%TZ | tr -d :-`-`hexdump -n4 -e '"%08x"' </dev/urandom` opts() { cmd="$1" ; shift n=$#@@ -15,6 +15,7 @@ do arg="$1" ; shift case "$arg!$magic_slash" in+ --shared!false) shared=true ;; --no-rm!false) rm_=false ;; --no-run!false) run=false ;; --extract!false) rm_=false ; tmp=false ; run=false ;;@@ -35,7 +36,13 @@ # Set the trap. if $tmp then- dir=/tmp/tmpx-"$token"+ if $shared+ then+ rm_=false+ dir=/tmp/tmpx-"$hash"+ else+ dir=/tmp/tmpx-"$token"+ fi : ${rm_:=true} if $rm_ then@@ -45,18 +52,24 @@ esac' EXIT trap 'exit 2' HUP INT QUIT BUS SEGV PIPE TERM fi- mkdir "$dir"+ mkdir -p "$dir" cd "$dir" fi # Call the command with the reassembled ARGV, options removed. "$cmd" "$@" } go () {- unpack_env > ./env- unpack_run > ./run ; chmod ug+x ./run- mkdir dat- cd dat- unpack_dat+ [ -f env ] || unpack_env > ./env+ [ -f run ] || unpack_run > ./run+ chmod ug+x ./run+ if [ -d dat ]+ then+ cd dat+ else+ mkdir dat+ cd dat+ unpack_dat+ fi if $run then ( . ../env && ../run "$@" )
version view
@@ -1,1 +1,1 @@-0.2.0-8-g8fdbb1f+0.2.3