epub-tools 3.0 → 3.1
raw patch · 9 files changed
+64/−348 lines, 9 files
Files
- .gitignore +0/−1
- LICENSE +13/−11
- README.md +1/−1
- changelog.md +6/−0
- epub-tools.cabal +3/−2
- stack.yaml.lock +19/−0
- util/install.hs +0/−328
- util/install.sh +15/−0
- util/win-dist.sh +7/−5
.gitignore view
@@ -1,6 +1,5 @@ # stack build artifacts .stack-work/-stack.yaml.lock # Generated by hasktags tags
LICENSE view
@@ -1,13 +1,15 @@-Copyright (c) 2008 Dino Morelli+Copyright (c) 2008, Dino Morelli <dino@ui3.info> -Permission to use, copy, modify, and/or distribute this software for any purpose-with or without fee is hereby granted, provided that the above copyright notice-and this permission notice appear in all copies.+Permission to use, copy, modify, and/or distribute this software+for any purpose with or without fee is hereby granted, provided+that the above copyright notice and this permission notice appear+in all copies. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND-FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS-OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF-THIS SOFTWARE.+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL+WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE+AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA+OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR+PERFORMANCE OF THIS SOFTWARE.
README.md view
@@ -72,7 +72,7 @@ Binaries - epub-tools is available for Arch Linux [from the AUR](http://aur.archlinux.org/packages/epub-tools/)-- Download [binaries for Windows](https://github.com/dino-/epub-tools/releases/download/2.11/epub-tools-2.11-win.zip)+- Download binary distributions for generic Linux, OSX and Windows [from this directory](https://github.com/dino-/epub-tools/releases/download/3.1) Getting source for development
changelog.md view
@@ -1,3 +1,9 @@+3.1 (2023-09-05)++ * Adjustments to deployment tooling and layout+ * Replaced license file with a better-formatted version++ 3.0 (2023-07-09) * Fixed link to Windows binary dist
epub-tools.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: epub-tools-version: 3.0+version: 3.1 synopsis: Command line utilities for working with epub files description: A suite of command-line utilities for creating and manipulating epub book files. Included are: epubmeta, epubname, epubzip category: Application, Console@@ -21,9 +21,10 @@ doc/INSTALL README.md stack.yaml+ stack.yaml.lock TODO.md util/all-books.hs- util/install.hs+ util/install.sh util/win-dist.sh source-repository head
+ stack.yaml.lock view
@@ -0,0 +1,19 @@+# 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/lock_files++packages:+- completed:+ hackage: epub-metadata-5.1@sha256:c04142a99c9c437bcef9b4ac7ad681bdbddd0a555583a68ef2cbf83bd49babe1,3460+ pantry-tree:+ sha256: 299c53341b5fd1e81d096bd9c9574a51b616224c43bd4d47d711afb92758c1c1+ size: 3659+ original:+ hackage: epub-metadata-5.1+snapshots:+- completed:+ sha256: af5d667f6096e535b9c725a72cffe0f6c060e0568d9f9eeda04caee70d0d9d2d+ size: 649133+ url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/12.yaml+ original: lts-20.12
− util/install.hs
@@ -1,328 +0,0 @@-#! /usr/bin/env stack-{- stack runghc -}--{-# LANGUAGE ScopedTypeVariables #-}--import Control.Exception-import Control.Monad-import Data.List-import Distribution.Package-import Distribution.PackageDescription hiding ( error, options )-import Distribution.PackageDescription.Parse-import Distribution.Verbosity-import Distribution.Version-import System.Console.GetOpt-import System.Directory-import System.Environment-import System.Exit-import System.FilePath-import System.Process-import Text.Printf-import Text.Read---defaultOptions :: Options-defaultOptions = Options- { optClean = False- , optDelete = False- , optHelp = False- , optLink = False- , optPrefix = "/opt"- , optRsrcCpVerbose = True- , optInstType = FHS- , optVersion = True- }--data InstallType = Bundle | FHS deriving Eq---main :: IO ()-main = do- -- Parse args- (opts, _) <- parseOpts =<< getArgs-- -- User asked for help- when (optHelp opts) $ putStrLn usageText >> exitSuccess-- -- Locate cabal file- cabalFiles <- (filter $ isSuffixOf ".cabal") <$> getDirectoryContents "."-- when (null cabalFiles) $ do- die "Can't continue because no cabal files were found in ."-- -- Parse the cabal file and extract things we need from it- -- then pass a pile of what we know to a function to create the- -- installation dirs- dirs <- constructDirs opts . package . packageDescription- <$> readGenericPackageDescription normal (head cabalFiles)--- -- Perform the installation-- -- Remove existing install directory- appDirExists <- doesDirectoryExist $ appDir dirs- when (optDelete opts && appDirExists) $ do- putStrLn $ "Removing existing directory " ++ (appDir dirs)- removeDirectoryRecursive $ appDir dirs-- -- Clean before building- when (optClean opts) $ system "stack clean" >> return ()-- -- Copy the binaries- createDirectoryIfMissing True $ binDir dirs- installExitCode <- system $ "stack install --local-bin-path=" ++ (binDir dirs)- unless (ok installExitCode) $ die "Can't continue because stack install failed"-- -- Copy additional scripts- {-- putStrLn "Copying additional scripts"- mapM_ (\f -> copyFile ("util" </> f) (binDir dirs </> f))- [ "script1.sh", "script2.hs" ]- -}-- -- Copy the license- putStrLn "\nCopying LICENSE"- createDirectoryIfMissing True $ docDir dirs- copyFile "LICENSE" (docDir dirs </> "LICENSE")-- -- Copy the resources- let rsrcDirSrc = "." </> "resources"- rsrcsExist <- doesDirectoryExist rsrcDirSrc- when rsrcsExist $ do- putStrLn $ "\nCopying resources"- copyTree (optRsrcCpVerbose opts) rsrcDirSrc (rsrcDir dirs)- return ()-- -- Make the symlink- when (optLink opts) $ do- if (optInstType opts == FHS) then- putStrLn "No link will be made because installation type is fhs"- else if (not . optVersion $ opts) then- putStrLn "No link will be made because the app dir already has no version part"- else do- printf "Making symbolic link now %s -> %s\n" (linkPath dirs) (appDir dirs)- system $ printf "rm %s" (linkPath dirs)- system $ printf "ln -s %s %s" (appDir dirs) (linkPath dirs)- return ()-- exitSuccess---data Dirs = Dirs- { appDir :: FilePath- , linkPath :: FilePath- , binDir :: FilePath- , docDir :: FilePath- , rsrcDir :: FilePath- }---constructDirs :: Options -> PackageId -> Dirs-constructDirs opts pkgId =- Dirs appDir' linkPath' binDir' (appDir' </> "doc") (appDir' </> "resources")-- where- project = unPackageName . pkgName $ pkgId- version = showVersion . pkgVersion $ pkgId- versionPart = if optVersion opts then "-" ++ version else ""- appDir' = case (optInstType opts) of- Bundle -> optPrefix opts </> (project ++ versionPart)- FHS -> optPrefix opts </> "share" </> (project ++ versionPart)- linkPath' = optPrefix opts </> project- binDir' = case (optInstType opts) of- Bundle -> appDir' </> "bin"- FHS -> optPrefix opts </> "bin"---{- Turn an exit code (say, from system) into a Bool--}-ok :: ExitCode -> Bool-ok ExitSuccess = True-ok _ = False---{-- Argument parsing code--}--data Options = Options- { optClean :: Bool- , optDelete :: Bool- , optHelp :: Bool- , optLink :: Bool- , optPrefix :: FilePath- , optRsrcCpVerbose :: Bool- , optInstType :: InstallType- , optVersion :: Bool- }---instance Read InstallType where- readsPrec _ "bundle" = [(Bundle, "")]- readsPrec _ "fhs" = [(FHS, "")]- readsPrec _ _ = []--instance Show InstallType where- show Bundle = "bundle"- show FHS = "fhs"---readInstallType :: String -> InstallType-readInstallType s =- case (readEither s) of- Left _ -> error $ printf "Can't continue because %s is not a valid install type\n\n%s" s usageText- Right t -> t---options :: [OptDescr (Options -> Options)]-options =- [ Option ['c'] ["clean"]- (NoArg (\opts -> opts { optClean = True } ))- ("Do 'stack clean' first." ++ (defaultText . optClean $ defaultOptions))- , Option ['C'] ["no-clean"]- (NoArg (\opts -> opts { optClean = False } ))- ("Do not 'stack clean' first."- ++ (defaultText . not . optClean $ defaultOptions))- , Option ['d'] ["delete"]- (NoArg (\opts -> opts { optDelete = True } ))- ("Delete the app directory before copying files."- ++ (defaultText . optDelete $ defaultOptions))- , Option ['D'] ["no-delete"]- (NoArg (\opts -> opts { optDelete = False } ))- ("Do not delete the app directory before copying files."- ++ (defaultText . not . optDelete $ defaultOptions))- , Option ['h'] ["help"]- (NoArg (\opts -> opts { optHelp = True } ))- "This help information."- , Option ['l'] ["link"]- (NoArg (\opts -> opts { optLink = True } ))- ("Create symlink PROJECT -> PROJECT-VERSION in PREFIX dir. Only useful for bundle installations. Does not work on Windows."- ++ (defaultText . optLink $ defaultOptions))- , Option ['L'] ["no-link"]- (NoArg (\opts -> opts { optLink = True } ))- ("Do not create symlink PROJECT -> PROJECT-VERSION in PREFIX dir."- ++ (defaultText . not . optLink $ defaultOptions))- , Option ['p'] ["prefix"]- (ReqArg (\s opts -> opts { optPrefix = s } ) "PREFIX" )- (printf "Install prefix directory. Defaults to %s so what you'll end up with is %s/PROJECT-VERSION"- (optPrefix defaultOptions) (optPrefix defaultOptions))- , Option ['r'] ["resource-copy-verbose"]- (NoArg (\opts -> opts { optRsrcCpVerbose = True } ))- ("Be chatty when copying the resources directory."- ++ (defaultText . optRsrcCpVerbose $ defaultOptions))- , Option ['R'] ["no-resource-copy-verbose"]- (NoArg (\opts -> opts { optRsrcCpVerbose = False } ))- ("Don't be chatty when copying the resources directory. Useful when there are a LOT of resources."- ++ (defaultText . not . optRsrcCpVerbose $ defaultOptions))- , Option ['t'] ["type"]- (ReqArg (\s opts -> opts { optInstType = readInstallType s } ) "INST_TYPE" )- (printf "Installation type, see INSTALLATION TYPE below for details. Default: %s"- (show . optInstType $ defaultOptions))- , Option ['v'] ["version"]- (NoArg (\opts -> opts { optVersion = True } ))- (printf "Include version in installation path, meaning: %s/PROJECT-VERSION %s"- (optPrefix defaultOptions) (defaultText . optVersion $ defaultOptions))- , Option ['V'] ["no-version"]- (NoArg (\opts -> opts { optVersion = False } ))- (printf "Do not include version in installation path, meaning: %s/PROJECT %s"- (optPrefix defaultOptions) (defaultText . not . optVersion $ defaultOptions))- ]---defaultText :: Bool -> String-defaultText True = " Default"-defaultText False = ""---parseOpts :: [String] -> IO (Options, [String])-parseOpts args =- case getOpt Permute options args of- (o,n,[] ) -> return (foldl (flip id) defaultOptions o, n)- (_,_,errs) -> ioError $ userError (concat errs ++ usageText)---usageText :: String-usageText = (usageInfo header options) ++ "\n" ++ footer- where- header = init $ unlines- [ "Usage: install.hs [OPTIONS]"- , ""- , "options:"- ]- footer = init $ unlines- [ "INSTALLATION TYPE"- , ""- , "This is the topology used when copying files, one of: bundle, fhs"- , ""- , "bundle is sort-of a self-contained structure like this:"- , ""- , " $PREFIX/"- , " $PROJECT -> $PROJECT-$VERSION <-- if --link was specified"- , " $PROJECT-$VERSION/ <-- this is the \"app directory\""- , " bin/..."- , " doc/LICENSE"- , " resources/..."- , ""- , "fhs is the more traditional UNIX structure like this:"- , ""- , " $PREFIX/"- , " bin/..."- , " share/"- , " $PROJECT-$VERSION/ <-- this is the \"app directory\""- , " doc/LICENSE"- , " resources/..."- , ""- , "Be aware that when the --delete switch is used along with fhs type, the binaries WILL NOT be deleted, only the \"app directory\"."- , ""- , "COMPILING"- , ""- , "install.hs was intentionally left as a script, but if you would prefer to compile it, do this:"- , ""- , " $ stack ghc -- -o util/install util/install.hs"- , ""- , ""- , "This script is part of the hsinstall package by Dino Morelli <dino@ui3.info>"- ]---{-- Recursive file copying code-- It was desireable to have a standalone recursive file copy in- this script for maximum cross-platform compatibility and to- avoid Haskell library dependencies.-- Many thanks to [abuzittin gillifirca](https://codereview.stackexchange.com/users/20251/abuzittin-gillifirca) for the StackOverflow post [Copying files in Haskell](https://codereview.stackexchange.com/questions/68908/copying-files-in-haskell) where the following code was lifted.--}--copyTree :: Bool -> FilePath -> FilePath -> IO ()-copyTree chatty s t = do- createDirectoryIfMissing True t- subItems <- getSubitems s- mapM_ (copyItem chatty s t) subItems---getSubitems :: FilePath -> IO [(Bool, FilePath)]-getSubitems path = getSubitems' ""- where- getChildren path = (\\ [".", ".."]) <$> getDirectoryContents path-- getSubitems' relPath = do- let absPath = path </> relPath- isDir <- doesDirectoryExist absPath- children <- if isDir then getChildren absPath else return []- let relChildren = [relPath </> p | p <- children]- ((isDir, relPath) :) . concat <$> mapM getSubitems' relChildren---copyItem :: Bool -> FilePath -> FilePath -> (Bool, FilePath) -> IO ()-copyItem chatty baseSourcePath baseTargetPath (isDir, relativePath) = do- let sourcePath = baseSourcePath </> relativePath- let targetPath = baseTargetPath </> relativePath-- when chatty $- putStrLn $ "Copying " ++ sourcePath ++ " to " ++ targetPath-- if isDir- then createDirectoryIfMissing False targetPath- else copyFile sourcePath targetPath
+ util/install.sh view
@@ -0,0 +1,15 @@+#! /usr/bin/env bash++set -e++projectName="epub-tools"+version=$(awk '/^[Vv]ersion/ { print $2 }' "${projectName}.cabal")++PREFIX=${PREFIX:-"${projectName}-${version}"}+docDir="$PREFIX/usr/share/doc/${projectName}"+licenseDir="$PREFIX/usr/share/licenses/${projectName}"++stack install --local-bin-path="$PREFIX/usr/bin"+install -Dm0644 "LICENSE" "$licenseDir/LICENSE"+install -Dm0644 "README.md" "$docDir/README.md"+install -Dm0644 "changelog.md" "$docDir/changelog.md"
util/win-dist.sh view
@@ -1,12 +1,14 @@-#! /bin/bash+#! /usr/bin/env bash -version=$(awk '/^[Vv]ersion/ { print $2 }' epub-tools.cabal)+projectName="epub-tools"+version=$(awk '/^[Vv]ersion/ { print $2 }' "${projectName}.cabal") -buildDir="dist"+buildDir="win-dist" -./util/install.hs -p $buildDir -t bundle+PREFIX="$buildDir" ./util/install.sh+install -Dm0644 doc/INSTALL "${buildDir}/usr/share/doc/${projectName}/INSTALL" -zipFile="epub-tools-$version-win.zip"+zipFile="${projectName}-${version}-win.zip" rm $zipFile