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

More lenient version check #257

Merged
merged 2 commits into from Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion flake.nix
Expand Up @@ -18,13 +18,14 @@
};

drvAttrs = attrs: with pkgs; {
# TODO: lock down coreutils paths too
NIX = nix;
GIT = git;
HUB = gitAndTools.hub;
JQ = jq;
TREE = tree;
GIST = gist;
# TODO: are there more coreutils paths that need locking down?
TIMEOUT = coreutils;
NIXPKGSREVIEW = (import nixpkgs-review { inherit pkgs; });
};

Expand Down
38 changes: 27 additions & 11 deletions src/Check.hs
Expand Up @@ -6,11 +6,13 @@

module Check
( result,
-- exposed for testing:
hasVersion
)
where

import Control.Applicative (many)
import Data.Char (isSpace)
import Data.Char (isDigit, isLetter)
import Data.Maybe (fromJust)
import qualified Data.Text as T
import Language.Haskell.TH.Env (envQ)
Expand All @@ -36,18 +38,33 @@ gistBin = fromJust ($$(envQ "GIST") :: Maybe String) <> "/bin/gist"
procGist :: [String] -> ProcessConfig () () ()
procGist = proc gistBin

timeoutBin :: String
timeoutBin = fromJust ($$(envQ "TIMEOUT") :: Maybe String) <> "/bin/timeout"

data BinaryCheck = BinaryCheck
{ filePath :: FilePath,
zeroExitCode :: Bool,
versionPresent :: Bool
}

-- | Construct regex: [^\.]*${version}\.*\s*
isWordCharacter :: Char -> Bool
isWordCharacter c = (isDigit c) || (isLetter c)

isNonWordCharacter :: Char -> Bool
isNonWordCharacter c = not (isWordCharacter c)

-- | Construct regex: /.*\b${version}\b.*/s
versionRegex :: Text -> RE' ()
versionRegex version =
(\_ _ _ _ -> ()) <$> many (RE.psym (/= '.')) <*> RE.string version
<*> many (RE.sym '.')
<*> many (RE.psym isSpace)
(\_ -> ()) <$> (
(((many RE.anySym) <* (RE.psym isNonWordCharacter)) <|> (RE.pure ""))
*> (RE.string version) <*
((RE.pure "") <|> ((RE.psym isNonWordCharacter) *> (many RE.anySym)))
)

hasVersion :: Text -> Text -> Bool
hasVersion contents expectedVersion =
isJust $ contents =~ versionRegex expectedVersion

checkTestsBuild :: Text -> IO Bool
checkTestsBuild attrPath =
Expand All @@ -71,15 +88,14 @@ checkBinary argument expectedVersion program = do
eResult <-
runExceptT $
withSystemTempDirectory
("nixpkgs-update-" <> program)
"nixpkgs-update"
( ourLockedDownReadProcessInterleaved $
shell ("timeout -k 2 1 " <> program <> " " <> T.unpack argument)
shell (timeoutBin <> " -k 2 1 " <> program <> " " <> T.unpack argument)
)
case eResult of
Left (_ :: Text) -> return $ BinaryCheck program False False
Right (exitCode, contents) -> do
let hasVersion = isJust $ contents =~ versionRegex expectedVersion
return $ BinaryCheck program (exitCode == ExitSuccess) hasVersion
Right (exitCode, contents) ->
return $ BinaryCheck program (exitCode == ExitSuccess) (hasVersion contents expectedVersion)

checks :: [Version -> FilePath -> IO BinaryCheck]
checks =
Expand Down Expand Up @@ -213,7 +229,7 @@ result updateEnv resultPath =
then
( do
fs <- listDirectory binaryDir
filterM doesFileExist fs
filterM doesFileExist (map (\f -> binaryDir ++ "/" ++ f) fs)
)
else return []
checks' <- forM binaries $ \binary -> runChecks expectedVersion binary
Expand Down
27 changes: 27 additions & 0 deletions test/CheckSpec.hs
@@ -0,0 +1,27 @@
module CheckSpec where

import qualified Data.Text as T
import Test.Hspec
import qualified Check

main :: IO ()
main = hspec spec

spec :: Spec
spec = do
describe "version check" do
let seaweedVersion234 = T.pack "version 30GB 2.34 linux amd64"
it "finds the version when present" do
Check.hasVersion (T.pack "The version is 2.34") (T.pack "2.34") `shouldBe` True
Check.hasVersion (T.pack "The version is 2.34.") (T.pack "2.34") `shouldBe` True
Check.hasVersion (T.pack "2.34 is the version") (T.pack "2.34") `shouldBe` True
Check.hasVersion seaweedVersion234 (T.pack "2.34") `shouldBe` True

it "doesn't produce false positives" do
Check.hasVersion (T.pack "The version is 12.34") (T.pack "2.34") `shouldBe` False
Check.hasVersion (T.pack "The version is 2.345") (T.pack "2.34") `shouldBe` False
Check.hasVersion (T.pack "The version is 2.35") (T.pack "2.34") `shouldBe` False
Check.hasVersion (T.pack "2.35 is the version") (T.pack "2.34") `shouldBe` False
Check.hasVersion (T.pack "2.345 is the version") (T.pack "2.34") `shouldBe` False
Check.hasVersion (T.pack "12.34 is the version") (T.pack "2.34") `shouldBe` False
Check.hasVersion seaweedVersion234 (T.pack "2.35") `shouldBe` False