Skip to content
Browse files

Round 1 finished: cabal2macpkg makes .pkg files now.

  • Loading branch information...
1 parent ebd2c92 commit 79dd0809f132d66f463bf47aaf6e26a1f599fa70 @gregorycollins committed Apr 1, 2009
Showing with 150 additions and 91 deletions.
  1. +4 −3 Distribution/OSX/Info.hs
  2. +117 −49 Main.hs
  3. +10 −9 README.markdown
  4. +19 −30 TODO.markdown
View
7 Distribution/OSX/Info.hs
@@ -47,7 +47,6 @@ data DescriptionPlist = DescriptionPlist {
}
-{-
instance Monoid InfoPlist where
mempty = InfoPlist {
plist_infoString = Nothing
@@ -81,7 +80,7 @@ instance Monoid InfoPlist where
(*+*) = (getLast .) . (mappend `on` Last)
o f = f a *+* f b
--}
+
emptyPlist :: InfoPlist
emptyPlist = InfoPlist {
@@ -98,6 +97,7 @@ emptyPlist = InfoPlist {
}
+emptyDescPlist :: DescriptionPlist
emptyDescPlist = DescriptionPlist {
dplist_title = Nothing
, dplist_version = Nothing
@@ -167,13 +167,14 @@ instance Show DescriptionPlist where
++ "</string>\n")
(f pkg)
+{-
bool :: String -> (DescriptionPlist -> Maybe Bool) -> String
bool hdr f = maybe ""
(\v -> key hdr ++ "\t" ++ val v ++ "\n")
(f pkg)
where
val b = if b then "<true/>" else "<false/>"
-
+-}
------------------------------------------------------------------------
mkInfoPlist :: String -- ^ package identifier
View
166 Main.hs
@@ -38,7 +38,7 @@ module Main (
, makeMacPkg
-- * Misc. helper functions
- , cleanupTempDirectory
+ , cleanupTempDirectory
, getTempDirectory
, runCmd
) where
@@ -123,38 +123,55 @@ runMain opts tmpdir = do
-- will build an Options object where the fields of @a@ are overridden
-- by the non-'Nothing' fields of @b@
data Options = Options {
- installPrefix :: Maybe String -- ^ the installation prefix
- -- for the generated library
-
- , packageMakerPath :: Maybe String -- ^ path to the OSX
- -- packagemaker binary (we'll
- -- choose a sane default here)
-
- , showUsage :: Bool -- ^ if true, show the usage
- -- message, either because the
- -- user requested it or
- -- because of an error parsing
- -- the command line arguments
+ installPrefix :: Maybe String -- ^ the installation prefix
+ -- for the generated library
+
+ , packageMakerPath :: Maybe String -- ^ path to the OSX
+ -- packagemaker binary (we'll
+ -- choose a sane default
+ -- here)
+
+ , showUsage :: Bool -- ^ if true, show the usage
+ -- message, either because
+ -- the user requested it or
+ -- because of an error
+ -- parsing the command line
+ -- arguments
+
+ , packageOutputDir :: Maybe String -- ^ output dir for generated
+ -- .pkg file
+
+ , packageOutputFile :: Maybe String -- ^ output filename for
+ -- generated .pkg file -- if
+ -- specified overrides
+ -- packageOutputDir
+
} deriving (Eq, Show)
defaultOptions :: Options
-defaultOptions = Options { installPrefix = Just "/usr/local"
- , showUsage = False
- , packageMakerPath = Just "/Developer/usr/bin/packagemaker"
+defaultOptions = Options { installPrefix = Just "/"
+ , showUsage = False
+ , packageMakerPath = Just "/Developer/usr/bin/packagemaker"
+ , packageOutputDir = Nothing
+ , packageOutputFile = Nothing
}
instance Monoid Options where
- mempty = Options { installPrefix = Nothing
- , showUsage = False
- , packageMakerPath = Nothing
+ mempty = Options { installPrefix = Nothing
+ , showUsage = False
+ , packageMakerPath = Nothing
+ , packageOutputDir = Nothing
+ , packageOutputFile = Nothing
}
a `mappend` b =
Options {
- installPrefix = override installPrefix
- , packageMakerPath = override packageMakerPath
- , showUsage = showUsage a || showUsage b
+ installPrefix = override installPrefix
+ , packageMakerPath = override packageMakerPath
+ , packageOutputDir = override packageOutputDir
+ , packageOutputFile = override packageOutputFile
+ , showUsage = showUsage a || showUsage b
}
where
-- monoid append using "Last" behaviour
@@ -172,15 +189,36 @@ optionFlags = [ GetOpt.Option
["help"]
(GetOpt.NoArg $ mempty {showUsage=True})
"prints usage statement"
+
, GetOpt.Option
""
["prefix"]
(GetOpt.OptArg mkPrefix "DIR")
- "installation prefix directory" ]
+ "installation prefix directory"
+
+ , GetOpt.Option
+ "d"
+ ["outdir"]
+ (GetOpt.OptArg mkOutputDir "DIR")
+ "output install package to the given directory (default \".\")"
+
+ , GetOpt.Option
+ "o"
+ ["output"]
+ (GetOpt.OptArg mkOutputFile "FILE")
+ "output install package to the given file"
+ ]
+
where
mkPrefix :: Maybe String -> Options
mkPrefix m = mempty { installPrefix = m }
+ mkOutputDir :: Maybe String -> Options
+ mkOutputDir m = mempty { packageOutputDir = m }
+
+ mkOutputFile :: Maybe String -> Options
+ mkOutputFile m = mempty { packageOutputFile = m }
+
------------------------------------------------------------------------
-- | prints the usage statement
@@ -242,23 +280,16 @@ makeMacPkg opts tmpdir pkgDesc = do
-- some portions of package building process require root
-- privileges
- -- TODO/FIXME: check that assumption, during development it isn't
- -- convenient so I'm commenting it out temporarily
-
- -- checkRootPrivileges
+ checkRootPrivileges
createDirectories
--------------------------------------------------------------------
buildPackageContents
-
- -- TODO: setRootPrivileges will make sure the generated files have
- -- the correct username & permissions
setRootPrivileges
-
- -- make .info files
mkInfoFiles
+ runPackageMaker
where
--------------------------------------------------------------------
@@ -270,8 +301,6 @@ makeMacPkg opts tmpdir pkgDesc = do
pkgTitle = unPackageName . packageName $ pkgDesc
pkgVersionString = showVersion . packageVersion $ pkgDesc
pkgBaseName = subRegex (mkRegex "[[:space:]]+") pkgTitle "_"
- pkgDestinationFile = tmpdir </> (pkgBaseName ++ "-" ++ pkgVersionString
- ++ ".pkg")
-- directories
cabalBuildDir = tmpdir </> "dist"
@@ -285,11 +314,18 @@ makeMacPkg opts tmpdir pkgDesc = do
prefix = fromJust $ installPrefix opts
-- output files
+ temporaryPkgConfig = tmpdir </> "temp.pkgconfig"
infoPath = tmpdir </> "Info.plist"
descInfoPath = resourceDir </> "Description.plist"
postflightScriptFile = resourceDir </> "postflight"
+ outputPackageDir = fromMaybe "." (packageOutputDir opts)
+ computedPackageFile = (pkgBaseName ++ "-" ++ pkgVersionString ++ ".pkg")
+ outputPackagePath = fromMaybe (outputPackageDir </> computedPackageFile)
+ (packageOutputFile opts)
+
+
--------------------------------------------------------------------
-- helper I/O actions
--------------------------------------------------------------------
@@ -312,15 +348,23 @@ makeMacPkg opts tmpdir pkgDesc = do
--------------------------------------------------------------------
-- uses cabal to build the package into the work area
buildPackageContents = do
- runSetup "configure" ["--global", "--prefix=/testme"]
- runSetup "build" []
- runSetup "haddock" []
- runSetup "copy" ["--destdir=" ++ contentsDir]
- runSetup "register" ["--gen-script"]
+ runSetup "configure" ["--global", "--prefix=/usr/local"]
+ runSetup "build" []
+ runSetup "haddock" []
+ runSetup "copy" ["--destdir=" ++ contentsDir]
+ runSetup "register" ["--gen-pkg-config=" ++ temporaryPkgConfig]
- copyFile "register.sh" postflightScriptFile
- runCmd "chmod" ["+x", postflightScriptFile]
- removeFile "register.sh"
+ makePostFlightScriptFile temporaryPkgConfig postflightScriptFile
+
+
+ --------------------------------------------------------------------
+ -- FIXME: make this stuff relocatable
+ makePostFlightScriptFile src dest = do
+ contents <- readFile src
+ let output = "#!/bin/sh\n\
+ \echo '" ++ contents ++
+ "' | /usr/bin/env ghc-pkg --global update -"
+ writeFile dest output
--------------------------------------------------------------------
@@ -338,10 +382,37 @@ makeMacPkg opts tmpdir pkgDesc = do
dpinfo = mkDescriptionPlist pkgBaseName pkgVersionString
- -- TODO: make sure files are owned by root and have correct
- -- permissions
+
+ --------------------------------------------------------------------
+ -- make sure files are owned by root and have correct permissions
setRootPrivileges :: IO ()
- setRootPrivileges = return ()
+ setRootPrivileges = do
+ runCmd "chmod" ["-R", "g+r,g-w,o+r,o-w", tmpdir]
+ runCmd "chown" ["-R", "root", tmpdir]
+ runCmd "sh" ["-c", "find " ++ tmpdir
+ ++ " -print0 -type d | xargs -0 chmod a+x"]
+
+
+ --------------------------------------------------------------------
+ -- build the package
+ runPackageMaker :: IO ()
+ runPackageMaker = do
+ putStrLn $ "building " ++ outputPackagePath
+ hFlush stdout
+
+ runCmd packageMakerCmd [ "-build"
+ , "-p"
+ , outputPackagePath
+ , "-f"
+ , contentsDir
+ , "-ds"
+ , "-r"
+ , resourceDir
+ , "-i"
+ , infoPath
+ , "-d"
+ , descInfoPath ]
+
--------------------------------------------------------------------
@@ -407,9 +478,6 @@ getTempDirectory =
--
cleanupTempDirectory :: FilePath
-> IO ()
-cleanupTempDirectory dir = do
- --removeDirectoryRecursive dir
- putStrLn $ "temporary directory is '" ++ dir ++ "'"
- return ()
+cleanupTempDirectory = removeDirectoryRecursive
View
19 README.markdown
@@ -1,13 +1,16 @@
-cabal2macpkg
-============
+# cabal2macpkg #
This is (will be) a tool to turn cabal libraries into Macintosh
-packages. Cabal2macpkg is in its very early stages, and doesn't work
-yet, sorry.
+packages.
-Status
-------
-Rough outline of the process:
+## Status ##
+
+Cabal2macpkg currently will build a .pkg file from a .cabal
+library. The next step (not started yet) will be to provide a mode
+that will read a .cabal file, recursively make .pkg files out of all
+of its dependencies, and package them all up into a .mpkg file.
+
+### Rough outline of the .pkg process ###
1. find a .cabal file in the current working directory
2. run "cabal build; cabal haddock" into a staging area
@@ -16,8 +19,6 @@ Rough outline of the process:
4. turn the staging area into a mac package file using the OS X
developer tools
-I've gotten up to number three here.
-
A consequence of this quick n' dirty approach is that in order to
build the installer for a cabal package, you need to have already
installed all of its dependencies on the build machine.
View
49 TODO.markdown
@@ -1,7 +1,25 @@
TODO for cabal2macpkg
=====================
-### status update ###
+## TODO items (round 1) ##
+
+* add support for relocatable packages -- not sure how to do this, any
+ ideas would be appreciated. Manuel wanted this.
+
+
+## TODO items (round 2) ##
+
+* add a "--metapackage" flag (or something similar) that will cause
+ cabal2macpkg to make .pkg files of the project's dependencies and
+ generate an aggregate .mpkg file
+
+* may need "--exclude"/"--include" flags for this, or some other
+ mechanism to stop the recursion. For the haskell platform a
+ recursion depth of 1 is probably fine.
+
+
+## status update ##
+
N.B. this is more for my notetaking benefit than for the reader
Status: getting close. Have decided, for the time being, to use the
@@ -41,32 +59,3 @@ command-line tools right now. Apple's solution seems to be "use the
GUI tool!" which is useless to me.
-round 1
--------
-
-* get the staging area in the right format for the OSX installer tool
- and run it
-
-* If I want relocatable packages, which Manuel wanted, I've become
- convinced that I need to move away from `cabal register
- --gen-script` to `cabal register --gen-pkg-config` and write my own
- postflight script. This will mean an extra step here (boilerplate
- shell script, rewriting the target path to `$4` or whatever the
- correct argument is). Note to self: use "env" to locate ghc-pkg?
-
-* add --output=[FILE] and an --outputdir=[DIR] to control where the
- generated .pkg files go
-
-* code cleanup (warnings, imports, formatting, etc) *(a pre-release
- activity)*
-
-
-round 2
--------
-
-* add a "--metapackage" flag (or something similar) that will cause
- cabal2macpkg to make .pkg files of the project's dependencies and
- generate an aggregate .mpkg file
-
-* may need "--exclude"/"--include" flags for this, or some other
- mechanism to stop the recursion

0 comments on commit 79dd080

Please sign in to comment.
Something went wrong with that request. Please try again.