Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions dune-project
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(lang dune 1.10)
(lang dune 2.8)
(generate_opam_files true)

(name open)
(version 0.2.2)
(version 0.3.0)
(license MIT)
(source (github smolkaj/ocaml-open))
(authors "Steffen Smolka <[email protected]>")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to add yourself as an author.

Expand All @@ -13,8 +13,20 @@
(name open)
(synopsis "Open files in their default applications")
(depends
(ocaml (>= 4.02.3))
(dune (and :build (>= 1.10)))
(ocaml (>= 4.02.3))
dune
(odoc :with-doc)
)
)

(package
(name open_lwt)
(synopsis "Open files in their default applications")
(depends
(ocaml (>= 4.02.3))
dune
(odoc :with-doc)
)
(depopts
lwt)
)
10 changes: 10 additions & 0 deletions examples/basic/basic_lwt.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
let extensions = ["pdf"; "png"; "svg"];;

List.iter (fun ext ->
Format.printf "attempting to open %s file...%!" ext;
let file = "ocaml logo." ^ ext in
let ok = Lwt_main.run (Open_lwt.in_default_app file) in
if ok then Format.printf "ok.\n%!" else Format.printf "failed.\n%!"
) extensions;;

Format.printf "Done.\n";;
22 changes: 20 additions & 2 deletions examples/basic/dune
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
(executable
(name basic)
(modules basic)
(libraries open unix))

(alias
(name runtest)
(executable
(name basic_lwt)
(modules basic_lwt)
(optional)
(libraries lwt open_lwt unix))

(rule
(alias runtest)
(deps
(:< basic.exe)
"%{workspace_root}/examples/basic/ocaml logo.pdf"
"%{workspace_root}/examples/basic/ocaml logo.png"
"%{workspace_root}/examples/basic/ocaml logo.svg")
(action
(run %{<})))

(rule
(alias runtest)
(enabled_if %{lib-available:lwt})
(deps
(:< basic_lwt.exe)
"%{workspace_root}/examples/basic/ocaml logo.pdf"
"%{workspace_root}/examples/basic/ocaml logo.png"
"%{workspace_root}/examples/basic/ocaml logo.svg")
(action
(run %{<})))
29 changes: 25 additions & 4 deletions examples/graphviz/dune
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
(executable
(name graphviz)
(libraries open core))
(enabled_if (>= %{ocaml_version} 4.14.0))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why do we neee OCaml 4.14 here?

(optional)
(modules graphviz)
(libraries open unix))

(alias
(name graphviz)
(executable
(name graphviz_lwt)
(enabled_if (>= %{ocaml_version} 4.14.0))
(optional)
(modules graphviz_lwt)
(libraries lwt open_lwt unix))

(rule
(alias runtest)
(enabled_if (>= %{ocaml_version} 4.14.0))
(deps
(:< graphviz.exe)
%{workspace_root}/examples/graphviz/unix.dot)
"%{workspace_root}/examples/graphviz/unix.dot")
(action
(run %{<})))

(rule
(alias runtest)
(enabled_if (and (>= %{ocaml_version} 4.14.0)
%{lib-available:lwt}))
(deps
(:< graphviz_lwt.exe)
"%{workspace_root}/examples/graphviz/unix.dot")
(action
(run %{<})))
24 changes: 13 additions & 11 deletions examples/graphviz/graphviz.ml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
open Core

let compile_dot ?(format="pdf") ?(engine="dot") ?(title=engine) data : string =
let output_file = Filename.temp_file title ("." ^ format) in
let cmd = sprintf "dot -T%s -o %s" format output_file in
Printf.printf "Compiling dot file...\n";
let output_file = Filename.temp_file ~temp_dir:"." title ("." ^ format) in
let cmd = Format.sprintf "dot -T%s -o %s" format output_file in
let dot_process = Unix.open_process_out cmd in
Out_channel.output_string dot_process data;
Out_channel.close dot_process;
Printf.fprintf dot_process "%s" data;
ignore (Unix.close_process_out dot_process);
Printf.printf "Output saved to %s...\n" output_file;
output_file
;;

In_channel.read_all "unix.dot"
|> compile_dot
|> Open.in_default_app
|> Format.printf "file opened successfully: %b\n"
;;
let _ =
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: let ()

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the let version

Printf.printf "Running graphviz test...\n";
In_channel.open_text "unix.dot"
|> In_channel.input_all (* requires ocaml 4.14.0 *)
|> compile_dot
|> Open.in_default_app
|> Printf.printf "file opened successfully: %b\n"

20 changes: 20 additions & 0 deletions examples/graphviz/graphviz_lwt.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

let compile_dot ?(format="pdf") ?(engine="dot") ?(title=engine) data : string =
Printf.printf "Compiling dot file...\n";
let output_file = Filename.temp_file ~temp_dir:"." title ("." ^ format) in
let cmd = Format.sprintf "dot -T%s -o %s" format output_file in
let dot_process = Unix.open_process_out cmd in
Printf.fprintf dot_process "%s" data;
ignore (Unix.close_process_out dot_process);
Printf.printf "Output saved to %s...\n" output_file;
output_file

let _ =
Printf.printf "Running graphviz test...\n";
In_channel.open_text "unix.dot"
|> In_channel.input_all (* requires ocaml 4.14.0 *)
|> compile_dot
|> Open_lwt.in_default_app
|> Lwt_main.run
|> Printf.printf "file opened successfully: %b\n"

32 changes: 20 additions & 12 deletions open.opam
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
build: [
["dune" "subst"] {pinned}
["dune" "build" "-p" name "-j" jobs]
["dune" "runtest" "-p" name "-j" jobs] {with-test}
["dune" "build" "-p" name "@doc"] {with-doc}
]
version: "0.3.0"
synopsis: "Open files in their default applications"
maintainer: ["Steffen Smolka <[email protected]>"]
authors: ["Steffen Smolka <[email protected]>"]
bug-reports: "https://github.com/smolkaj/ocaml-open/issues"
license: "MIT"
homepage: "https://github.com/smolkaj/ocaml-open"
doc: "https://smolkaj.github.io/ocaml-open/"
license: "MIT"
version: "0.2.2"
dev-repo: "git+https://github.com/smolkaj/ocaml-open.git"
synopsis: "Open files in their default applications"
bug-reports: "https://github.com/smolkaj/ocaml-open/issues"
depends: [
"ocaml" {>= "4.02.3"}
"dune" {build & >= "1.10"}
"dune" {>= "2.8"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/smolkaj/ocaml-open.git"
31 changes: 31 additions & 0 deletions open_lwt.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
version: "0.3.0"
synopsis: "Open files in their default applications"
maintainer: ["Steffen Smolka <[email protected]>"]
authors: ["Steffen Smolka <[email protected]>"]
license: "MIT"
homepage: "https://github.com/smolkaj/ocaml-open"
doc: "https://smolkaj.github.io/ocaml-open/"
bug-reports: "https://github.com/smolkaj/ocaml-open/issues"
depends: [
"ocaml" {>= "4.02.3"}
"dune" {>= "2.8"}
"odoc" {with-doc}
]
depopts: ["lwt"]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/smolkaj/ocaml-open.git"
23 changes: 23 additions & 0 deletions src/base.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
type os =
| MacOS
| Linux
| Windows
| Cygwin

let detect_os () : os =
if Sys.win32 then Windows else
if Sys.cygwin then Cygwin else
let in_ch,_,_ as uname = Unix.open_process_full "uname" [||] in
let os = input_line in_ch in
ignore (Unix.close_process_full uname);
match os with
| "Darwin" -> MacOS
| "Linux" -> Linux
| _ -> failwith "unknown operating system"

let open_cmd os =
match os with
| MacOS -> "open"
| Linux -> "xdg-open"
| Windows -> "start"
| Cygwin -> "cygstart"
9 changes: 9 additions & 0 deletions src/base.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type os =
| MacOS
| Linux
| Windows
| Cygwin

val detect_os : unit -> os

val open_cmd : os -> string
21 changes: 20 additions & 1 deletion src/dune
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
(library
(name open_base)
(wrapped false)
(package open) ;; require dune 2.8, allows library to be private
(modules
base)
)

(library
(name open)
(public_name open)
(wrapped false)
(libraries unix))
(modules
open)
(libraries unix open_base))

(library
(name open_lwt)
(public_name open_lwt)
(wrapped false)
(optional)
(modules
open_lwt)
(libraries unix lwt.unix open_base))
35 changes: 6 additions & 29 deletions src/open.ml
Original file line number Diff line number Diff line change
@@ -1,36 +1,13 @@
type os =
| MacOS
| Linux
| Windows
| Cygwin

let detect_os () : os =
if Sys.win32 then Windows else
if Sys.cygwin then Cygwin else
let in_ch,_,_ as uname = Unix.open_process_full "uname" [||] in
let os = input_line in_ch in
ignore (Unix.close_process_full uname);
match os with
| "Darwin" -> MacOS
| "Linux" -> Linux
| _ -> failwith "unknown operating system"

let open_cmd os =
match os with
| MacOS -> "open"
| Linux -> "xdg-open"
| Windows -> "start"
| Cygwin -> "cygstart"

let silence os =
match os with
| MacOS | Linux | Cygwin-> "> /dev/null 2>&1"
| Windows -> "> nul 2>&1"
let in_default_app_status file : Unix.process_status =
let os = Base.detect_os () in
(Filename.quote_command (Base.open_cmd os) [file])
|> Unix.open_process_out
|> Unix.close_process_out

let in_default_app file : bool =
let os = detect_os () in
Format.sprintf "%s %S %s" (open_cmd os) file (silence os)
|> Unix.system
in_default_app_status file
|> function
| Unix.WEXITED 0 -> true
| _ -> false
5 changes: 5 additions & 0 deletions src/open.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
Returns [true] if the open command exits normally, or [false] otherwise.
*)
val in_default_app : string -> bool

(** Same as above, but returns process status instead.
*)
val in_default_app_status : string -> Unix.process_status

11 changes: 11 additions & 0 deletions src/open_lwt.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: remove empty line.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the other new files

let in_default_app_status file : Unix.process_status Lwt.t =
let os = Base.detect_os () in
let cmd = Filename.quote_command (Base.open_cmd os) [file] in
Lwt_process.exec ~stdout:(`Dev_null) (Lwt_process.shell cmd)

let in_default_app file : bool Lwt.t =
Lwt.bind (in_default_app_status file)
(function
| Unix.WEXITED 0 -> Lwt.return true
| _ -> Lwt.return false)
9 changes: 9 additions & 0 deletions src/open_lwt.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

(** Opens the given file in the default app associated with the file's type.
Returns [true] if the open command exits normally, or [false] otherwise.
*)
val in_default_app : string -> bool Lwt.t

(** Same as above, but returns process status instead.
*)
val in_default_app_status : string -> Unix.process_status Lwt.t