Add ext/.waspignore file (#196)

This commit is contained in:
Craig McIlwrath 2021-03-03 03:35:27 -05:00 committed by GitHub
parent 875db3207b
commit 82ea947981
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 141 additions and 2 deletions

View File

@ -0,0 +1,3 @@
# Ignore editor tmp files
**/*~
**/#*#

View File

@ -0,0 +1,3 @@
# Ignore editor tmp files
**/*~
**/#*#

View File

@ -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|]

View File

@ -0,0 +1,3 @@
# Ignore editor tmp files
**/*~
**/#*#

View File

@ -61,6 +61,7 @@ library:
- bytestring
- regex-tdfa
- utf8-string
- Glob
executables:
wasp:

View File

@ -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.

View 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

View 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)