open-browser 0.4.0.0 → 0.5.1.0
raw patch · 10 files changed
Files
- CHANGELOG.md +10/−0
- example/Main.hs +7/−11
- lib/Web/Browser.hs +12/−17
- lib/unix-like/open/Web/Browser/OS.hs +12/−6
- lib/unix-like/xdg-open/Web/Browser/OS.hs +12/−6
- lib/unsupported-os/Web/Browser/OS.hs +5/−7
- lib/windows/Web/Browser/OS.hs +15/−13
- open-browser.cabal +79/−81
- stack.yaml +0/−1
- stack.yaml.lock +0/−12
CHANGELOG.md view
@@ -6,6 +6,16 @@ and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/). +## 0.5.1.0 - 2026-07-02 + +* Fix a regression on unsupported operating systems. + +## 0.5.0.0 - 2026-06-22 + +* Fix a regression on Linux operating systems, whereby `xdg-open` would not + return until the browser was closed. +* Replace utility `openBrowserWithExitCode` with `openBrowserWithException`. + ## 0.4.0.0 - 2025-04-02 * On Unix-like operating systems, use Haskell to silence the opening
example/Main.hs view
@@ -5,8 +5,7 @@ ) where import Control.Exception ( Exception (..), SomeException ) -import System.Exit ( ExitCode (..) ) -import Web.Browser ( openBrowser, openBrowserWithExitCode ) +import Web.Browser ( openBrowser, openBrowserWithException ) main :: IO () main = do @@ -21,14 +20,11 @@ putStrLn "Try a bad URL:" tryOpenBadUrl >>= reportResult where - tryOpenGoodUrl :: IO (Either SomeException (ExitCode, String, String)) - tryOpenGoodUrl = openBrowserWithExitCode "https://haskell.org/" - tryOpenBadUrl :: IO (Either SomeException (ExitCode, String, String)) - tryOpenBadUrl = openBrowserWithExitCode "example-bad-url" + tryOpenGoodUrl :: IO (Maybe SomeException) + tryOpenGoodUrl = openBrowserWithException "https://haskell.org/" + tryOpenBadUrl :: IO (Maybe SomeException) + tryOpenBadUrl = openBrowserWithException "example-bad-url" reportResult = \case - Left e -> putStrLn $ "Exception: " <> displayException e - Right (ec, out, err) -> do - putStrLn $ "Exit code: " <> show ec - putStrLn $ "Standard output: " <> out - putStrLn $ "Standard error: " <> err + Just e -> putStrLn $ "Exception: " <> displayException e + Nothing -> putStrLn "Nothing to report" blankLine = putStrLn ""
lib/Web/Browser.hs view
@@ -14,11 +14,11 @@ module Web.Browser ( openBrowser -- * Utilities - , openBrowserWithExitCode + , openBrowserWithException ) where import Control.Exception ( Exception (..), SomeException, try) -import System.Exit ( ExitCode (..) ) +import Data.Maybe ( isNothing ) import qualified Web.Browser.OS as OS -- | Seeks to open the given item, silently. If the item is a URL or another @@ -47,23 +47,18 @@ String -- ^ URL or other item to try to open. -> IO Bool -openBrowser url = tryOpenUrl >>= \case - Left _ -> pure False - Right (ec, _, _) -> pure $ ec == ExitSuccess - where - tryOpenUrl :: IO (Either SomeException (ExitCode, String, String)) - tryOpenUrl = openBrowserWithExitCode url +openBrowser url = + isNothing <$> (openBrowserWithException url :: IO (Maybe SomeException)) --- | Exported to help with debugging. As for 'openBrowser' but returns either an --- exception or, as a triple, the 'ExitCode' of the opening mechanism and any --- output to the standard output and standard error channels. On failure, the --- meaning of the exit code will depend on the operating system; for unsupported --- operating systems, it will be 'ExitFailure' @1@. +-- | Exported to help with debugging. As for 'openBrowser' but returns 'Nothing' +-- or 'Just' an exception. -- --- @since 0.4.0.0 -openBrowserWithExitCode :: +-- @since 0.5.0.0 +openBrowserWithException :: Exception e => String -- ^ URL or other item to try to open. - -> IO (Either e (ExitCode, String, String)) -openBrowserWithExitCode url = try $ OS.openBrowserWithExitCode url + -> IO (Maybe e) +openBrowserWithException url = try (OS.openBrowser url) >>= \case + Left e -> pure $ Just e + Right () -> pure Nothing
lib/unix-like/open/Web/Browser/OS.hs view
@@ -4,15 +4,21 @@ -------------------------------------------------------------------------------- module Web.Browser.OS - ( openBrowserWithExitCode + ( openBrowser ) where -import System.Exit ( ExitCode (..) ) -import System.Process ( readProcessWithExitCode ) +import Control.Monad ( void ) +import System.Process + ( CreateProcess (..), StdStream (..), createProcess, proc ) -- https://ss64.com/mac/open.html -openBrowserWithExitCode :: +openBrowser :: String -- ^ URL or other item to try to open. - -> IO (ExitCode, String, String) -openBrowserWithExitCode url = readProcessWithExitCode "open" [url] "" + -> IO () +openBrowser url = void $ createProcess (proc "open" [url]) + { std_in = NoStream + , std_out = NoStream + , std_err = NoStream + , close_fds = True + }
lib/unix-like/xdg-open/Web/Browser/OS.hs view
@@ -3,15 +3,21 @@ -------------------------------------------------------------------------------- module Web.Browser.OS - ( openBrowserWithExitCode + ( openBrowser ) where -import System.Exit ( ExitCode (..) ) -import System.Process ( readProcessWithExitCode ) +import Control.Monad ( void ) +import System.Process + ( CreateProcess (..), StdStream (..), createProcess, proc ) -- https://ss64.com/bash/xdg-open.html -openBrowserWithExitCode :: +openBrowser :: String -- ^ URL or other item to try to open. - -> IO (ExitCode, String, String) -openBrowserWithExitCode url = readProcessWithExitCode "xdg-open" [url] "" + -> IO () +openBrowser url = void $ createProcess (proc "xdg-open" [url]) + { std_in = NoStream + , std_out = NoStream + , std_err = NoStream + , close_fds = True + }
lib/unsupported-os/Web/Browser/OS.hs view
@@ -3,15 +3,13 @@ -------------------------------------------------------------------------------- module Web.Browser.OS - ( openBrowserWithExitCode + ( openBrowser ) where -import System.Exit ( ExitCode (..) ) - -openBrowserWithExitCode :: +openBrowser :: String -- ^ URL or other item to try to open. - -> IO (ExitCode, String, String) -openBrowserWithExitCode = + -> IO () +openBrowser _ = -- Operation never succeeds - const (pure (ExitFailure 1, "", "Unsupported operating system.")) + error "openBrowser: Unsupported operating system."
lib/windows/Web/Browser/OS.hs view
@@ -8,12 +8,14 @@ -------------------------------------------------------------------------------- module Web.Browser.OS - ( openBrowserWithExitCode + ( openBrowser ) where -import System.Exit ( ExitCode (..) ) -import System.Win32.Types - ( HANDLE, HINSTANCE, INT, LPCWSTR, handleToWord, nullPtr, withTString ) +import Control.Monad ( unless ) +import System.Win32.Types + ( HANDLE, HINSTANCE, INT, LPCWSTR, handleToWord, nullPtr + , withTString + ) type HWND = HANDLE @@ -25,18 +27,18 @@ sW_SHOWNORMAL :: INT sW_SHOWNORMAL = 1 -openBrowserWithExitCode :: +openBrowser :: String -- ^ URL or other item to try to open. - -> IO (ExitCode, String, String) -openBrowserWithExitCode url = - withTString "open" $ \openStr -> - withTString url $ \urlStr -> exitcodeToExitCode <$> + -> IO () +openBrowser url = do + hinst <- withTString "open" $ \openStr -> + withTString url $ \urlStr -> c_ShellExecute nullPtr openStr urlStr nullPtr nullPtr sW_SHOWNORMAL - where - exitcodeToExitCode hinst = - let exitcode = fromIntegral $ handleToWord hinst - in (if exitcode > 32 then ExitSuccess else ExitFailure exitcode, "", "") + let exitcode = fromIntegral (handleToWord hinst) :: Int + unless (exitcode > 32) $ error $ + "openBrowser: ShellExecuteW \"open\" failed with exit code: " + <> show exitcode -- https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew foreign import ccall unsafe "windows.h ShellExecuteW"
open-browser.cabal view
@@ -1,82 +1,80 @@ cabal-version: 1.12 ---- This file has been generated from package.yaml by hpack version 0.38.0.------ see: https://github.com/sol/hpack--name: open-browser-version: 0.4.0.0-synopsis: Open a web browser from Haskell-description: Open a web browser from Haskell. Windows, macOS, Linux and BSD are supported.-category: Web-homepage: https://github.com/mpilgrem/open-browser-bug-reports: https://github.com/mpilgrem/open-browser/issues-author: rightfold-maintainer: public@pilgrem.com-license: BSD3-license-file: LICENSE-build-type: Simple-tested-with:- GHC >= 8.4-extra-source-files:- CHANGELOG.md- README.md- stack.yaml- stack.yaml.lock--source-repository head- type: git- location: https://github.com/mpilgrem/open-browser--flag example- description: Build the example application- manual: True- default: False--library- hs-source-dirs:- lib- exposed-modules:- Web.Browser- build-depends:- base ==4.*- default-language: Haskell2010- if os(windows)- other-modules:- Web.Browser.OS- hs-source-dirs:- lib/windows- build-depends:- Win32 <3- else- if os(darwin)- other-modules:- Web.Browser.OS- hs-source-dirs:- lib/unix-like/open- build-depends:- process >=1.2.0.0 && <2- else- if os(linux) || os(freebsd) || os(openbsd) || os(netbsd)- other-modules:- Web.Browser.OS- hs-source-dirs:- lib/unix-like/xdg-open- build-depends:- process >=1.2.0.0 && <2- else- other-modules:- Web.Browser.OS- hs-source-dirs:- lib/unsupported-os--executable open-browser-example- main-is: Main.hs- hs-source-dirs:- example- build-depends:- base ==4.*- , open-browser- default-language: Haskell2010- if !flag(example)- buildable: False+ +-- This file has been generated from package.yaml by hpack version 0.39.6. +-- +-- see: https://github.com/sol/hpack + +name: open-browser +version: 0.5.1.0 +synopsis: Open a web browser from Haskell +description: Open a web browser from Haskell. Windows, macOS, Linux and BSD are supported. +category: Web +homepage: https://github.com/mpilgrem/open-browser +bug-reports: https://github.com/mpilgrem/open-browser/issues +author: rightfold +maintainer: public@pilgrem.com +license: BSD3 +license-file: LICENSE +build-type: Simple +tested-with: + GHC >= 8.4 +extra-source-files: + CHANGELOG.md + README.md + +source-repository head + type: git + location: https://github.com/mpilgrem/open-browser + +flag example + description: Build the example application + manual: True + default: False + +library + hs-source-dirs: + lib + exposed-modules: + Web.Browser + build-depends: + base ==4.* + default-language: Haskell2010 + if os(windows) + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/windows + build-depends: + Win32 <3 + else + if os(darwin) + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/unix-like/open + build-depends: + process >=1.2.0.0 && <2 + else + if os(linux) || os(freebsd) || os(openbsd) || os(netbsd) + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/unix-like/xdg-open + build-depends: + process >=1.2.0.0 && <2 + else + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/unsupported-os + +executable open-browser-example + main-is: Main.hs + hs-source-dirs: + example + build-depends: + base ==4.* + , open-browser + default-language: Haskell2010 + if !flag(example) + buildable: False
− stack.yaml
@@ -1,1 +0,0 @@-snapshot: lts-23.17 # GHC 9.8.4
− stack.yaml.lock
@@ -1,12 +0,0 @@-# This file was autogenerated by Stack.-# You should not edit this file by hand.-# For more information, please see the documentation at:-# https://docs.haskellstack.org/en/stable/topics/lock_files--packages: []-snapshots:-- completed:- sha256: 2763632e4c4094ce12f5ae12b22f524cdc6453b6b19007ff164a37fd9d2ea829- size: 683819- url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/17.yaml- original: lts-23.17