language-puppet 1.3.5.1 → 1.3.6
raw patch · 9 files changed
+128/−26 lines, 9 files
Files
- CHANGELOG.markdown +6/−0
- Facter.hs +10/−8
- Puppet/Interpreter.hs +1/−0
- Puppet/Interpreter/Resolve.hs +24/−14
- Puppet/Stdlib.hs +3/−3
- language-puppet.cabal +3/−1
- tests/Function/DeleteAtSpec.hs +36/−0
- tests/Interpreter/IfSpec.hs +41/−0
- tests/Spec.hs +4/−0
CHANGELOG.markdown view
@@ -1,3 +1,9 @@+# v1.3.6 (UNRELEASED)++* The `defined` function can now test variables+* Fixed the `delete_at` function, added new tests, TBC+* Fixed the `ensure_resource` function, so that its second argument can take an array.+ # v1.3.5.1 (2017/02/02) * Version bumps for megaparsec & servant
Facter.hs view
@@ -110,14 +110,16 @@ | otherwise = takeWhile (/= '.') lrelease osfam | distid == "Ubuntu" = "Debian" | otherwise = distid- return [ ("lsbdistid" , distid)- , ("operatingsystem" , distid)- , ("lsbdistrelease" , lrelease)- , ("operatingsystemrelease" , lrelease)- , ("lsbmajdistrelease" , maj)- , ("osfamily" , osfam)- , ("lsbdistcodename" , getval "DISTRIB_CODENAME")- , ("lsbdistdescription" , getval "DISTRIB_DESCRIPTION")+ return [ ("lsbdistid" , distid)+ , ("operatingsystem" , distid)+ , ("lsbdistrelease" , lrelease)+ , ("operatingsystemrelease" , lrelease)+ , ("operatingsystemmajrelease" , lrelease)+ , ("lsbmajdistrelease" , maj)+ , ("lsbminordistrelease" , "")+ , ("osfamily" , osfam)+ , ("lsbdistcodename" , getval "DISTRIB_CODENAME")+ , ("lsbdistdescription" , getval "DISTRIB_DESCRIPTION") ] factMountPoints :: IO [(String, String)]
Puppet/Interpreter.hs view
@@ -911,6 +911,7 @@ checkStrict "The use of the 'ensure_resource' function is a code smell." "The 'ensure_resource' function is not allowed in strict mode." ensureResource' t params title+ensureResource [t, PArray arr, params] = concat <$> mapM (\r -> ensureResource [t, r, params]) (V.toList arr) ensureResource [t,title] = ensureResource [t,title,PHash mempty] ensureResource [_, PString _, PHash _] = throwPosError "ensureResource(): The first argument must be a string." ensureResource [PString _, _, PHash _] = throwPosError "ensureResource(): The second argument must be a string."
Puppet/Interpreter/Resolve.hs view
@@ -61,7 +61,7 @@ import qualified Data.Text.Encoding as T import Data.Tuple.Strict as S import qualified Data.Vector as V-import Data.Version (parseVersion)+import Data.Version (parseVersion, Version(..)) import Text.ParserCombinators.ReadP (readP_to_S) import qualified Text.PrettyPrint.ANSI.Leijen as PP import Text.Regex.PCRE.ByteString.Utils@@ -263,7 +263,7 @@ checkStrict ("Look up for an hash with the unknown key '" <> ttext ridx <> "' for" <+> pretty (PHash h)) ("Can't find index '" <> ttext ridx <> "' in" <+> pretty (PHash h))- return "undef"+ return PUndef PArray ar -> do ridx <- resolveExpression idx i <- case ridx ^? _Integer of@@ -421,15 +421,24 @@ checkStrict "The use of the 'defined' function is a code smell." "The 'defined' function is not allowed in strict mode." t <- resolvePValueString ut- -- case 1, netsted thingie- nestedStuff <- use nestedDeclarations- if has (ix (TopDefine, t)) nestedStuff || has (ix (TopClass, t)) nestedStuff- then return (PBoolean True)- else do -- case 2, loadeded class- lc <- use loadedClasses- if has (ix t) lc+ if (not (T.null t) && T.head t == '$') -- variable test+ then do+ scps <- use scopes+ scp <- getScopeName+ return $ PBoolean $ case getVariable scps scp (T.tail t) of+ Left _ -> False+ Right _ -> True+ else do -- resource test+ -- case 1, nested thingie+ nestedStuff <- use nestedDeclarations+ if has (ix (TopDefine, t)) nestedStuff || has (ix (TopClass, t)) nestedStuff then return (PBoolean True)- else fmap PBoolean (isNativeType t)+ else do -- case 2, loaded class+ lc <- use loadedClasses+ if has (ix t) lc+ then return (PBoolean True)+ else fmap PBoolean (isNativeType t)+ resolveFunction' "defined" x = throwPosError ("defined(): expects a single resource reference, type or class name, and not" <+> pretty x) resolveFunction' "fail" x = throwPosError ("fail:" <+> pretty x) resolveFunction' "inline_template" [] = throwPosError "inline_template(): Expects at least one argument"@@ -497,14 +506,15 @@ a <- resolvePValueString pa b <- resolvePValueString pb let parser x = case filter (null . Prelude.snd) (readP_to_S parseVersion (T.unpack x)) of- ( (v, _) : _ ) -> return v- _ -> throwPosError ("Could not parse this string as a version:" <+> ttext x)- va <- parser a- vb <- parser b+ ( (v, _) : _ ) -> v+ _ -> Version [] [] -- fallback :(+ va = parser a+ vb = parser b return $ PString $ case compare va vb of EQ -> "0" LT -> "-1" GT -> "1"+ resolveFunction' "versioncmp" _ = throwPosError "versioncmp(): Expects two arguments" -- some custom functions resolveFunction' "pdbresourcequery" [q] = pdbresourcequery q Nothing
Puppet/Stdlib.hs view
@@ -55,8 +55,8 @@ -- dos2unix , ("downcase", stringArrayFunction T.toLower) , singleArgument "empty" _empty- -- ensure_packages- -- ensure_resource+ -- ensure_packages (in main interpreter module)+ -- ensure_resource (in main interpreter module) , singleArgument "flatten" flatten -- floor -- fqdn_rand_string@@ -264,7 +264,7 @@ lr = V.length r s1 = V.slice 0 n r s2 = V.slice (n+1) (lr - n - 1) r- in if V.length r >= n+ in if V.length r <= n then throwPosError ("delete_at(): Out of bounds access detected, tried to remove index" <+> pretty z <+> "wheras the array only has" <+> string (show lr) <+> "elements") else return (PArray (s1 <> s2)) _ -> throwPosError ("delete_at(): The second argument must be an integer, not" <+> pretty z)
language-puppet.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: language-puppet-version: 1.3.5.1+version: 1.3.6 synopsis: Tools to parse and evaluate the Puppet DSL. description: This is a set of tools that is supposed to fill all your Puppet needs : syntax checks, catalog compilation, PuppetDB queries, simulationg of complex interactions between nodes, Puppet master replacement, and more ! homepage: http://lpuppet.banquise.net/@@ -179,10 +179,12 @@ Function.SizeSpec Function.MergeSpec Function.EachSpec+ Function.DeleteAtSpec Function.AssertPrivateSpec Function.JoinKeysToValuesSpec InterpreterSpec Interpreter.CollectorSpec+ Interpreter.IfSpec Helpers main-is: Spec.hs
+ tests/Function/DeleteAtSpec.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE OverloadedLists #-}+module Function.DeleteAtSpec (spec, main) where++import Test.Hspec++import Data.Monoid++import Puppet.Interpreter.Pure+import Puppet.Interpreter.Types++import Helpers++main :: IO ()+main = hspec spec++spec :: Spec+spec = withStdlibFunction "delete_at" $ \deleteAtFunc -> do+ let evalArgs' = dummyEval . deleteAtFunc+ narray = PArray . fmap PNumber+ check a b res = case evalArgs' [narray a, PNumber b] of+ Left rr -> expectationFailure (show rr)+ Right res' -> res' `shouldBe` narray res+ checkError args ins = case evalArgs' args of+ Left rr -> show rr `shouldContain` ins+ Right r -> expectationFailure ("Should have errored, received this instead: " <> show r)+ it "should error with invalid arguments" $ do+ checkError [] "expects 2 arguments"+ checkError [PNumber 1] "expects 2 arguments"+ checkError ["foo", "bar"] "expects its first argument to be an array"+ checkError [ narray [0,1,2], PNumber 3 ] "Out of bounds access"+ it "should work otherwise" $ do+ check [0,1,2] 1 [0,2]+ it "should work for negative positions" $ do+ pending+ check [0,1,2] (-1) [0,1]+ check [0,1,2] (-4) [0,1,2]
+ tests/Interpreter/IfSpec.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE OverloadedLists #-}+-- | Directly ported from puppet specs+module Interpreter.IfSpec (spec) where++import Test.Hspec++import Control.Lens+import Control.Monad.Except+import Data.Text (Text)+import qualified Data.Text as T++import Helpers+import Puppet.Interpreter.Types++{-+shouldReturn :: [Text] -> [PValue] -> Expectation+shouldReturn content expectedMessages = do+ cat <- case runExcept (getCatalog (T.unlines content)) of+ Left rr -> fail rr+ Right x -> return x+ _foo cat+-}++shouldFail :: [Text] -> Expectation+shouldFail content = let cat :: Either String FinalCatalog+ cat = runExcept (getCatalog (T.unlines content))+ in cat `shouldSatisfy` has _Left++shouldNotFail :: [Text] -> Expectation+shouldNotFail content = let cat :: Either String FinalCatalog+ cat = runExcept (getCatalog (T.unlines content))+ in cat `shouldSatisfy` has _Right++spec :: Spec+spec = do+ it "doesn't enter false conditions" $ shouldNotFail+ [ "if (false) { fail ':(' }" ]+ it "enters true conditions" $ shouldFail+ [ "if (true) { fail ':(' }" ]+ it "not (unknown variable) is true" $ shouldFail+ [ "if (!$::unknown123) { fail ':(' }" ]
tests/Spec.hs view
@@ -8,6 +8,8 @@ import qualified Function.EachSpec import qualified Function.AssertPrivateSpec import qualified Function.JoinKeysToValuesSpec+import qualified Function.DeleteAtSpec+import qualified Interpreter.IfSpec main :: IO () main = hspec spec@@ -18,6 +20,7 @@ describe "Collector" InterpreterSpec.collectorSpec describe "Class include" InterpreterSpec.classIncludeSpec describe "Collector (puppet tests)" Interpreter.CollectorSpec.spec+ describe "If" Interpreter.IfSpec.spec describe "Puppet functions" $ do describe "The shellquote function" Function.ShellquoteSpec.spec describe "The each function" Function.EachSpec.spec@@ -26,3 +29,4 @@ describe "The join_keys_to_values function" Function.JoinKeysToValuesSpec.spec describe "The merge function" Function.MergeSpec.spec describe "The size function" Function.SizeSpec.spec+ describe "The delete_at function" Function.DeleteAtSpec.spec