Giter Site home page Giter Site logo

fli's Introduction

Hello there ๐Ÿ‘‹

  • ๐Ÿ’ป Iโ€™m currently working on small F# projects in my spare time:
  • ๐Ÿšง Maintainer of FsUnit & NHamcrest
  • โšก Fun fact: I like ๐Ÿง€ and ๐Ÿฅ‘'s a lot.
  • ๐Ÿฅ“ Eating my own dog food.
  • ๐Ÿ’ช Weight lifting
  • ๐Ÿช™ Numismatist

fli's People

Contributors

captncodr avatar mrboring avatar xgqt avatar yanikceulemans avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fli's Issues

BASH pipe

BASH does not accept pipes so:

seq { "test.txt" }
|> Seq.iter (fun file ->
    cli {
        Shell BASH
        Command $"{file} | echo"
        WorkingDirectory __SOURCE_DIRECTORY__
    }
    |> Command.execute
    |> Output.printText)

Does nothing.

add output to stream of lines (seq string) ?

would be useful to process the output as stream, like less or more commands, so as a stream of lines, and to have control to interrupt or modify the behaviour of code based on content

e.g.

dotnet test |> break if containing 'Exception' so it will stop at the first error in tests instead of running the full suite

`Command.executeAsync` does not await output

First of all, I would like to say thanks for creating this library. It has been super useful for me.

When using the Command.executeAsync function, it seems like the output of the command is not awaited.

Running the example program:

open Fli

let mainAsync = async {
    let! output =
        cli {
            Shell PWSH
            Command "echo test"
        }
        |> Command.executeAsync
    output |> Output.toExitCode |> printfn "exit code: %d"
    output |> Output.toError |> printfn "stderr: %s"
    output |> Output.toText |> printfn "stdout: %s"
}

[<EntryPoint>]
let main argv =
    async {
        do! Async.SwitchToThreadPool ()
        return! mainAsync
    }
    |> Async.RunSynchronously

    0

results in the following output:

exit code: 0
stderr:     
stdout: 

Running the same program with Command.execute instead, gives the expected output:

exit code: 0
stderr: 
stdout: test

I have tested using both .NET 7 and .NET 6 with the same results.

Furthermore, it seems like the tests for the executeAsync function don't actually test anything because they do not await the result.
For example, the following test in src/Fli.Tests/ShellContext/ShellCommandExecuteTests.fs:

[<Test>]
let ``Hello World with BASH async`` () =
    if OperatingSystem.IsWindows() |> not then
        async {
            let! output =
                cli {
                    Shell BASH
                    Command "echo Hello World!"
                }
                |> Command.executeAsync

            // output |> Output.toText |> should equal "Hello World!"
            should equal 2 1
        }
        |> Async.Start
    else
        Assert.Pass()

The use of Async.Start just starts the async computation but does not await its results, leading to the test immediately passing

Running this updated test using the command: dotnet test --filter 'BASH&async' will report a passing test like so:

Microsoft (R) Test Execution Command Line Tool Version 17.7.0-preview-23364-03+bc17bb9693cfc4778ded51aa0ab7f1065433f989 (x64)
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

Passed!  - Failed:     0, Passed:     1, Skipped:     0, Total:     1, Duration: 64 ms - Fli.Tests.dll (net7.0)

Some additional perhaps useful diagnostic information.
OS: Windows 10
dotnet version: 7.0.400
Fli version: 1.10.0

Please let me know if you need any additional information.

FSharp.Core, Version=7.0.0.0

I currently have a deployment with the following .NET SDKs available:

dotnet --list-sdks
3.1.404
5.0.403
6.0.400

When running a Fli test with version 1.0.0 and 0.11.0, I get the following error:

Unhandled exception. System.IO.FileLoadException: Could not load file or assembly 'FSharp.Core, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
The located assembly's manifest definition does not match the assembly reference. (0x80131040)
File name: 'FSharp.Core, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

Can the FSharp.Core version be set to greater than or equal to 6 in the paket.dependencies file so .NET 6 can be used?

nuget FSharp.Core >= 6

Thanks

How would I open an HTML page in the default browser?

Hi I'm trying to open an HTML file in the default browser.

cli {
    Exec @"<full path to HTML file>"
}
|> Command.execute

The above gives me the following exception:

System.ComponentModel.Win32Exception (193): An error occurred trying to start process 'C:\Data\FSharp\Projects\AudioUtilities\DO NOT COMMIT\Script Files\Find Audio Issues\Untitled-1.html' with working directory 'C:\Data\FSharp\Projects\AudioUtilities'. The specified executable is not a valid application for this OS platform.
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Fli.Command.startProcess(FSharpFunc`2 inputFunc, FSharpFunc`2 outputFunc, ProcessStartInfo psi) in C:\Users\const\github\repos\Fli\src\Fli\Command.fs:line 87
   at Fli.Command.Command.execute(ExecContext context) in C:\Users\const\github\repos\Fli\src\Fli\Command.fs:line 223
   at <StartupCode$FSI_0024>.$FSI_0024.main@()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)        
Stopped due to error

I searched for The specified executable is not a valid application for this OS platform and found the following (old ) Stack Overflow page:

.Net Core 2.0 Process.Start throws "The specified executable is not a valid application for this OS platform"

It suggests setting UseShellExecute = true. How would I do this with Fli, or is there a better way?

Thanks.

Implement Zero value for computation expression.

Would it be possible to implement the Zero value for the cli computation expression? This is needed for letting other values be added conditionally.

In my current process, I'm trying to add the output logging if the user specifies a log file. and it would allow the following to happen

cli {
    Command "command"
    Arguments ["arg1"; "arg2"]
    
    if logPath.isSome then
        Output logPath.Value
}

Apps are not displayed when run as admin

Hi

I'm trying to launch Image for Windows. This is a Windows application. It launches and I can see it in Task Manager, but the window is not visible.

I'm running VS Code elevated as the application requires admin rights.

I'm using the following code inside an fsx file:

#r "nuget: Fli, 1.101.0"

open System
open System.IO
open Fli

cli {
        Exec @"C:\Program Files (x86)\TeraByte Drive Image Backup and Restore Suite\imagew64.exe"
        WorkingDirectory @"C:\Program Files (x86)\TeraByte Drive Image Backup and Restore Suite"
}
|> Command.execute

I tried the above with and without the WorkingDirectory line. I also tried running the fsx file from the command line:

dotnet fsi '.\Image For Windows Runner.fsx'

If I run the follwing from an elevated PowerShell prompt, it works fine:

& "C:\Program Files (x86)\TeraByte Drive Image Backup and Restore Suite\imagew64.exe"

I also tried Disk2Vhd which also requires elevation. Same results, I can see it in task manager, but the window is not visible. Running it from PowerShell works:

& "C:\Users\<removed>\AppData\Local\Microsoft\WindowsApps\disk2vhd.exe"

Can't use custom func as output

Trying to use a custom function in Output I am getting the following exception:

 System.Exception: Cannot convert output type.
         at Fli.CE.ICommandContext`1.outputTypeMapping[a,a](ICommandContext`1 _, a output)
         at Fli.CE.ICommandContext`1.Output[a,a](ICommandContext`1 this, ICommandContext`1 context, a output)

My command:

    let! output =
                    cli {
                        Shell BASH
                        Command (opts.Value.Path)
                        WorkingDirectory(opts.Value.WorkingDir)
                        Output (Custom(Func<string,unit>(fun s -> ctx.GetLogger().LogInformation("log: {Message}", s) )
                        ))
                    }
                    |> Command.executeAsync
                    |> Async.StartAsTask

Cannot pass data on stdin to a program with Exec

Hi,

I testing your library for scripting purposes, and I found a small bug. In short, you can't pass data on stdin to a command (at least on Linux and Mac OS X where I tried it).

I have a PR to fix the bug and increase test coverage for Linux and Mac OS X which I'll raise in relation to this issue.

Reproduction

Running the following through dotnet fsi results in the exception below. I would've expected it to be equivalent to echo "foo" | cat.

#r "nuget: Fli"

open Fli

cli {
    Exec "cat"
    Input "foo"
}
|> Command.execute
System.InvalidOperationException: StandardIn has not been redirected.
   at System.Diagnostics.Process.get_StandardInput()
   at Fli.Command.writeInput$cont@167(FSharpOption`1 input, FSharpOption`1 encoding, Process p, Unit unitVar) in D:\github\repos\Fli\src\Fli\Command.fs:line 168
   at Fli.Command.writeInput(FSharpOption`1 input, FSharpOption`1 encoding, Process p) in D:\github\repos\Fli\src\Fli\Command.fs:line 165
   at [email protected](Process p)
   at Fli.Command.startProcess(FSharpFunc`2 inputFunc, FSharpFunc`2 outputFunc, ProcessStartInfo psi) in D:\github\repos\Fli\src\Fli\Command.fs:line 110
   at Fli.Command.Command.execute(ExecContext context) in D:\github\repos\Fli\src\Fli\Command.fs:line 282
   at <StartupCode$FSI_0002>.$FSI_0002.main@() in /tmp/tmp.QVPGcNRmGK/bug.fsx:line 6
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Standard error support

Most commands will provide useful information in stderr in case they return non-zero exit code. Some commands may also break if the parent process isn't reading the stderr.

Thus, I believe it would be useful to provide access to stderr in Fli.

BASH issue

I'm converting a bash script to an F# script to fix a problem with regex in the bash script. But after the regex runs, I need to run more code.

I'm trying to run code like shown below, but it's not doing anything, and it doesn't output anything. I have confirmed that pwd returns the expected current directory. When I run the same command in a bash script, it works as expected.

// 3. Fetch all the new/modified files into the delivery folder.
list_of_files
|> Seq.iter (fun filePath -> 
    cli {
        Shell BASH
        Command $"git show HEAD:{filePath} | install -D /dev/stdin {delivery_folder}/{repo_name}/{branch_name}/{filePath}"
    }
    |> Command.execute
    |> ignore

    Console.WriteLine $"Downloaded {filePath}"
)

The original bash script looked like this:

IFS="
"
for filename in $list_of_files; do
    trimmed_filename=$(echo ${filename} | xargs)
    git show HEAD:${trimmed_filename} | install -D /dev/stdin ${delivery_folder}/${repo_name}/${branch_name}/${trimmed_filename}
    echo \'${trimmed_filename}\'
done

Standard input support

In some cases, a command requires the caller to provide something in the stdin (consider an example of a program feeding a stream of shell commands to the shell line-by-line).

For such cases, something like this could be useful:

cli {
    Shell CMD
    input "echo 123\necho 345"
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.