packages feed

open-browser 0.2.1.1 → 0.3.0.0

raw patch · 17 files changed

+247/−143 lines, 17 filesdep ~Win32dep ~processsetup-changedPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: Win32, process

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -6,6 +6,13 @@ and this project adheres to the
 [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
+## 0.3.0.0 - 2025-03-16
+
+* Make operating system-related choices at compilation. The function will never
+  succeed on unsupported operating systems, rather than than throwing an
+  `ErrorCall` exception.
+* Drop support for 32-bit Windows.
+
 ## 0.2.1.1 - 2025-03-15
 
 * Add `CHANGELOG.md` and `README.md`.
LICENSE view
@@ -1,30 +1,30 @@-Copyright (c) 2015, rightfold
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-    * Neither the name of rightfold nor the names of other
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Copyright (c) 2015, rightfold++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of rightfold nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
README.md view
@@ -1,9 +1,9 @@-# open-browser
-
-A Haskell library that provides the function `openBrowser` that, given a URL,
-yields an IO action that seeks to open the URL in the user's preferred web
-browser.
-
-Supported operating systems are Windows, macOS, Linux and BSD.
-
-Originally developed by rightfold.
+# open-browser++A Haskell library that provides the function `openBrowser` that, given a URL,+yields an IO action that seeks to open the URL in the user's preferred web+browser.++Supported operating systems are Windows, macOS, Linux and BSD.++Originally developed by rightfold.
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple
-main = defaultMain
+import Distribution.Simple+main = defaultMain
example/Main.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE LambdaCase #-}
+
 module Main
   ( main
   ) where
@@ -5,4 +7,6 @@ import Web.Browser ( openBrowser )
 
 main :: IO ()
-main = openBrowser "https://haskell.org/" >>= print
+main = openBrowser "https://haskell.org/" >>= \case
+  True -> putStrLn "The operation succeeded!"
+  False -> putStrLn "The operation failed!"
lib/Web/Browser.hs view
@@ -1,30 +1,37 @@-{-# LANGUAGE CPP #-}
+{-|
+Module      : Web.Browser
+Description : Open a web browser from Haskell
+Copyright   : (c) rightfold 2015
+License     : BSD3
+Maintainer  : public@pilgrem.com
 
+Open a web browser from Haskell. Supported operating systems are Windows, macOS,
+Linux and BSD.
+-}
+
 module Web.Browser
   ( openBrowser
   ) where
 
-#if defined(mingw32_HOST_OS)
-import Web.Browser.Windows ( openBrowserWindows )
-#else
-import Data.List ( isInfixOf )
-import System.Info ( os )
-import Web.Browser.Linux ( openBrowserLinux )
-import Web.Browser.OSX ( openBrowserOSX )
-#endif
+import qualified Web.Browser.OS as OS
 
 -- | Seeks to open the given URL in the user's preferred web browser. Returns
--- whether or not the operation succeeded. Throws an 'ErrorCall' exception if
--- the operating system is unsupported.
+-- whether or not the operation succeeded. No checks are performed on the
+-- validity of the given URL.
+--
+-- Implemented using:
+--
+-- * on Windows, the \'open\' operation provided by the Win32 API;
+--
+-- * on macOS, the \'open\' application, if it is on the user's PATH; and
+--
+-- * on Linux, FreeBSD, OpenBSD or NetBSD, the \'xdg-open\' application, if it
+--   is on the user's PATH, via \'sh\' to allow the application's output to be
+--   silenced.
+--
+-- On other operating systems, the operation always fails.
 openBrowser ::
      String
      -- ^ URL
   -> IO Bool
-#if defined(mingw32_HOST_OS)
-openBrowser = openBrowserWindows
-#else
-openBrowser
-  | any (`isInfixOf` os) ["linux", "bsd"] = openBrowserLinux
-  | "darwin" `isInfixOf` os               = openBrowserOSX
-  | otherwise                             = error "unsupported platform"
-#endif
+openBrowser = OS.openBrowser
− lib/Web/Browser/Linux.hs
@@ -1,13 +0,0 @@-module Web.Browser.Linux
-  ( openBrowserLinux
-  ) where
-
-import System.Exit ( ExitCode (..) )
-import System.Process ( rawSystem )
-
-openBrowserLinux :: String -> IO Bool
-openBrowserLinux url = exitCodeToBool `fmap` rawSystem executable argv
- where
-  (executable, argv) = ("sh", ["-c", "xdg-open \"$0\" 2>&1 > /dev/null", url])
-  exitCodeToBool ExitSuccess     = True
-  exitCodeToBool (ExitFailure _) = False
− lib/Web/Browser/OSX.hs
@@ -1,13 +0,0 @@-module Web.Browser.OSX
-  ( openBrowserOSX
-  ) where
-
-import System.Exit ( ExitCode (..) )
-import System.Process ( rawSystem )
-
-openBrowserOSX :: String -> IO Bool
-openBrowserOSX url = exitCodeToBool `fmap` rawSystem executable argv
- where
-  (executable, argv) = ("open", [url])
-  exitCodeToBool ExitSuccess     = True
-  exitCodeToBool (ExitFailure _) = False
− lib/Web/Browser/Windows.hs
@@ -1,35 +0,0 @@-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ForeignFunctionInterface #-}
-
-module Web.Browser.Windows
-  ( openBrowserWindows
-  ) where
-
-import System.Win32.Types
-         ( HANDLE, HINSTANCE, INT, LPCTSTR, handleToWord, nullPtr, withTString )
-
-openBrowserWindows :: String -> IO Bool
-openBrowserWindows url =
-  withTString "open" $ \openStr ->
-    withTString url $ \urlStr ->
-      exitCodeToBool `fmap` c_ShellExecute nullPtr
-                                           openStr
-                                           urlStr
-                                           nullPtr
-                                           nullPtr
-                                           1
- where
-  exitCodeToBool hinst
-    | handleToWord hinst > 32 = True
-    | otherwise               = False
-
--- https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew
-foreign import WINDOWS_CCONV unsafe "windows.h ShellExecuteW"
-  c_ShellExecute ::
-       HANDLE  -- _In_opt_
-    -> LPCTSTR -- _In_opt_
-    -> LPCTSTR -- _In_
-    -> LPCTSTR -- _In_opt_
-    -> LPCTSTR -- _In_opt_
-    -> INT     -- _In_
-    -> IO HINSTANCE
+ lib/unix-like/common/Utils.hs view
@@ -0,0 +1,20 @@+--------------------------------------------------------------------------------
+-- For operating systems that use an application on the PATH to open the URL.
+--------------------------------------------------------------------------------
+
+module Utils
+  ( openBrowserWith
+  ) where
+
+import System.Exit ( ExitCode (..) )
+import System.Process ( proc, waitForProcess, withCreateProcess )
+
+openBrowserWith ::
+     String
+     -- ^ Name of relevant executable on the PATH.
+  -> [String]
+     -- ^ Arguments for executable.
+  -> IO Bool
+openBrowserWith cmd args =
+  withCreateProcess (proc cmd args) $ \_ _ _ p ->
+    (== ExitSuccess) <$> waitForProcess p
+ lib/unix-like/open/Web/Browser/OS.hs view
@@ -0,0 +1,17 @@+--------------------------------------------------------------------------------
+-- For Unix-like operating systems, such as macOS, that provide the open
+-- application on the PATH.
+--------------------------------------------------------------------------------
+
+module Web.Browser.OS
+  ( openBrowser
+  ) where
+
+import Utils ( openBrowserWith )
+
+-- https://ss64.com/mac/open.html
+openBrowser ::
+     String
+     -- ^ URL
+  -> IO Bool
+openBrowser url = openBrowserWith "open" [url]
+ lib/unix-like/xdg-open/Web/Browser/OS.hs view
@@ -0,0 +1,31 @@+--------------------------------------------------------------------------------
+-- For Unix-like operating systems that provide the xdg-open application on the
+-- PATH.
+--------------------------------------------------------------------------------
+
+module Web.Browser.OS
+  ( openBrowser
+  ) where
+
+import Utils ( openBrowserWith )
+
+-- https://ss64.com/bash/xdg-open.html
+openBrowser ::
+     String
+     -- ^ URL
+  -> IO Bool
+openBrowser url =
+  -- sh -c '...'
+  --
+  -- tells the shell (sh) to execute the given string as a command, and
+  -- the following argument (url) is passed as a positional argument $0.
+  --
+  -- xdg-open "$0" 2>&1 > /dev/null
+  --
+  -- The $0 is expanded and the double quotes ensures it is treated as a single
+  -- argument to xdg-open.
+  --
+  -- 2>&1 redirects standard error to standard output.
+  --
+  -- > /dev/null discards standard output.
+  openBrowserWith "sh" ["-c", "xdg-open \"$0\" 2>&1 > /dev/null", url]
+ lib/unsupported-os/Web/Browser/OS.hs view
@@ -0,0 +1,13 @@+--------------------------------------------------------------------------------
+-- For unsupported operating systems
+--------------------------------------------------------------------------------
+
+module Web.Browser.OS
+  ( openBrowser
+  ) where
+
+openBrowser ::
+     String
+     -- ^ URL
+  -> IO Bool
+openBrowser = const (pure False) -- Operation never succeeds
+ lib/windows/Web/Browser/OS.hs view
@@ -0,0 +1,47 @@+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
+{-# HLINT ignore "Use camelCase" #-}
+
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+--------------------------------------------------------------------------------
+-- For Windows operating systems, making use of the Win32 API.
+--------------------------------------------------------------------------------
+
+module Web.Browser.OS
+  ( openBrowser
+  ) where
+
+import System.Win32.Types
+         ( HANDLE, HINSTANCE, INT, LPCWSTR, handleToWord, nullPtr, withTString )
+
+type HWND = HANDLE
+
+-- https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
+-- Activates and displays a window. If the window is minimized, maximized, or
+-- arranged, the system restores it to its original size and position. An
+-- application should specify this flag when displaying the window for the first
+-- time.
+sW_SHOWNORMAL :: INT
+sW_SHOWNORMAL = 1
+
+openBrowser ::
+     String
+     -- ^ URL
+  -> IO Bool
+openBrowser url =
+  withTString "open" $ \openStr ->
+    withTString url $ \urlStr -> exitCodeToBool <$>
+      c_ShellExecute nullPtr openStr urlStr nullPtr nullPtr sW_SHOWNORMAL
+ where
+  exitCodeToBool hinst = handleToWord hinst > 32
+
+-- https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew
+foreign import ccall unsafe "windows.h ShellExecuteW"
+  c_ShellExecute ::
+       HWND         -- [in, optional] hwnd
+    -> LPCWSTR      -- [in, optional] lpOperation
+    -> LPCWSTR      -- [in]           lpFile
+    -> LPCWSTR      -- [in, optional] lpParameters
+    -> LPCWSTR      -- [in, optional] lpDirectory
+    -> INT          -- [in]           nShowCmd
+    -> IO HINSTANCE
open-browser.cabal view
@@ -5,10 +5,9 @@ -- see: https://github.com/sol/hpack  name:           open-browser-version:        0.2.1.1-synopsis:       Open a web browser from Haskell.-description:    Open a web browser from Haskell. Currently BSD, Linux, OS X and Windows are-                supported.+version:        0.3.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@@ -18,7 +17,7 @@ license-file:   LICENSE build-type:     Simple tested-with:-    GHC >= 7.6+    GHC >= 8.4 extra-source-files:     CHANGELOG.md     README.md@@ -35,26 +34,46 @@   default: False  library-  exposed-modules:-      Web.Browser-  other-modules:-      Web.Browser.Linux-      Web.Browser.OSX   hs-source-dirs:       lib+  exposed-modules:+      Web.Browser   build-depends:       base ==4.*-    , process ==1.*+    , process >=1.4.3.0 && <2   default-language: Haskell2010   if os(windows)     other-modules:-        Web.Browser.Windows+        Web.Browser.OS+    hs-source-dirs:+        lib/windows     build-depends:-        Win32-    if arch(i386)-      cpp-options: -DWINDOWS_CCONV=stdcall+        Win32 <3+  else+    if os(darwin)+      other-modules:+          Utils+          Web.Browser.OS+      hs-source-dirs:+          lib/unix-like/common+          lib/unix-like/open+      build-depends:+          process >=1.4.3.0 && <2     else-      cpp-options: -DWINDOWS_CCONV=ccall+      if os(linux) || os(freebsd) || os(openbsd) || os(netbsd)+        other-modules:+            Utils+            Web.Browser.OS+        hs-source-dirs:+            lib/unix-like/common+            lib/unix-like/xdg-open+        build-depends:+            process >=1.4.3.0 && <2+      else+        other-modules:+            Web.Browser.OS+        hs-source-dirs:+            lib/unsupported-os  executable open-browser-example   main-is: Main.hs
stack.yaml view
@@ -1,1 +1,1 @@-snapshot: lts-23.10 # GHC 9.8.4
+snapshot: lts-23.14 # GHC 9.8.4
stack.yaml.lock view
@@ -6,7 +6,7 @@ packages: []
 snapshots:
 - completed:
-    sha256: 889b6bffaf21cd509a7c6017703281e77c2f6df0a0908a11c85fa97fcbf11d4e
-    size: 680573
-    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/10.yaml
-  original: lts-23.10
+    sha256: 1964d439d2a152be4238053f3f997a09fb348391984daab86d724975ef9a423f
+    size: 683814
+    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/14.yaml
+  original: lts-23.14