mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-11-23 01:54:37 +03:00
Add ext/.waspignore file (#196)
This commit is contained in:
parent
875db3207b
commit
82ea947981
3
examples/realworld/ext/.waspignore
Normal file
3
examples/realworld/ext/.waspignore
Normal file
@ -0,0 +1,3 @@
|
||||
# Ignore editor tmp files
|
||||
**/*~
|
||||
**/#*#
|
3
examples/tutorials/TodoApp/ext/.waspignore
Normal file
3
examples/tutorials/TodoApp/ext/.waspignore
Normal file
@ -0,0 +1,3 @@
|
||||
# Ignore editor tmp files
|
||||
**/*~
|
||||
**/#*#
|
@ -41,6 +41,8 @@ createNewProject projectName = do
|
||||
|
||||
let copyTemplateFile' = copyTemplateFile dataDir extCodeDir
|
||||
|
||||
writeFileSP (extCodeDir </> waspignoreFileInExtCodeDir) waspignoreFileContent
|
||||
|
||||
copyTemplateFile'
|
||||
(SP.fromPathRelFile [P.relfile|new/ext/MainPage.js|])
|
||||
mainPageJsFileInExtCodeDir
|
||||
@ -95,6 +97,15 @@ createNewProject projectName = do
|
||||
gitignoreFileContent = unlines
|
||||
[ "/.wasp/"
|
||||
]
|
||||
|
||||
waspignoreFileInExtCodeDir :: Path (Rel SourceExternalCodeDir) File
|
||||
waspignoreFileInExtCodeDir = SP.fromPathRelFile [P.relfile|.waspignore|]
|
||||
|
||||
waspignoreFileContent = unlines
|
||||
[ "# Ignore editor tmp files"
|
||||
, "**/*~"
|
||||
, "**/#*#"
|
||||
]
|
||||
|
||||
mainPageJsFileInExtCodeDir :: Path (Rel SourceExternalCodeDir) File
|
||||
mainPageJsFileInExtCodeDir = SP.fromPathRelFile [P.relfile|MainPage.js|]
|
||||
|
3
waspc/examples/todoApp/ext/.waspignore
Normal file
3
waspc/examples/todoApp/ext/.waspignore
Normal file
@ -0,0 +1,3 @@
|
||||
# Ignore editor tmp files
|
||||
**/*~
|
||||
**/#*#
|
@ -61,6 +61,7 @@ library:
|
||||
- bytestring
|
||||
- regex-tdfa
|
||||
- utf8-string
|
||||
- Glob
|
||||
|
||||
executables:
|
||||
wasp:
|
||||
|
@ -13,10 +13,12 @@ import qualified Data.Text.Lazy as TextL
|
||||
import qualified Data.Text.Lazy.IO as TextL.IO
|
||||
import Data.Maybe (catMaybes)
|
||||
import Data.Text (Text)
|
||||
import qualified Path as P
|
||||
|
||||
import qualified Util.IO
|
||||
import StrongPath (Path, Abs, Rel, Dir, (</>))
|
||||
import qualified StrongPath as SP
|
||||
import WaspignoreFile (readWaspignoreFile, ignores)
|
||||
|
||||
-- | External code directory in Wasp source, from which external code files are read.
|
||||
data SourceExternalCodeDir
|
||||
@ -45,10 +47,18 @@ fileText = TextL.toStrict . _text
|
||||
fileAbsPath :: ExternalCode.File -> Path Abs SP.File
|
||||
fileAbsPath file = _extCodeDirPath file </> _pathInExtCodeDir file
|
||||
|
||||
-- | Returns all files contained in the specified external code dir, recursively.
|
||||
waspignorePathInExtCodeDir :: Path (Rel SourceExternalCodeDir) SP.File
|
||||
waspignorePathInExtCodeDir = SP.fromPathRelFile [P.relfile|.waspignore|]
|
||||
|
||||
-- | Returns all files contained in the specified external code dir, recursively,
|
||||
-- except files ignores by the specified waspignore file.
|
||||
readFiles :: Path Abs (Dir SourceExternalCodeDir) -> IO [File]
|
||||
readFiles extCodeDirPath = do
|
||||
relFilePaths <- Util.IO.listDirectoryDeep (SP.toPathAbsDir extCodeDirPath) >>= return . (map SP.fromPathRelFile)
|
||||
let waspignoreFilePath = extCodeDirPath </> waspignorePathInExtCodeDir
|
||||
waspignoreFile <- readWaspignoreFile waspignoreFilePath
|
||||
relFilePaths <- filter (not . ignores waspignoreFile . SP.toFilePath) .
|
||||
map SP.fromPathRelFile <$>
|
||||
Util.IO.listDirectoryDeep (SP.toPathAbsDir extCodeDirPath)
|
||||
let absFilePaths = map (extCodeDirPath </>) relFilePaths
|
||||
-- NOTE: We read text from all the files, regardless if they are text files or not, because
|
||||
-- we don't know if they are a text file or not.
|
||||
|
70
waspc/src/WaspignoreFile.hs
Normal file
70
waspc/src/WaspignoreFile.hs
Normal file
@ -0,0 +1,70 @@
|
||||
module WaspignoreFile
|
||||
( WaspignoreFile
|
||||
, parseWaspignoreFile
|
||||
, readWaspignoreFile
|
||||
, ignores
|
||||
) where
|
||||
|
||||
import Control.Exception (catch)
|
||||
import System.IO.Error (isDoesNotExistError)
|
||||
import StrongPath (Path, Abs, File, toFilePath)
|
||||
import System.FilePath.Glob (Pattern, compile, match)
|
||||
|
||||
newtype WaspignoreFile = WaspignoreFile [Pattern]
|
||||
|
||||
-- | These patterns are ignored by every 'WaspignoreFile'
|
||||
defaultIgnorePatterns :: [Pattern]
|
||||
defaultIgnorePatterns = map compile [".waspignore"]
|
||||
|
||||
-- | Parses a string to a 'WaspignoreFile'.
|
||||
--
|
||||
-- An ignore file contains lines that are one of:
|
||||
-- * blank
|
||||
-- * comments (starting with '#')
|
||||
-- * a pattern
|
||||
--
|
||||
-- An ignore file always ignores `.waspignore`.
|
||||
--
|
||||
-- Patterns are glob 'Pattern's, for full details "System.FilePath.Glob". A
|
||||
-- brief description is:
|
||||
--
|
||||
-- [@?@] Matches any single character except slashes.
|
||||
-- [@*@] Matches a string of at least 1 character, excluding slashes.
|
||||
-- [@[xyz\]@] Matches a single character in the set `xyz`.
|
||||
-- [@[^xyz\]@] Matches a single character not in the set `xyz`.
|
||||
-- [@**/@] Matches a string of at least 1 character, including slashes.
|
||||
parseWaspignoreFile :: String -> WaspignoreFile
|
||||
parseWaspignoreFile = WaspignoreFile .
|
||||
(defaultIgnorePatterns++) .
|
||||
map compile .
|
||||
filter isPatternLine .
|
||||
lines
|
||||
where
|
||||
isPatternLine :: String -> Bool
|
||||
isPatternLine [] = False
|
||||
isPatternLine ('#':_) = False
|
||||
isPatternLine _ = True
|
||||
|
||||
-- | Reads and parses the wasp ignore file. See 'parseWaspignoreFile' for details of
|
||||
-- the file format, but it is very similar to `.gitignore`'s format.
|
||||
--
|
||||
-- If the ignore file does not exist, it is interpreted as a blank file.
|
||||
readWaspignoreFile :: Path Abs File -> IO WaspignoreFile
|
||||
readWaspignoreFile fp = do
|
||||
text <- readFile (toFilePath fp)
|
||||
`catch` (\e -> if isDoesNotExistError e then return ""
|
||||
else ioError e)
|
||||
return $ parseWaspignoreFile text
|
||||
|
||||
-- | Tests whether a file should be ignored according to a 'WaspignoreFile'.
|
||||
--
|
||||
-- Example:
|
||||
--
|
||||
-- @
|
||||
-- let ignoreFile = parseWaspignoreFile "**/*.tmp"
|
||||
-- ignoreFile `ignores` "out.tmp" -- True
|
||||
-- ignoreFile `ignores` "src/a.tmp" -- True
|
||||
-- ignoreFile `ignores` "src/a.js" -- False
|
||||
-- @
|
||||
ignores :: WaspignoreFile -> FilePath -> Bool
|
||||
ignores (WaspignoreFile pats) fp = any (`match` fp) pats
|
38
waspc/test/WaspignoreFileTest.hs
Normal file
38
waspc/test/WaspignoreFileTest.hs
Normal file
@ -0,0 +1,38 @@
|
||||
module WaspignoreFileTest where
|
||||
|
||||
import Test.Tasty.Hspec
|
||||
import Test.Tasty.QuickCheck (property)
|
||||
|
||||
import WaspignoreFile (parseWaspignoreFile, ignores)
|
||||
|
||||
spec_IgnoreFile :: Spec
|
||||
spec_IgnoreFile = do
|
||||
describe "IgnoreFile" $ do
|
||||
it "When given a single pattern, should match it and '.waspignore'" $ do
|
||||
let ignoreFile = parseWaspignoreFile "*.tmp"
|
||||
(ignoreFile `ignores` "a.tmp") `shouldBe` True
|
||||
(ignoreFile `ignores` "a.src") `shouldBe` False
|
||||
(ignoreFile `ignores` ".waspignore") `shouldBe` True
|
||||
|
||||
it "When given a blank input, should match only '.waspignore'" $ do
|
||||
let ignoreFile = parseWaspignoreFile ""
|
||||
property $ \fp -> if fp == ".waspignore"
|
||||
then ignoreFile `ignores` fp
|
||||
else not $ ignoreFile `ignores` fp
|
||||
|
||||
it "When given a comment as the only line, should match only '.waspignore'" $ do
|
||||
let ignoreFile = parseWaspignoreFile "# test comment"
|
||||
property $ \fp -> if fp == ".waspignore"
|
||||
then ignoreFile `ignores` fp
|
||||
else not $ ignoreFile `ignores` fp
|
||||
|
||||
it "When the only difference between two files is a comment, the files should match the same strings" $ do
|
||||
let comment = "\n# test comment"
|
||||
property $ \pat fp -> (parseWaspignoreFile pat `ignores` fp) ==
|
||||
(parseWaspignoreFile (pat ++ comment) `ignores` fp)
|
||||
|
||||
it "When given 2 patterns, should match the path if either of the patterns match" $ do
|
||||
let pat1 = parseWaspignoreFile "a"
|
||||
let pat2 = parseWaspignoreFile "b"
|
||||
let patBoth = parseWaspignoreFile "a\nb"
|
||||
property $ \fp -> patBoth `ignores` fp == (pat1 `ignores` fp || pat2 `ignores` fp)
|
Loading…
Reference in New Issue
Block a user