Skip to content

Improve functions to run commands #389

@Anton-4

Description

@Anton-4

The currently provided functions in Cmd don't result in the cleanest code. See the improvement in this diff where I added my own helper functions:

 main! : List Arg => Result {} _
 main! = |_args|
 
-    # get cwd to check if we are in the www dir
-    pwd_cmd_output =
-        Cmd.new("pwd")
-        |> Cmd.output!()
-
-    when pwd_cmd_output.status is
-        Ok(0) ->
-            pwd_bytes = pwd_cmd_output.stdout
-            
-            if !(List.ends_with(pwd_bytes, [119, 119, 119])) then
-                pwd_str = Str.from_utf8(pwd_bytes)?
-                Stderr.line!("You must run this script inside the 'www' directory, I am currently in: ${pwd_str}")?
-            else
-                {}
-        _ ->
-            Err(CommandPWDFailed(Inspect.to_str(pwd_cmd_output)))?
+    pwd_stdout_str = run_cmd_w_output!("pwd", [])?
+    if !(Str.ends_with(pwd_stdout_str, "/www")) then
+        Stderr.line!("You must run this script inside the 'www' directory, I am currently in: ${pwd_stdout_str}")?
+    else
+        {}
 
     # Clean up dirs from previous runs
     _ = Dir.delete_all!("build")
     _ = Dir.delete_all!("content/examples")
     _ = Dir.delete_all!("examples-main")
 
-    Cmd.exec!("cp", ["-r", "public", "build"]) ? |err| CopyPublicToBuildFailed(err)
-
+    run_cmd!("cp", ["-r", "content", "build"])?
 
     # Download latest examples
-    Cmd.exec!("curl", ["-fL", "-o", "examples-main.zip", "https://github.com/roc-lang/examples/archive/refs/heads/main.zip"]) ? |err| CurlDowloadExamplesRepoFailed(err)
-    
-    Cmd.exec!("unzip", ["-o", "-q", "examples-main.zip"]) ? |err| UnzipExamplesRepoFailed(err)
+    run_cmd!("curl", ["-fL", "-o", "examples-main.zip", "https://github.com/roc-lang/examples/archive/refs/heads/main.zip"])?
 
-    Cmd.exec!("cp", ["-R", "examples-main/examples/", "content/examples/"]) ? |err| CopyExamplesToContentFailed(err)
+    run_cmd!("unzip", ["-o", "-q", "examples-main.zip"])?
+
+    run_cmd!("cp", ["-R", "examples-main/examples/", "content/examples/"])?
 
     # replace links in content/examples/index.md to work on the WIP site
     # TODO do this in Roc
-    Cmd.exec!("perl", ["-pi", "-e", "s|\\]\\(/|\\]\\(/examples/|g", "content/examples/index.md"]) ? |err| PerlReplaceFailed(err)
+    run_cmd!("perl", ["-pi", "-e", "s|\\]\\(/|\\]\\(/examples/|g", "content/examples/index.md"])?
 
     Dir.delete_all!("examples-main") ? |err| DeleteExamplesMainDirFailed(err)
     File.delete!("examples-main.zip") ? |err| DeleteExamplesMainZipFailed(err)
@@ -55,11 +43,11 @@ main! = |_args|
     design_assets_tarfile = "roc-lang-design-assets-4d94964.tar.gz"
     design_assets_dir = "roc-lang-design-assets-4d94964"
 
-    Cmd.exec!("curl", ["-fLJO", "https://github.com/roc-lang/design-assets/tarball/${design_assets_commit}"]) ? |err| CurlDownloadDesignAssetsFailed(err)
+    run_cmd!("curl", ["-fLJO", "https://github.com/roc-lang/design-assets/tarball/${design_assets_commit}"])?
 
-    Cmd.exec!("tar", ["-xzf", design_assets_tarfile]) ? |err| TarExtractDesignAssetsFailed(err)
+    run_cmd!("tar", ["-xzf", design_assets_tarfile])?
 
-    Cmd.exec!("mv", ["${design_assets_dir}/fonts", "build/fonts"]) ? |err| MoveFontsToBuildFailed(err)
+    run_cmd!("mv", ["${design_assets_dir}/fonts", "build/fonts"])?
 
     # clean up
     Dir.delete_all!(design_assets_dir) ? |err| DeleteDesignAssetsDirFailed(err)
@@ -69,26 +57,30 @@ main! = |_args|
     repl_tarfile = "roc_repl_wasm.tar.gz"
 
     # Download the latest stable Web REPL as a zip file.
-    Cmd.exec!("curl", ["-fLJO", "https://github.com/roc-lang/roc/releases/download/alpha3-rolling/${repl_tarfile}"]) ? |err| CurlDownloadReplFailed(err)
-    
+    run_cmd!("curl", ["-fLJO", "https://github.com/roc-lang/roc/releases/download/alpha3-rolling/${repl_tarfile}"])?
+
     Dir.create!("build/repl") ? |err| CreateReplDirFailed(err)
 
-    Cmd.exec!("tar", ["-xzf", repl_tarfile, "-C", "build/repl"]) ? |err| TarExtractReplFailed(err)
+    run_cmd!("tar", ["-xzf", repl_tarfile, "-C", "build/repl"])?
 
     File.delete!(repl_tarfile) ? |err| DeleteReplTarFailed(err)
 
     # TODO generate docs for alpha3 instead of main branch
-    Cmd.exec!("roc", ["docs", "--output", "build/builtins", "--root-dir", "builtins"]) ? |err| RocGenDocsBuiltinsFailed(err)
+    run_cmd!("roc", ["docs", "--output", "build/builtins", "--root-dir", "builtins"])?
 
+    find_index_stdout = run_cmd_w_output!("find", ["www/build/builtins", "-type", "f", "-name", "index.html"])?
+    clean_paths = Str.split_on(find_index_stdout, "\n")
 
-    # Manually add this tip to all the builtin docs.
-    Cmd.exec!("find", ["www/build/builtins", "-type", "f", "-name", "index.html", "-exec", "sed", "-i", "'s!</nav>!<div class=\"builtins-tip\"><b>Tip:</b> <a href=\"/different-names\">Some names</a> differ from other languages.</div></nav>!'", "{}"]) ? |err| SedAddTipToBuiltinsDocsFailed(err)
+    List.for_each_try!(
+        clean_paths,
+        |path|
+            File.write_utf8!(path, Str.replace_each(File.read_utf8!(path)?, "</nav>", """<div class="builtins-tip"><b>Tip:</b> <a href="/different-names">Some names</a> differ from other languages.</div></nav>"""))
+    ) ? |err| WriteBuiltinsDocsReplaceFailed(err)
 
 
     # Generating site markdown content
-    Cmd.exec!("roc", ["build", "--linker", "legacy", "www/main.roc"]) ? |err| RocBuildStaticSiteMainFailed(err)
-    
-    Cmd.exec!("roc", ["www/main.roc", "www/content/", "www/build/"]) ? |err| RocRunStaticSiteMainFailed(err)
+    run_cmd!("roc", ["build", "--linker", "legacy", "www/main.roc"])?
+    run_cmd!("roc", ["www/main.roc", "www/content/", "www/build/"])?
 
 
     # Add github link to examples
@@ -102,29 +94,52 @@ main! = |_args|
         </svg>
         """
 
-    find_readme_html_output =
-        Cmd.new("find")
-        |> Cmd.args([examples_dir, "-type", "f", "-name", "README.html", "-exec", "realpath", "{}", ";"])
-        |> Cmd.output!()
+    find_readme_html_output = run_cmd_w_output!("find", [examples_dir, "-type", "f", "-name", "README.html", "-exec", "realpath", "{}", ";"])?
 
-    when find_readme_html_output.status is
-        Ok(0) ->
-            find_stdout = Str.from_utf8(find_readme_html_output.stdout)?
-            clean_readme_paths = Str.split_on(find_stdout, "\n")
-            # TODO check output as expected
+    clean_readme_paths = Str.split_on(find_readme_html_output, "\n")
+    # TODO check output as expected
 
-            List.for_each_try!(
-                clean_readme_paths,
-                |readme_path|
-                    readme_html_str = File.read_utf8!(readme_path)?
+    List.for_each_try!(
+        clean_readme_paths,
+        |readme_path|
+            readme_html_str = File.read_utf8!(readme_path)?
 
-                    example_folder_name = Str.split_on(readme_path, "/") |> List.take_last(2) |> List.first()?
-                    specific_example_link = Str.join_with([examples_repo_link, example_folder_name], "/")
-                    readme_str_edited = Str.replace_each(readme_html_str, "</h1>", """</h1><a id="gh-example-link" href="${specific_example_link}" aria-label="view on github">${github_logo_svg}</a>""")
+            example_folder_name = Str.split_on(readme_path, "/") |> List.take_last(2) |> List.first()?
+            specific_example_link = Str.join_with([examples_repo_link, example_folder_name], "/")
+            readme_str_edited = Str.replace_each(readme_html_str, "</h1>", """</h1><a id="gh-example-link" href="${specific_example_link}" aria-label="view on github">${github_logo_svg}</a>""")
 
-                    File.write_utf8!(readme_path, readme_str_edited)
-            )?
-        _ ->
-            Err(FindExamplesReadmeHtmlFailed(Inspect.to_str(find_readme_html_output)))?
+            File.write_utf8!(readme_path, readme_str_edited)
 
-    Stdout.line!("Website built in dir 'www/build'.")
\ No newline at end of file
+    ) ? |err| ExamplesReadmeReplaceFailed(err)
+
+    Stdout.line!("Website built in dir 'www/build'.")
+
+run_cmd! : Str, List Str => Result {} [BadCmdOutput(Str)]_
+run_cmd! = |cmd_str, args|
+    _ = run_cmd_w_output!(cmd_str, args)?
+
+    Ok({})
+
+run_cmd_w_output! : Str, List Str => Result Str [BadCmdOutput(Str)]_
+run_cmd_w_output! = |cmd_str, args|
+    cmd_out =
+        Cmd.new(cmd_str)
+        |> Cmd.args(args)
+        |> Cmd.output!()
+
+    stdout_utf8 = Str.from_utf8_lossy(cmd_out.stdout)
+
+    when cmd_out.status is
+        Ok(0) ->
+            Ok(stdout_utf8)
+        _ ->
+            stderr_utf8 = Str.from_utf8_lossy(cmd_out.stderr)
+            err_data =
+                """
+                Cmd ${cmd_str} ${Str.join_with(args, " ")} failed:
+                - status: ${Inspect.to_str(cmd_out.status)}
+                - stdout: ${stdout_utf8}
+                - stderr: ${stderr_utf8}
+                """
+
+            Err(BadCmdOutput(err_data))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions