Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/local cache #41

Merged
merged 10 commits into from
Jan 31, 2017
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,16 @@ environment variable to your desired profile.

The Romefile has three purposes:

1. Specifies what S3 bucket to use - `[Cache]` section. This section is __required__.
1. Specifies what caches to use - `[Cache]` section. This section is __required__.
1. Allows to use custom name mappings between repository names and framework names - `[RepositoryMap]` section. This section is __optional__ and can be omitted.
1. Allows to ignore certain framework names - `[IgnoreMap]` section. This section is __optional__ and can be omitted.


A Romefile looks like this:

```
[Cache]
S3-Bucket = ios-dev-bucket
local = /tmp/Rome

[RepositoryMap]
HockeySDK-iOS = HockeySDK
Expand All @@ -120,8 +120,10 @@ A Romefile looks like this:

The Romefile is in the [INI format](https://en.wikipedia.org/wiki/INI_file)

#### S3Bucket section
This section contains the name of the S3 bucket you want Rome to use to upload/download.
#### Cache section
This section contains the name of:
- the S3 bucket you want Rome to use to upload/download. The key `S3-Bucket` is __required__.
- the path to local directory to use as an additional cache. The key `local` is __optional__.

#### RepositoryMap
This contains the mappings of git repository names with framework names.
Expand Down Expand Up @@ -159,6 +161,7 @@ This is particularly useful in case not all your `Cartfile.resolved` entries pro
Some repositories use Carthage as a simple mechanism to include other git repositories that do not produce frameworks.
Even Carthage itself does this, to include xcconfigs.


Example:

Suppose you have the following in your `Cartfile`
Expand All @@ -167,8 +170,10 @@ Suppose you have the following in your `Cartfile`
github "Quick/Nimble"
github "jspahrsummers/xcconfigs"
```

`xcconfigs` can be ignored by Rome by adding an `IgnoreMap` section in the Romefile


```
[IgnoreMap]
xcconfigs = xcconfigs
Expand Down Expand Up @@ -232,6 +237,8 @@ Uploaded CatFramework to: CatFramework/CatFramework.framework-3.3.1.zip
Uploaded CatFramework.dSYM to: CatFramework/CatFramework.framework.dSYM-3.3.1.zip
```

If a local cache is specified in your `Romefile` and you wish to ignore it pass `--skip-local-cache` on the command line.

#### Downloading

Downloading one or more frameworks and corresponding dSYMs
Expand All @@ -251,6 +258,8 @@ Downloaded CatFramework from: CatFramework/CatFramework.framework.dSYM-3.3.1.zip
Unzipped CatFramework from: CatFramework.framework.dSYM-3.3.1.zip
```

If a local cache is specified in your `Romefile` and you wish to ignore it pass `--skip-local-cache` on the command line.

#### Listing

Listing frameworks and reporting on their availability:
Expand Down
5 changes: 4 additions & 1 deletion Rome.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Rome
version: 0.7.1.14
version: 0.8.0.17
synopsis: An S3 cache for Carthage
description: Please see README.md
homepage: https://github.com/blender/Rome
Expand Down Expand Up @@ -29,12 +29,15 @@ library
, mtl >= 2.2.1
, MissingH >= 1.3
, directory >= 1.2.2
, filepath >= 1.4
, containers >= 0.5
, unordered-containers >= 0.2.7
, conduit >= 1.2
, conduit-extra >= 1.1
, ini >= 0.3.5
, text >= 1.2
, time >= 1.5.0
, transformers >= 0.4
, bytestring >= 0.10
, zip-archive >= 0.2
, resourcet >= 1.1
Expand Down
3 changes: 2 additions & 1 deletion app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import Options.Applicative as Opts


romeVersion :: String
romeVersion = "0.7.1.14"
romeVersion = "0.8.0.17"




Expand Down
54 changes: 42 additions & 12 deletions src/Data/Romefile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@ module Data.Romefile
, FrameworkName (..)
, GitRepoName (..)
, RomeFileParseResult (..)
, RomeCacheInfo (..)
)
where

import Data.Ini as INI
import Data.Ini.Utils as INI
import Data.HashMap.Strict as M
import Data.Monoid
import Data.Maybe
import Data.Text
import Control.Monad.Except
import Control.Monad.Trans
import System.Directory
import System.FilePath
import System.Path.NameManip



Expand All @@ -36,12 +41,14 @@ data RomefileEntry = RomefileEntry { gitRepositoryName :: GitRepoName
}
deriving (Show, Eq)

data RomeFileParseResult = RomeFileParseResult { bucket :: Text
data RomeFileParseResult = RomeFileParseResult { cacheInfo :: RomeCacheInfo
, repositoryMapEntries :: [RomefileEntry]
, ignoreMapEntries :: [RomefileEntry]
}


data RomeCacheInfo = RomeCacheInfo { _bucket :: Text
, _localCacheDir :: Maybe FilePath
}

-- |The name of the Romefile
romefile :: String
Expand All @@ -55,6 +62,10 @@ cacheSectionDelimiter = "Cache"
s3BucketKey :: Text
s3BucketKey = "S3-Bucket"

-- |The local cache dir Key
localCacheDirKey :: Text
localCacheDirKey = "local"

-- |The delimier of the REPOSITORYMAP section
repositoryMapSectionDelimiter :: Text
repositoryMapSectionDelimiter = "RepositoryMap"
Expand All @@ -64,21 +75,28 @@ ignoreMapSectionDelimiter :: Text
ignoreMapSectionDelimiter = "IgnoreMap"


parseRomefile :: (MonadIO m, MonadError String m) => FilePath -> m RomeFileParseResult
parseRomefile :: MonadIO m => FilePath -> ExceptT FilePath m RomeFileParseResult
parseRomefile f = do
eitherIni <- liftIO $ INI.readIniFile f
case eitherIni of
Left iniError -> throwError iniError
Right ini -> do
eitherBucker <- getBucket ini
case eitherBucker of
Left e -> throwError $ "Error while parsing " <> f <> ": " <> unpack e
Right bucket -> do
repositoryMapEntries <- getRepostiryMapEntries ini
ignoreMapEntries <- getIgnoreMapEntries ini
return RomeFileParseResult {..}

getBucket ini = requireKey s3BucketKey `inRequiredSection` cacheSectionDelimiter `fromIni'` ini
_bucket <- withExceptT toErrorMessage $ getBucket ini
maybeCacheDirAsText <- withExceptT toErrorMessage $ getLocalCacheDir ini
_localCacheDir <- liftIO $ mapM absolutize (unpack <$> maybeCacheDirAsText)
repositoryMapEntries <- getRepostiryMapEntries ini
ignoreMapEntries <- getIgnoreMapEntries ini
let cacheInfo = RomeCacheInfo {..}
return RomeFileParseResult { .. }
where
toErrorMessage :: Text -> String
toErrorMessage e = "Error while parsing " <> f <> ": " <> unpack e

getBucket :: MonadIO m => Ini -> ExceptT Text m Text
getBucket ini = requireKey s3BucketKey `inRequiredSection` cacheSectionDelimiter `fromIni''` ini

getLocalCacheDir :: MonadIO m => Ini -> ExceptT Text m (Maybe Text)
getLocalCacheDir ini = optionalKey localCacheDirKey `inRequiredSection` cacheSectionDelimiter `fromIni''` ini

getRepostiryMapEntries :: MonadIO m => Ini -> m [RomefileEntry]
getRepostiryMapEntries = getRomefileEntries repositoryMapSectionDelimiter
Expand All @@ -98,3 +116,15 @@ getRomefileEntries sectionDelimiter ini = do
(FrameworkName . unpack . strip)
(splitOn "," frameworkCommonNames)))
(M.toList m)

-- | Take a path and makes it absolute resolving ../ and ~
-- See https://www.schoolofhaskell.com/user/dshevchenko/cookbook/transform-relative-path-to-an-absolute-path
absolutize :: FilePath -> IO FilePath
absolutize aPath
| "~" `isPrefixOf` pack aPath = do
homePath <- getHomeDirectory
return $ normalise $ addTrailingPathSeparator homePath
++ Prelude.tail aPath
| otherwise = do
pathMaybeWithDots <- absolute_path aPath
return $ fromJust $ guess_dotdot pathMaybeWithDots
Loading