πŸ¦€πŸ›  Rustaceans have been hard at work [rewriting classic unix tools for the modern age](https://zaiste.net/posts/shell-commands-rust/). With its static type system and committment to creating zero-cost abstractions, rust is a great tool for publishing command line apps~ Now Scala can too! We'll be looking at reimplimenting a gnu util [`csplit`]([https://man7.org/linux/man-pages/man1/csplit.1.html](https://man7.org/linux/man-pages/man1/csplit.1.html)) in Scala as a project called [`resplit`](https://github.com/AesaKamar/resplit)! You can follow along here with in-code examples, or [head directly to GitHub](https://github.com/AesaKamar/resplit) ## πŸ”§ How do I get Scala to build a binary and ditch my JVM? All you need is a simple `build.sbt` file that looks something like this: <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">1 </span><span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">name</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">:=</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">resplit</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">2 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">3 </span><span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">scalaVersion</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">:=</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;3.2.2&quot;</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">4 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">5 </span><span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// This tells our project</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">6 </span><span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">enablePlugins</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">ScalaNativePlugin</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">7 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">8 </span><span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// defaults set with common options shown</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">9 </span><span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">nativeConfig</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">~=</span> { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">configuration</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">10 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">configuration</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">11 </span> <span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// </span><span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">https://scala-native.org/en/stable/user/sbt.html#garbage-collectors</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">12 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">withLTO</span>(<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scala</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scalanative</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">build</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">LTO</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">none</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">13 </span> <span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// </span><span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">https://scala-native.org/en/stable/user/sbt.html#compilation-modes</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">14 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">withMode</span>(<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scala</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scalanative</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">build</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Mode</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">debug</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">15 </span> <span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// </span><span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">https://scala-native.org/en/stable/user/sbt.html#garbage-collectors</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">16 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">withGC</span>(<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scala</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scalanative</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">build</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">GC</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">commix</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">17 </span>} <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">18 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">19 </span><span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">libraryDependencies</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">++=</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">Seq</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">20 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;co.fs2&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%%%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;fs2-core&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;3.6.1&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">21 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;co.fs2&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%%%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;fs2-io&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;3.6.1&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">22 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;org.typelevel&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%%%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cats-effect&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;3.4.8&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">23 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;org.typelevel&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%%%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cats-core&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;2.9.0&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">24 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;com.github.scopt&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%%%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;scopt&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;4.1.0&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">25 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;com.lihaoyi&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%%%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">pprint</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;0.8.1&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">26 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;org.typelevel&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%%%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;munit-cats-effect&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;2.0.0-M3&quot;</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">Test</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">27 </span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">28 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">29 </span><span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// I often declare and do not use things while developing</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">30 </span><span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">tpolecatExcludeOptions</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">++=</span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">ScalacOptions</span>.<span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">warnUnusedOptions</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">31 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">32 </span><span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// set to Debug for compilation details (Info is default)</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">33 </span><span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">logLevel</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">:=</span> <span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">Level</span>.<span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">Info</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">34 </span> </pre> This `enablePlugins(ScalaNativePlugin` directive will give you access to the `sbt nativeLink` task which will produce a precompiled binary for you! ## πŸ“œπŸͺ“ A program to split large files by a regex #### Given this Input file: ``` cat1 cat2 cat3 dog1 cat4 cat5 cat6 dog2 cat7 cat8 cat9 ``` #### When I run ``` > cat testfile | resplit '(dog)\d' '$1' ``` #### Then I should get these 3 output files `000_` ``` cat1 cat2 cat3 ``` `001_dog` ``` dog1 cat4 cat5 cat6 ``` `002_dog` ``` dog2 cat7 cat8 cat9 ``` Here is a sneak-peek at the final product Streaming "The Adventures of Sherlock Holmes" withΒ `wget`Β and spliting by chapter regex into unique files <img src="https://user-images.githubusercontent.com/4334491/224520721-9500f632-12a6-41f0-859a-d5f84b4d6b01.gif"> ## πŸ§‘β€πŸ’» Making a user-friendly cli ### Our `Main` file This is pretty small, we use `IOApp` from `cats.effect` to let us hook into the `run` method <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">1 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">import</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">cats</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">effect</span>.{<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">ExitCode</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">IO</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">IOApp</span>} <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">2 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">import</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scopt</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">OParser</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">3 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">4 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">object</span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Main</span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">extends</span> <span style="color:rgb(98,197,198);font-weight:normal;font-style:normal;">IOApp</span> { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">5 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">6 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">def</span> <span style="color:rgb(255,198,109);font-weight:normal;font-style:normal;">run</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">List</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span>]): <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">ExitCode</span>] = <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">7 </span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">OParser</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">8 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">parse</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">9 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">parser</span> = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">InputArgs</span>.<span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">commandLineParser</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">10 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span> = <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">11 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">init</span> = <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">12 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">13 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">fold</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">ifEmpty</span> = <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">IO</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">ExitCode</span>.<span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">Error</span>)) { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">parsedInputs</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">14 </span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Resplit</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">15 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">resplit</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span> = <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">parsedInputs</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">16 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">compile</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">17 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">drain</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">18 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">map</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">_</span> =&gt; <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">ExitCode</span>.<span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">Success</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">19 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">20 </span>} </pre> We want to get this nice user-friendly help message... -- but how do we set up all of that without spending all of our time mired in command line parsing? πŸ˜΅β€πŸ’« ```sh > resplit --help Usage: resplit [options] regexToMatch [regexToSub] Splits a file based on a regex. split files will be prefixed by digits, and named by the contents of the matched regular expression. Outputs names of files created to stdout regexToMatch A regular expression to split the file on regexToSub A regular expression substitution expression to use to format the output filenames -n, --digits <value> Number of digits to left-pad the split filenames with -d, --directory <value> Directory to write the split files into -f, --file <value> Read from the specified file instead of stdin --suppressMatched Include the line that matched the regexMatch arg as the first line in the split files -s, --quiet Quiet --help prints this usage text ``` ### `scopt` for command line argument parsing We set up a simple `case class` to hold onto all of the inputs we'd like to "gather" from the user <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">1 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">import</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scopt</span>.{<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">OParser</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">OParserBuilder</span>} <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">2 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">3 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">import</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">java</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">io</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">File</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">4 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">import</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scala</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">util</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">matching</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">Regex</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">5 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">6 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">case</span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">class</span> <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">7 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Regex</span> = <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;&quot;</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">r</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">8 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToSub</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Option</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span>] = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">None</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">9 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">filenamePaddingDigits</span>: <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Int</span> = <span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">3</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">10 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Option</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">File</span>] = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">None</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">11 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">inputFileInsteadOfStdin</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Option</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">File</span>] = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">None</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">12 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">suppressMatched</span>: <span style="color:rgb(204,120,50);background-color:rgb(52,65,52);font-weight:normal;font-style:normal;">Boolean</span> = <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">false,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">13 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">silentMode</span>: <span style="color:rgb(204,120,50);background-color:rgb(52,65,52);font-weight:normal;font-style:normal;">Boolean</span> = <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">false</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">14 </span>) </pre> We use `scopt`'s easy-to-use DSL to specify how to gather all of the arguments, options, and flags <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">16 </span><span style="color:rgb(98,151,85);font-weight:normal;font-style:italic;">/** Use </span><span style="color:rgb(119,183,103);font-weight:normal;font-style:normal;">[[</span><span style="color:rgb(208,218,235);font-weight:normal;font-style:italic;">OParserBuilder</span><span style="color:rgb(119,183,103);font-weight:normal;font-style:normal;">]]</span><span style="color:rgb(98,151,85);font-weight:normal;font-style:italic;"> API to specify how to take input args from the</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">17 </span><span style="color:rgb(98,151,85);font-weight:normal;font-style:italic;"> * command line and make them user friendly</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">18 </span><span style="color:rgb(98,151,85);font-weight:normal;font-style:italic;"> */</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">19 </span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">object</span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">InputArgs</span> { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">20 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">import</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">scala</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">util</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">chaining</span>._ <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">21 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">private</span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">builder</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">OParserBuilder</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span>] = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">OParser</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">builder</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span>] <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">22 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">23 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">commandLineParser</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">OParser</span>[<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Unit,</span> <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span>] = { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">24 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">import</span> <span style="color:rgb(152,118,170);font-weight:normal;font-style:italic;">builder</span>._ <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">25 </span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">OParser</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">sequence</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">26 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">programName</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">resplit</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>)<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">27 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">note</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">28 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;&quot;&quot;Splits input based on a regex. Split files will be prefixed by digits,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">29 </span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;"> |and named by the contents of the matched regular expression.</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">30 </span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;"> |</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">31 </span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;"> |Outputs names of files created to stdout</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">32 </span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;"> |&quot;&quot;&quot;</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">stripMargin</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">33 </span> )<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">34 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">arg</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span>](<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;regexToMatch&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">35 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">required</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">36 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;A regular expression to split the file on &quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">37 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">action</span>((<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>) =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">copy</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span> = <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">r</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">38 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">arg</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Option</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span>]](<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;regexToSub&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">39 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">optional</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">40 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">41 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;A regular expression substitution expression to use to format the output filenames&quot;</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">42 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">43 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">action</span>((<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>) =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">copy</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToSub</span> = <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">44 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">opt</span>[<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Int</span>](<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&#39;n&#39;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;digits&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">45 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">optional</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">46 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;Number of digits to left-pad the split filenames with&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">47 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">validate</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">n</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">48 </span> (<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">n</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">&gt;</span> <span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">0</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">&amp;&amp;</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">n</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">&lt;=</span> <span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">128</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">49 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">pipe</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Either</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">cond</span>(_<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> ()<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;Not a valid number of digits&quot;</span>)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">50 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">51 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">action</span>((<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>) =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">copy</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">filenamePaddingDigits</span> = <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">52 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">opt</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">File</span>](<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&#39;d&#39;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;directory&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">53 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;Directory to write the split files into&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">54 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">optional</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">55 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">action</span>((<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>) =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">copy</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span> = <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Some</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span>)))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">56 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">opt</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">File</span>](<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&#39;f&#39;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;file&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">57 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;Read from the specified file instead of stdin&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">58 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">optional</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">59 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">validate</span>(_.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">isFile</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">pipe</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Either</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">cond</span>(_<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> ()<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;Not a valid file&quot;</span>))) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">60 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">action</span>((<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>) =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">copy</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">inputFileInsteadOfStdin</span> = <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Some</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">arg</span>)))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">61 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">opt</span>[<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Unit</span>](<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;suppressMatched&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">62 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">optional</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">63 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">64 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;Include the line that matched the regexMatch arg as the first line in the split files&quot;</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">65 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">66 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">action</span>((<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">_</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>) =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">copy</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">suppressMatched</span> = <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">true</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">67 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">opt</span>[<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Unit</span>](<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&#39;s&#39;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;quiet&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">68 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">optional</span>() <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">69 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;Quiet&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">70 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">action</span>((<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">_</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>) =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">conf</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">copy</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">silentMode</span> = <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">true</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">71 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">help</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;help&quot;</span>).<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">text</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;prints this usage text&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">72 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">73 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">74 </span>} </pre> We can even use it to bind in a `--help` option πŸ˜‰ ## πŸ“‚ Setting up the filesystem Before we can write to an output directory, we've got to make sure it exists! <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">17 </span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Stream</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">18 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">eval</span>(<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">createDirectoryOrDoNothing</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span>)) </pre> We use `Stream.eval` to run an effect, `IO[SomeType]` into a `Stream[IO, SomeType]` <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">48 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">def</span> <span style="color:rgb(255,198,109);font-weight:normal;font-style:normal;">createDirectoryOrDoNothing</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Option</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">File</span>]): <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>[<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Unit</span>] = <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">49 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">50 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">map</span>(_.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">getPath</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">51 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">map</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Path</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">apply</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">52 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">fold</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">ifEmpty</span> = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">IO</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">unit</span>) { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">dir</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">53 </span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">io</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">file</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">54 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Files</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>] <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">55 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">exists</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">dir</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">56 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">flatMap</span> { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">exists</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">57 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">if</span> (<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">exists</span>) <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">IO</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">unit</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">58 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">else</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">59 </span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">io</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">file</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">60 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Files</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>] <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">61 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">createDirectory</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">dir</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">62 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">63 </span> } </pre> ## πŸ“₯ Streaming the inputs from either `stdin` or a file ### `fs2` stands for streaming We leverage `fs2`'s powerful and succint API for helping us deal with the complexities of streaming data <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">16 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">def</span> <span style="color:rgb(255,198,109);font-weight:normal;font-style:normal;">resplit</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span>): <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Stream</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> (<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Path</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Chunk</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span>])] = <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">17 </span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Stream</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">18 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">eval</span>(<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">createDirectoryOrDoNothing</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span>)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">19 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">productR</span> { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">20 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">inputFileInsteadOfStdin</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">21 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">fold</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">ifEmpty</span> = <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">io</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">stdin</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>](<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">bufSize</span> = <span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">1024</span>)) { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">22 </span> _.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">getPath</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">23 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">pipe</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Path</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">apply</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">24 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">pipe</span>(<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">io</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">file</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Files</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>].<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">readAll</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">25 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">26 </span> } </pre> The `resplit` function will be called by out `Main` class when the cli app is invoked Firstly, it checks the arguments if an inputFile is passed in to use instead of stdin (We've luckily leveraged `scopt` previously to parse it in under the `-f` or `--file` option, so we don't need to specify the details here ☺️) Since both a file stream and `stdin` are bytestreams all the same, we'll need to pipe them `through` 2 more functions to get them into a `Stream[IO, String]` By the way, `productR` is equivalent to `flatMap`, where we discard the argument to the lambda ### More well-typed helper functions <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">24 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">through</span> { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">inputStream</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">25 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">if</span> (<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">suppressMatched</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">26 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">inputStream</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">split</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">thisLine</span> =&gt; <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">matches</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">thisLine</span>)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">27 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">else</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">28 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">splitInclusive</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">inputStream</span>)(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">thisLine</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">29 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">matches</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">thisLine</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">30 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">31 </span> } </pre> We decide if the matched line should be included in the file, or disincluded Here's the spec of how that `splitInclusive` function should behave <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">12 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">test</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;splitInclusive&quot;</span>) { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">13 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">value</span>: <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Stream</span>[<span style="color:rgb(44,143,105);font-weight:normal;font-style:normal;">Pure</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Int</span>] = <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">14 </span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Stream</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">range</span>(<span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">0</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">10</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">15 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">16 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">predicate</span>: <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Int</span> =&gt; <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Boolean</span> = <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">17 </span> _ <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">%</span> <span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">4</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">==</span> <span style="color:rgb(104,151,187);font-weight:normal;font-style:normal;">0</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">18 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">19 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">split</span>: <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Stream</span>[<span style="color:rgb(44,143,105);font-weight:normal;font-style:normal;">Pure</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Chunk</span>[<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Int</span>]] = <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">20 </span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Resplit</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">splitInclusive</span>(<span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">value</span>)(<span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">predicate</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">21 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">22 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">allBeginWithPredicate</span>: <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Boolean</span> = <span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">split</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">23 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">forall</span>(_.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">head</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">forall</span>(<span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">predicate</span>)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">24 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">compile</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">25 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">toList</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">26 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">head</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">27 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">28 </span> <span style="color:rgb(209,207,187);background-color:rgb(52,65,52);font-weight:normal;font-style:normal;">assert</span>(<span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">allBeginWithPredicate</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">29 </span> } </pre> ## πŸ“€ Streaming the outputs to a file ### Pulling the first line out from each file <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">36 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">zipWithIndex</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">37 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">map</span> { (<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">chunkOfLines</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">chunkNumber</span>) =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">38 </span> ( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">39 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">inferPathFromFirstMatchedLineOfChunk</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">chunkOfLines</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">chunkNumber</span>)<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">40 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">chunkOfLines</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">41 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">42 </span> } </pre> Hopefully these strong type signatures and declarative names are mostly self-explanatory! <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">85 </span> <span style="color:rgb(128,128,128);font-weight:normal;font-style:normal;">// </span><span style="color:rgb(192,178,0);font-weight:normal;font-style:italic;">TODO this is technically impure because is has a console printing effect in it</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">86 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">def</span> <span style="color:rgb(255,198,109);font-weight:normal;font-style:normal;">inferPathFromFirstMatchedLineOfChunk</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">87 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">88 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">c</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Chunk</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span>]<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">89 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">i</span>: <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Long</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">90 </span> ): <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Path</span> = { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">91 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">fileContext</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span> = <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">c</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">head</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">92 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">flatMap</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">findFirstIn</span>(_)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">93 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">map</span> { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">matchedChars</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">94 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToSub</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">fold</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">ifEmpty</span> = <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">matchedChars</span>) { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">providedRegexSub</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">95 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">try</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">96 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">matchedChars</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">replaceFirst</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">regex</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">providedRegexSub</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">97 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">catch</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">98 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">case</span> _ =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">99 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">if</span> (<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">!</span><span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">silentMode</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">100 </span> (<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">s</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;invalid regex: on </span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span><span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">matchedChars</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;"> &quot;</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">+</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">101 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">s</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;for </span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span>{<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">regex</span>}<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;"> &quot;</span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">+</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">102 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">s</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;with substitution </span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span><span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">providedRegexSub</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">103 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">pipe</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Console</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">err</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">println</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">104 </span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;&quot;</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">105 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">106 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">107 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">getOrElse</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">108 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">val</span> <span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">iii</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span> = <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">leftPad</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">i</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">toString</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">filenamePaddingDigits</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&#39;0&#39;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">109 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">110 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">fold</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">ifEmpty</span> = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Path</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">apply</span>(<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">s</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span>{<span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">iii</span>}<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">_</span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span><span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">fileContext</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>)) { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">dir</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">111 </span> <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Path</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">apply</span>(<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">s</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span><span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">dir</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">/</span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span>{<span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">iii</span>}<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">_</span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span><span style="color:rgb(124,173,198);font-weight:normal;font-style:normal;">fileContext</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">112 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">113 </span> } </pre> ### Actually writing the file Lastly, here's the function responsible for writing the file, making heavy use of `fs2` <pre style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">44 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">evalTap</span> { (<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">path</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">chunkOfLines</span>) =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">45 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">writeChunkToPathAndPrint</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">chunkOfLines</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">path</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">args</span>.<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">silentMode</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">46 </span> } </pre> <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">65 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">def</span> <span style="color:rgb(255,198,109);font-weight:normal;font-style:normal;">writeChunkToPathAndPrint</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">66 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">c</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Chunk</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">String</span>]<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">67 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">path</span>: <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Path</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">68 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">isSilent</span>: <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Boolean</span> = <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">false</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">69 </span> ): <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>[<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">Unit</span>] = <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">70 </span> <span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Stream</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">71 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">chunk</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">c</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">72 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">intersperse</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">\n</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">73 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">append</span>(<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Stream</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">emit</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">\n</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">74 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">through</span>(<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">text</span>.<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">utf8</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">encode</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">75 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">through</span>(<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">fs2</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">io</span>.<span style="color:rgb(169,183,198);font-weight:normal;font-style:normal;">file</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Files</span>[<span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">IO</span>].<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">writeAll</span>(<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">path</span>)(_)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">76 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">compile</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">77 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">drain</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">78 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">flatTap</span> { <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">_</span> =&gt; <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">79 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">if</span> (<span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">isSilent</span>) <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">IO</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">unit</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">80 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">else</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">IO</span>(<span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Console</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">println</span>(<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">s</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(0,184,187);font-weight:bold;font-style:normal;">lt;/span><span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">path</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">\t</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">81 </span> } </pre> Similarly to how we needed to pipe our input `through` `text.utf8.decode` and `text.lines`, we need to first `intersperse` some newline characters back in and then pipe it `through` `text.utf8.encode` If you've been wondering what `.compile.drain` are doing, that's tjust the way to instruct `fs2` to finalize this stream pipeline to get ready to run as an `IO` effect 🏎 ### Final spec Here is a description of how this `resplit` funciton should behave <pre class="intellij" style="color:rgb(0,0,0);font-weight:normal;font-style:normal;font-family:monospace;"> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">56 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">test</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">resplit</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>) { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">57 </span> <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">for</span> { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">58 </span> <span style="color:rgb(198,148,175);font-weight:normal;font-style:normal;">output</span> &lt;- <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">Resplit</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">59 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">resplit</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">60 </span> <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">InputArgs</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">61 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToMatch</span> = <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(106,135,89);background-color:rgb(54,65,53);font-weight:normal;font-style:normal;">dog</span><span style="color:rgb(232,191,106);background-color:rgb(54,65,53);font-weight:bold;font-style:normal;">\\d</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>.<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">r</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">62 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">regexToSub</span> = <span style="color:rgb(159,198,96);font-weight:normal;font-style:normal;">None</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">63 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">filenamePaddingDigits</span><span style="color:rgb(114,115,122);font-weight:normal;font-style:normal;"> = 3</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">64 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">outputDirectory</span> = <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Some</span>(<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">new</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">File</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;tmp/&quot;</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">65 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">inputFileInsteadOfStdin</span> = <span style="color:rgb(208,218,235);font-weight:normal;font-style:normal;">Some</span>(<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">new</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">File</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">testfile</span><span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">66 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">suppressMatched</span><span style="color:rgb(114,115,122);font-weight:normal;font-style:normal;"> = false</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">67 </span> <span style="color:rgb(136,198,155);font-weight:normal;font-style:normal;">silentMode</span> = <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">true</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">68 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">69 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">70 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">compile</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">71 </span> .<span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">toList</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">72 </span> <span style="color:rgb(198,148,175);font-weight:normal;font-style:normal;">expectedOutput</span> = <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">List</span>( <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">73 </span> (<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Path</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;tmp/000_&quot;</span>)<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Chunk</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat1&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat2&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat3&quot;</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">74 </span> (<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Path</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;tmp/001_dog1&quot;</span>)<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Chunk</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;dog1&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat4&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat5&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat6&quot;</span>))<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">75 </span> (<span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Path</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;tmp/002_dog2&quot;</span>)<span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:italic;">Chunk</span>(<span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;dog2&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat7&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat8&quot;</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(106,135,89);font-weight:normal;font-style:normal;">&quot;cat9&quot;</span>)) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">76 </span> ) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">77 </span> } <span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">yield</span> { <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">78 </span> <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">79 </span> <span style="color:rgb(209,207,187);font-weight:normal;font-style:normal;">assertEquals</span>(<span style="color:rgb(198,148,175);font-weight:normal;font-style:normal;">output</span><span style="color:rgb(204,120,50);font-weight:normal;font-style:normal;">,</span> <span style="color:rgb(198,148,175);font-weight:normal;font-style:normal;">expectedOutput</span>) <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">80 </span> } <span style="color:rgb(96,99,102);font-weight:normal;font-style:normal;">81 </span> } </pre> ## Conclusion Hopefully this has convinced you that using ScalaNative isn't so hard! It affords us the ability to use all the powerful typing and wonderful libraries we know and love in Scala and get the instant startup and small binary sizes on natively compiled applications. Happy CLI hacking! πŸŽ‰