Stack: Local packages are not allowed when using the script command.

Created on 22 Aug 2017  Â·  6Comments  Â·  Source: commercialhaskell/stack

General summary/comments (optional)

It seems packges outside stackage are not allowed in stack scripts.

Is there any fix?

Steps to reproduce

Execute

#!/usr/bin/env stack
{- stack --resolver lts-9.1 script --optimize
   --package turtle
   --package charsetdetect
   --package iconv
   --package bytestring
-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
import Codec.Text.Detect (detectEncodingName)
import Codec.Text.IConv (convert)
import Turtle.Options
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text.Lazy as T
import qualified Data.Text.Lazy.Encoding as TE
import qualified Data.Text.Lazy.IO as TIO
import Control.Monad (when, forM_)
import Data.Monoid ((<>))

data Option = Option { notest :: Bool, files :: [FilePath] }

optParser :: Parser Option
optParser = Option
  <$> switch "notest" 'n' "Actually convert files"
  <*> some (argPath "FILE")

desc :: String
desc = "It converts the encoding of each file's content to UTF-8, and \
       \remove carriage returns."

-- processFile :: Bool -> FilePath -> IO ()
processFile notest file = do
  bs <- BL.readFile file
  case detectEncodingName bs of
    Nothing -> echo "Encoding detection failed."
    Just "UTF-8" -> echo "Character encoding is already UTF-8"
    Just enc -> do
      echo $ "Detected encoding : " <> enc
      when notest $ do
        TIO.writeFile $ T.filter (/='\r') $ TE.decodeUtf8 $
          convert enc "UTF-8" bs
        putStrLn "File encoding has been converted to UTF-8."

main :: IO ()
main = do
  Option{..} <- options desc optParser
  let process = processFile notest
  putStrLn ""
  forM_ files $ \file -> do
    putStrLn $ file <> ":"
    process file
    putStrLn ""

Expected

Help message is printed.

Actual

$ charset.hs
Local packages are not allowed when using the script command. Packages found:
- charsetdetect-1.1.0.2

Stack version

$ stack --version
Version 1.5.1 x86_64

Method of installation

  • Haskell gentoo overlay
awaiting pull request documentation script interpreter

Most helpful comment

@crocket The older runghc script approach supports this - https://docs.haskellstack.org/en/stable/GUIDE/#writing-independent-and-reliable-scripts . Perhaps the documentation should be improved to make this clearer. I am leaving this open and marking it as a documentation issue.

Doing it that way is a bit slower and potentially not as reproducible, but it works:

{- stack --resolver lts-9.1 runghc
   --package turtle
   --package charsetdetect
   --package iconv
   --package bytestring
-}

All 6 comments

This is by design, for reproducibility and ease of interface/implementation I think.

You could look at custom snapshots, that might do what you like. See #3218 for instance. It looks like the commit mentioned in there isn't in a released stack version yet though, you'd likely have to do a stack upgrade --git or wait until the next release.

How can I specify charsetdetect-1.1.0.2 in a stack script?

You'd have to create a custom snapshot, as described in the user guide and also has an example in the issue I linked there. You also might need a version of stack that's built from source as mentioned. I'm not sure if you do or not.

Then you'd just use that snapshot as the resolver for your script, and have it in the --package list. Also shown in the linked issue.

Oh, stack scripts are unable to access custom snapshot on stack 1.5.1. I'll wait.

@crocket The older runghc script approach supports this - https://docs.haskellstack.org/en/stable/GUIDE/#writing-independent-and-reliable-scripts . Perhaps the documentation should be improved to make this clearer. I am leaving this open and marking it as a documentation issue.

Doing it that way is a bit slower and potentially not as reproducible, but it works:

{- stack --resolver lts-9.1 runghc
   --package turtle
   --package charsetdetect
   --package iconv
   --package bytestring
-}

Is there any update on the issue? Is it now possible to define local packages in scripts?
e.g.

{- stack --resolver lts-9.1 runghc
   --package turtle
   --package charsetdetect
   --package iconv
   --package bytestring
   --package /home/user/dev/myHaskellPackage
-}
Was this page helpful?
0 / 5 - 0 ratings