Skip to content
This repository
Browse code

Search for the config file in the project root.

Project root is defined as the nearest ancestor directory that contains a
.stylish-haskell.yaml file (the same logic that Git uses for finding the .git
directory). Project root is searched after the current directory, but before the
home directory.
  • Loading branch information...
commit 559a8062bc98315a00e492899d2167955bcf3ca9 1 parent 28ba049
Mikhail Glushenkov authored November 05, 2012
8  README.markdown
Source Rendered
@@ -78,11 +78,13 @@ The tool is customizable to some extent. It tries to find a config file in the
78 78
 following order:
79 79
 
80 80
 1. A file passed to the tool using the `-c/--config` argument
81  
-2. `.stylish-haskell.yaml` in the current directory (useful for per-project
  81
+2. `.stylish-haskell.yaml` in the current directory (useful for per-directory
82 82
    settings)
83  
-3. `.stylish-haskell.yaml` in your home directory (useful for user-wide
  83
+3. `.stylish-haskell.yaml` in the nearest ancestor directory (useful for
  84
+   per-project settings)
  85
+4. `.stylish-haskell.yaml` in your home directory (useful for user-wide
84 86
    settings)
85  
-4. The default settings.
  87
+5. The default settings.
86 88
 
87 89
 Use `stylish-haskell --defaults > .stylish-haskell.yaml` to dump a
88 90
 well-documented default configuration to a file, this way you can get started
27  src/Language/Haskell/Stylish/Config.hs
@@ -16,12 +16,13 @@ import           Data.Aeson                             (FromJSON (..))
16 16
 import qualified Data.Aeson                             as A
17 17
 import qualified Data.Aeson.Types                       as A
18 18
 import qualified Data.ByteString                        as B
19  
-import           Data.List                              (intercalate)
  19
+import           Data.List                              (inits, intercalate)
20 20
 import           Data.Map                               (Map)
21 21
 import qualified Data.Map                               as M
22 22
 import           Data.Yaml                              (decodeEither)
23 23
 import           System.Directory
24  
-import           System.FilePath                        ((</>))
  24
+import           System.FilePath                        (joinPath, splitPath,
  25
+                                                         (</>))
25 26
 
26 27
 
27 28
 --------------------------------------------------------------------------------
@@ -71,16 +72,32 @@ defaultConfigFilePath = getDataFileName "data/stylish-haskell.yaml"
71 72
 --------------------------------------------------------------------------------
72 73
 configFilePath :: Verbose -> Maybe FilePath -> IO (Maybe FilePath)
73 74
 configFilePath verbose userSpecified = do
74  
-    (current, currentE) <- check $ (</> configFileName) <$> getCurrentDirectory
75  
-    (home, homeE)       <- check $ (</> configFileName) <$> getHomeDirectory
76  
-    (def, defE)         <- check defaultConfigFilePath
  75
+    (current, currentE)         <- check $ (</> configFileName) <$>
  76
+                                   getCurrentDirectory
  77
+    (projectRoot, projectRootE) <- checkUntilFound =<< (map (</> configFileName))
  78
+                                   <$> getAncestorDirectories
  79
+    (home, homeE)               <- check $ (</> configFileName) <$>
  80
+                                   getHomeDirectory
  81
+    (def, defE)                 <- check defaultConfigFilePath
77 82
     return $ msum
78 83
         [ userSpecified
79 84
         , if currentE then Just current else Nothing
  85
+        , if projectRootE then Just projectRoot else Nothing
80 86
         , if homeE then Just home else Nothing
81 87
         , if defE then Just def else Nothing
82 88
         ]
83 89
   where
  90
+    getAncestorDirectories :: IO [FilePath]
  91
+    getAncestorDirectories = map joinPath . reverse . drop 2
  92
+                             . inits . splitPath <$> getCurrentDirectory
  93
+
  94
+    checkUntilFound :: [FilePath] -> IO (FilePath, Bool)
  95
+    checkUntilFound []     = return ("", False)
  96
+    checkUntilFound (f:fs) = do
  97
+      res@(_, ex) <- check (return f)
  98
+      if ex then return res else checkUntilFound fs
  99
+
  100
+    check :: IO FilePath -> IO (FilePath, Bool)
84 101
     check fp = do
85 102
         fp' <- fp
86 103
         ex  <- doesFileExist fp'

0 notes on commit 559a806

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