diff --git a/CHANGES.md b/CHANGES.md index c6cf32e6..b14f135b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -56,6 +56,8 @@ Unreleased + Now Xrefcheck is able to follow relative redirects. * [#262](https://github.com/serokell/xrefcheck/pull/262) + Now Xrefcheck includes a scanner that verifies the repository symlinks. +* [#307](https://github.com/serokell/xrefcheck/pull/307) + + The output of Xrefcheck is now more legible. 0.2.2 ========== diff --git a/docs/output-sample.png b/docs/output-sample.png new file mode 100644 index 00000000..040c2e7a Binary files /dev/null and b/docs/output-sample.png differ diff --git a/docs/output-sample/output-sample.png b/docs/output-sample/output-sample.png index 139cf287..d70d6d42 100644 Binary files a/docs/output-sample/output-sample.png and b/docs/output-sample/output-sample.png differ diff --git a/package.yaml b/package.yaml index 0dd6b026..d5dfed8e 100644 --- a/package.yaml +++ b/package.yaml @@ -93,6 +93,7 @@ library: - filepath - fmt - ftp-client + - crypton-connection - Glob - http-client - http-types diff --git a/src/Xrefcheck/CLI.hs b/src/Xrefcheck/CLI.hs index 58d7094f..8922e25f 100644 --- a/src/Xrefcheck/CLI.hs +++ b/src/Xrefcheck/CLI.hs @@ -208,7 +208,7 @@ exclusionOptionsParser :: Parser ExclusionOptions exclusionOptionsParser = do eoIgnore <- many . globOption $ long "ignore" <> - metavar "GLOB PATTERN" <> + metavar "GLOB_PATTERN" <> help "Ignore these files. References to them will fail verification,\ \ and references from them will not be verified.\ \ Glob patterns that contain wildcards MUST be enclosed\ @@ -237,7 +237,7 @@ dumpConfigOptions = hsubparser $ option repoTypeReadM $ short 't' <> long "type" <> - metavar "REPOSITORY TYPE" <> + metavar "REPOSITORY_TYPE" <> help [int|| Git repository type. \ Can be (#{intercalate " | " $ map show allFlavors}). \ diff --git a/src/Xrefcheck/Command.hs b/src/Xrefcheck/Command.hs index 415df6bb..8b8a0129 100644 --- a/src/Xrefcheck/Command.hs +++ b/src/Xrefcheck/Command.hs @@ -92,7 +92,8 @@ defaultAction Options{..} = do verifyRepo rw fullConfig oMode repoInfo case verifyErrors verifyRes of - Nothing | null scanErrs -> fmtLn "All repository links are valid." + Nothing | null scanErrs -> + fmtLn $ colorIfNeeded Green "All repository links are valid." Nothing -> exitFailure Just verifyErrs -> do unless (null scanErrs) $ fmt "\n" diff --git a/src/Xrefcheck/Core.hs b/src/Xrefcheck/Core.hs index 9519e1ac..06537623 100644 --- a/src/Xrefcheck/Core.hs +++ b/src/Xrefcheck/Core.hs @@ -60,13 +60,11 @@ instance FromJSON Flavor where -- | Description of element position in source file. -- We keep this in text because scanners for different formats use different -- representation of this thing, and it actually appears in reports only. -newtype Position = Position (Maybe Text) +newtype Position = Position Text deriving stock (Show, Eq, Generic) -instance Given ColorMode => Buildable Position where - build (Position pos) = case pos of - Nothing -> "" - Just p -> styleIfNeeded Faint $ "at src:" <> build p +instance Buildable Position where + build (Position pos) = build pos -- | Full info about a reference. data Reference = Reference @@ -235,46 +233,41 @@ instance Given ColorMode => Buildable Reference where case rifLink of FLLocal -> [int|| - reference #{paren $ colorIfNeeded Green "file-local"}#{posSep}#{rPos}: + reference #{paren $ colorIfNeeded Green "file-local"} at #{rPos}: - text: #s{rName} - anchor: #{rifAnchor ?: styleIfNeeded Faint "-"} |] FLRelative link -> [int|| - reference #{paren $ colorIfNeeded Yellow "relative"}#{posSep}#{rPos}: + reference #{paren $ colorIfNeeded Yellow "relative"} at #{rPos}: - text: #s{rName} - link: #{link} - anchor: #{rifAnchor ?: styleIfNeeded Faint "-"} |] FLAbsolute link -> [int|| - reference #{paren $ colorIfNeeded Yellow "absolute"}#{posSep}#{rPos}: + reference #{paren $ colorIfNeeded Yellow "absolute"} at #{rPos}: - text: #s{rName} - link: /#{link} - anchor: #{rifAnchor ?: styleIfNeeded Faint "-"} |] RIExternal (ELUrl url) -> [int|| - reference #{paren $ colorIfNeeded Red "external"}#{posSep}#{rPos}: + reference #{paren $ colorIfNeeded Red "external"} at #{rPos}: - text: #s{rName} - link: #{url} |] RIExternal (ELOther url) -> [int|| - reference (other)#{posSep}#{rPos}: + reference (other) at #{rPos}: - text: #s{rName} - link: #{url} |] - where - posSep :: Text - posSep = case rPos of - Position Nothing -> "" - _ -> " " instance Given ColorMode => Buildable AnchorType where build = styleIfNeeded Faint . \case HeaderAnchor l -> colorIfNeeded Green ("header " <> headerLevelToRoman l) - HandAnchor -> colorIfNeeded Yellow "hand made" + HandAnchor -> colorIfNeeded Yellow "handmade" BiblioAnchor -> colorIfNeeded Cyan "biblio" where headerLevelToRoman = \case @@ -289,7 +282,7 @@ instance Given ColorMode => Buildable AnchorType where instance Given ColorMode => Buildable Anchor where build Anchor{..} = [int|| - #{aName} (#{aType}) #{aPos} + #{aName} (#{aType}) at #{aPos} |] instance Given ColorMode => Buildable FileInfo where diff --git a/src/Xrefcheck/Scan.hs b/src/Xrefcheck/Scan.hs index f6a910b7..874ff0f1 100644 --- a/src/Xrefcheck/Scan.hs +++ b/src/Xrefcheck/Scan.hs @@ -37,7 +37,7 @@ import Control.Lens (_1, makeLensesWith, (%~)) import Data.Aeson (FromJSON (..), genericParseJSON, withText) import Data.Map qualified as M import Data.Reflection (Given) -import Fmt (Buildable (..), fmt) +import Fmt (Buildable (..), Builder, fmtLn) import System.Directory (doesDirectoryExist, pathIsSymbolicLink) import System.Process (cwd, readCreateProcess, shell) import Text.Interpolation.Nyan @@ -120,23 +120,20 @@ mkGatherScanError seFile ScanError{sePosition, seDescription} = ScanError , seDescription } -instance Given ColorMode => Buildable (ScanError 'Gather) where - build ScanError{..} = [int|| - In file #{styleIfNeeded Faint (styleIfNeeded Bold seFile)} - scan error #{sePosition}: - - #{seDescription} - - |] +pprScanErr :: Given ColorMode => ScanError 'Gather -> Builder +pprScanErr ScanError{..} = hdr <> "\n" <> interpolateIndentF 2 msg <> "\n" + where + hdr, msg :: Builder + hdr = + styleIfNeeded Bold (build sePosition <> ": ") <> + colorIfNeeded Red "scan error:" + msg = build seDescription reportScanErrs :: Given ColorMode => NonEmpty (ScanError 'Gather) -> IO () -reportScanErrs errs = fmt - [int|| - === Scan errors found === - - #{interpolateIndentF 2 (interpolateBlockListF' "➥ " build errs)} - Scan errors dumped, #{length errs} in total. - |] +reportScanErrs errs = do + traverse_ (fmtLn . pprScanErr) errs + fmtLn $ colorIfNeeded Red $ + "Scan errors dumped, " <> build (length errs) <> " in total." data ScanErrorDescription = LinkErr @@ -152,8 +149,8 @@ instance Buildable ScanErrorDescription where markdown or right after comments at the top|] ParagraphErr txt -> [int||Expected a PARAGRAPH after \ "ignore paragraph" annotation, but found #{txt}|] - UnrecognisedErr txt -> [int||Unrecognised option "#{txt}" perhaps you meant \ - <"ignore link"|"ignore paragraph"|"ignore all">|] + UnrecognisedErr txt -> [int||Unrecognised option "#{txt}" + Perhaps you meant <"ignore link"|"ignore paragraph"|"ignore all">|] firstFileSupport :: [FileSupport] -> FileSupport firstFileSupport fs isSymlink = diff --git a/src/Xrefcheck/Scanners/Markdown.hs b/src/Xrefcheck/Scanners/Markdown.hs index d3cc6962..534da570 100644 --- a/src/Xrefcheck/Scanners/Markdown.hs +++ b/src/Xrefcheck/Scanners/Markdown.hs @@ -52,17 +52,17 @@ instance Buildable Node where build (Node _mpos ty mSubs) = nameF (show ty) $ maybe "[]" interpolateBlockListF (nonEmpty mSubs) -toPosition :: Maybe PosInfo -> Position -toPosition = Position . \case - Nothing -> Nothing +toPosition :: FilePath -> Maybe PosInfo -> Position +toPosition filepath = Position . \case + Nothing -> [int|s|#{filepath}|] Just PosInfo{..} - | startLine == endLine -> Just + | startLine == endLine -> [int|s| - #{startLine}:#{startColumn}-#{endColumn} + #{filepath}:#{startLine}:#{startColumn}-#{endColumn} |] - | otherwise -> Just + | otherwise -> [int|s| - #{startLine}:#{startColumn}-#{endLine}:#{endColumn} + #{filepath}:#{startLine}:#{startColumn}-#{endLine}:#{endColumn} |] -- | Extract text from the topmost node. @@ -154,9 +154,10 @@ cataNodeWithParentNodeInfo f node = cataNode f' node -- | Find ignore annotations (ignore paragraph and ignore link) -- and remove nodes that should be ignored. -removeIgnored :: Node -> Writer [ScanError 'Parse] Node -removeIgnored = withIgnoreMode . cataNodeWithParentNodeInfo remove - where +removeIgnored :: Node -> ExtractorM Node +removeIgnored rootNode = do + filepath <- asks ecFilePath + let remove :: Maybe PosInfo -> NodeType @@ -167,7 +168,7 @@ removeIgnored = withIgnoreMode . cataNodeWithParentNodeInfo remove scan <- use ssIgnore >>= \case -- When no `Ignore` state is set check next node for annotation, -- if found then set it as new `IgnoreMode` otherwise skip node. - Nothing -> handleIgnoreMode pos ty subs $ getIgnoreMode node + Nothing -> handleIgnoreMode pos ty subs $ getIgnoreMode node Just (Ignore mode modePos) -> case (mode, ty) of -- We expect to find a paragraph immediately after the @@ -175,7 +176,7 @@ removeIgnored = withIgnoreMode . cataNodeWithParentNodeInfo remove -- found we should report an error. (IMSParagraph, PARAGRAPH) -> (ssIgnore .= Nothing) $> defNode (IMSParagraph, x) -> do - lift . tell . makeError modePos . ParagraphErr $ prettyType x + lift . tell $ makeError filepath modePos (ParagraphErr (prettyType x)) ssIgnore .= Nothing Node pos ty <$> sequence subs @@ -184,7 +185,7 @@ removeIgnored = withIgnoreMode . cataNodeWithParentNodeInfo remove -- the file should already be ignored when `checkIgnoreFile` is called. -- We should report an error if we find it anyway. (IMSAll, _) -> do - lift . tell $ makeError modePos FileErr + lift . tell $ makeError filepath modePos FileErr ssIgnore .= Nothing Node pos ty <$> sequence subs @@ -202,14 +203,14 @@ removeIgnored = withIgnoreMode . cataNodeWithParentNodeInfo remove currentIgnore <- use ssIgnore case currentIgnore of Just (Ignore {_ignoreMode = IMSLink ParentExpectsLink}) -> do - lift $ tell $ makeError modePos LinkErr + lift $ tell $ makeError filepath modePos LinkErr ssIgnore .= Nothing _ -> pass return node' when (ty == PARAGRAPH) $ use ssIgnore >>= \case Just (Ignore (IMSLink ExpectingLinkInParagraph) pragmaPos) -> - lift $ tell $ makeError pragmaPos LinkErr + lift $ tell $ makeError filepath pragmaPos LinkErr _ -> pass return scan @@ -233,7 +234,7 @@ removeIgnored = withIgnoreMode . cataNodeWithParentNodeInfo remove (ssIgnore .= Just (Ignore ignoreModeState correctPos)) $> defNode InvalidMode msg -> do - lift . tell $ makeError correctPos $ UnrecognisedErr msg + lift . tell $ makeError filepath correctPos $ UnrecognisedErr msg (ssIgnore .= Nothing) $> defNode NotAnAnnotation -> Node pos nodeType <$> sequence subs where @@ -244,24 +245,26 @@ removeIgnored = withIgnoreMode . cataNodeWithParentNodeInfo remove let mType = safeHead $ words $ show ty in fromMaybe "" mType - withIgnoreMode - :: ScannerM Node - -> Writer [ScanError 'Parse] Node - withIgnoreMode action = action `runStateT` initialScannerState >>= \case - -- We expect `Ignore` state to be `Nothing` when we reach EOF, - -- otherwise that means there was an annotation that didn't match - -- any node, so we have to report that. - (node, ScannerState {_ssIgnore = Just (Ignore mode pos)}) -> case mode of + action :: ScannerM Node + action = cataNodeWithParentNodeInfo remove rootNode + + (node, s) <- lift $ runStateT action initialScannerState + case s of + -- We expect `Ignore` state to be `Nothing` when we reach EOF, + -- otherwise that means there was an annotation that didn't match + -- any node, so we have to report that. + ScannerState {_ssIgnore = Just (Ignore mode pos)} -> do + case mode of IMSParagraph -> do - tell . makeError pos $ ParagraphErr "EOF" + lift $ tell . makeError filepath pos $ ParagraphErr "EOF" pure node IMSLink _ -> do - tell $ makeError pos LinkErr + lift $ tell $ makeError filepath pos LinkErr pure node IMSAll -> do - tell $ makeError pos FileErr + lift $ tell $ makeError filepath pos FileErr pure node - (node, _) -> pure node + _ -> pure node -- | Custom `foldMap` for source tree. foldNode :: (Monoid a, Monad m) => (Node -> m a) -> Node -> m a @@ -270,27 +273,33 @@ foldNode action node@(Node _ _ subs) = do b <- concatForM subs (foldNode action) return (a <> b) -type ExtractorM a = ReaderT MarkdownConfig (Writer [ScanError 'Parse]) a +data ExtractorCtx = ExtractorCtx + { ecConfig :: MarkdownConfig + , ecFilePath :: FilePath + } + +type ExtractorM a = ReaderT ExtractorCtx (Writer [ScanError 'Parse]) a -- | Extract information from source tree. nodeExtractInfo :: Node -> ExtractorM FileInfo nodeExtractInfo input@(Node _ _ nSubs) = do if checkIgnoreAllFile nSubs then return (diffToFileInfo mempty) - else diffToFileInfo <$> (foldNode extractor =<< lift (removeIgnored input)) + else diffToFileInfo <$> (foldNode extractor =<< removeIgnored input) where extractor :: Node -> ExtractorM FileInfoDiff - extractor node@(Node pos ty _) = + extractor node@(Node pos ty _) = do + filepath <- asks ecFilePath case ty of HTML_BLOCK _ -> do return mempty HEADING lvl -> do - flavor <- asks mcFlavor + flavor <- asks (mcFlavor . ecConfig) let aType = HeaderAnchor lvl let aName = headerToAnchor flavor $ nodeExtractText node - let aPos = toPosition pos + let aPos = toPosition filepath pos return $ FileInfoDiff DList.empty $ DList.singleton $ Anchor {aType, aName, aPos} HTML_INLINE text -> do @@ -307,7 +316,7 @@ nodeExtractInfo input@(Node _ _ nSubs) = do case mName of Just aName -> do let aType = HandAnchor - aPos = toPosition pos + aPos = toPosition filepath pos return $ FileInfoDiff mempty (pure $ Anchor {aType, aName, aPos}) @@ -323,8 +332,9 @@ nodeExtractInfo input@(Node _ _ nSubs) = do where extractLink url = do + filepath <- asks ecFilePath let rName = nodeExtractText node - rPos = toPosition pos + rPos = toPosition filepath pos rInfo = referenceInfo $ if null url then rName else url return $ FileInfoDiff @@ -351,10 +361,12 @@ defNode :: Node defNode = Node Nothing DOCUMENT [] -- hard-coded default Node makeError - :: Maybe PosInfo + :: FilePath + -> Maybe PosInfo -> ScanErrorDescription -> [ScanError 'Parse] -makeError pos errDescription = one $ mkParseScanError (toPosition pos) errDescription +makeError filepath pos errDescription = + one $ mkParseScanError (toPosition filepath pos) errDescription getCommentContent :: Node -> Maybe Text getCommentContent node = do @@ -396,18 +408,21 @@ textToMode ("ignore" : [x]) | otherwise = InvalidMode x textToMode _ = NotAnAnnotation -parseFileInfo :: MarkdownConfig -> LT.Text -> (FileInfo, [ScanError 'Parse]) -parseFileInfo config input +parseFileInfo :: MarkdownConfig -> FilePath -> LT.Text -> (FileInfo, [ScanError 'Parse]) +parseFileInfo config filepath input = runWriter - $ flip runReaderT config + $ flip runReaderT (ExtractorCtx config filepath) $ nodeExtractInfo $ commonmarkToNode [optFootnotes] [extAutolink] $ toStrict input markdownScanner :: MarkdownConfig -> ScanAction -markdownScanner config root file = - parseFileInfo config . decodeUtf8 - <$> BSL.readFile (filePathFromRoot root file) +markdownScanner config root relativePath = + parseFileInfo config expandedPath . decodeUtf8 + <$> BSL.readFile expandedPath + where + rootedPath = filePathFromRoot root relativePath + expandedPath = (toString . expandPosixIndirections . fromString) rootedPath markdownSupport :: MarkdownConfig -> FileSupport markdownSupport config isSymlink extension = do diff --git a/src/Xrefcheck/Scanners/Symlink.hs b/src/Xrefcheck/Scanners/Symlink.hs index de6a575f..5090ce2c 100644 --- a/src/Xrefcheck/Scanners/Symlink.hs +++ b/src/Xrefcheck/Scanners/Symlink.hs @@ -20,12 +20,14 @@ import Xrefcheck.Scan import Xrefcheck.System symlinkScanner :: ScanAction -symlinkScanner root path = do +symlinkScanner root relativePath = do + let rootedPath = filePathFromRoot root relativePath + expandedPath = (toString . expandPosixIndirections . fromString) rootedPath rLink <- unRelPosixLink . mkRelPosixLink - <$> getSymbolicLinkTarget (filePathFromRoot root path) + <$> getSymbolicLinkTarget rootedPath let rName = "Symbolic Link" - rPos = Position Nothing + rPos = Position (fromString expandedPath) rInfo = referenceInfo rLink pure (FileInfo [Reference {rName, rPos, rInfo}] [], []) diff --git a/src/Xrefcheck/System.hs b/src/Xrefcheck/System.hs index 49a286c2..538b6481 100644 --- a/src/Xrefcheck/System.hs +++ b/src/Xrefcheck/System.hs @@ -9,6 +9,7 @@ module Xrefcheck.System , RelPosixLink (..) , () , mkRelPosixLink + , expandPosixIndirections , filePathFromRoot , getIntermediateDirs , hasBackslash diff --git a/src/Xrefcheck/Verify.hs b/src/Xrefcheck/Verify.hs index e8c4fcbc..b131d850 100644 --- a/src/Xrefcheck/Verify.hs +++ b/src/Xrefcheck/Verify.hs @@ -46,9 +46,10 @@ import Data.Text.Metrics (damerauLevenshteinNorm) import Data.Time (UTCTime, defaultTimeLocale, formatTime, readPTime, rfc822DateFormat) import Data.Time.Clock.POSIX (getPOSIXTime) import Data.Traversable (for) -import Fmt (Buildable (..), Builder, fmt, maybeF, nameF) +import Fmt (Buildable (..), Builder, fmt, fmtLn, maybeF, nameF) import GHC.Exts qualified as Exts import GHC.Read (Read (readPrec)) +import Network.Connection qualified as N.C import Network.FTP.Client (FTPException (..), FTPResponse (..), ResponseStatus (..), login, nlst, size, withFTP, withFTPS) import Network.HTTP.Client @@ -107,13 +108,6 @@ data WithReferenceLoc a = WithReferenceLoc , wrlItem :: a } -instance (Given ColorMode, Buildable a) => Buildable (WithReferenceLoc a) where - build WithReferenceLoc{..} = [int|| - In file #{styleIfNeeded Faint (styleIfNeeded Bold wrlFile)} - bad #{wrlReference} - #{wrlItem} - |] - -- | Contains a name of a domain, examples: -- @DomainName "github.com"@, -- @DomainName "localhost"@, @@ -137,6 +131,7 @@ data VerifyError | ExternalFtpException FTPException | FtpEntryDoesNotExist FilePath | ExternalResourceSomeError Text + | ExternalResourceConnectionFailure | RedirectChainCycle RedirectChain | RedirectMissingLocation RedirectChain | RedirectChainLimit RedirectChain @@ -147,8 +142,8 @@ data ResponseResult = RRDone | RRFollow Text -instance Given ColorMode => Buildable VerifyError where - build = \case +pprVerifyErr' :: Given ColorMode => ReferenceInfo -> VerifyError -> Builder +pprVerifyErr' rInfo = \case LocalFileDoesNotExist file -> [int|| File does not exist: @@ -161,15 +156,15 @@ instance Given ColorMode => Buildable VerifyError where LocalFileOutsideRepo file -> [int|| - Link targets a local file outside repository: + Link #{pprLinkTyp rInfo} targets a local file outside the repository: #{file} |] LinkTargetNotAddedToGit file -> [int|| - Link target is not tracked by Git: + Link #{pprLinkTyp rInfo} targets a file not tracked by Git: #{file} - Please run "git add" before running xrefcheck or enable --include-untracked CLI option. + Please run "git add" before running xrefcheck or enable --include-untracked CLI option. |] AnchorDoesNotExist anchor similar -> case nonEmpty similar of @@ -180,70 +175,70 @@ instance Given ColorMode => Buildable VerifyError where Just otherAnchors -> [int|| Anchor '#{anchor}' is not present, did you mean: - #{interpolateIndentF 4 $ interpolateBlockListF otherAnchors} + #{interpolateIndentF 2 $ interpolateBlockListF otherAnchors} |] AmbiguousAnchorRef file anchor fileAnchors -> [int|| Ambiguous reference to anchor '#{anchor}' - In file #{file} - It could refer to either: - #{interpolateIndentF 4 $ interpolateBlockListF fileAnchors} - Use of ambiguous anchors is discouraged because the target - can change silently while the document containing it evolves. + in file #{file} + It could refer to either: + #{interpolateIndentF 2 $ interpolateBlockListF fileAnchors} + Use of ambiguous anchors is discouraged because the target + can change silently while the document containing it evolves. |] ExternalResourceUriParseError (UPEInvalid err) -> [int|| Invalid URI (#{err}) - |] + |] <> pprLinkCtx rInfo ExternalResourceUriParseError (UPEConversion err) -> [int|| Invalid URI - #{interpolateIndentF 4 . build $ displayException err} - |] + #{interpolateIndentF 2 . build $ displayException err} + |] <> pprLinkCtx rInfo ExternalResourceInvalidUrl Nothing -> [int|| Invalid URL - |] + |] <> pprLinkCtx rInfo ExternalResourceInvalidUrl (Just message) -> [int|| Invalid URL (#{message}) - |] + |] <> pprLinkCtx rInfo ExternalResourceUnknownProtocol -> [int|| Bad url (expected 'http','https', 'ftp' or 'ftps') - |] + |] <> pprLinkCtx rInfo ExternalHttpResourceUnavailable status -> [int|| Resource unavailable (#{statusCode status} #{decodeUtf8 @Text (statusMessage status)}) - |] + |] <> pprLinkCtx rInfo ExternalHttpTooManyRequests retryAfter _ -> [int|| Resource unavailable (429 Too Many Requests; retry after #{maybeF retryAfter}) - |] + |] <> pprLinkCtx rInfo ExternalHttpTimeout _ -> [int|| Response timeout - |] + |] <> pprLinkCtx rInfo ExternalFtpResourceUnavailable response -> [int|| Resource unavailable: #{response} - |] + |] <> pprLinkCtx rInfo ExternalFtpException err -> [int|| FTP exception (#{err}) - |] + |] <> pprLinkCtx rInfo FtpEntryDoesNotExist entry -> [int|| @@ -254,31 +249,36 @@ instance Given ColorMode => Buildable VerifyError where ExternalResourceSomeError err -> [int|| #{err} - |] + |] <> pprLinkCtx rInfo + + ExternalResourceConnectionFailure -> + [int|| + Connection failure + |] <> pprLinkCtx rInfo RedirectChainCycle chain -> [int|| Cycle found in the following redirect chain: #{interpolateIndentF 2 $ attachToRedirectChain chain "here"} - |] + |] <> pprLinkCtx rInfo RedirectMissingLocation chain -> [int|| Missing location header in the following redirect chain: #{interpolateIndentF 2 $ attachToRedirectChain chain "no location header"} - |] + |] <> pprLinkCtx rInfo RedirectChainLimit chain -> [int|| The follow redirects limit has been reached in the following redirect chain: #{interpolateIndentF 2 $ attachToRedirectChain chain "stopped before this one"} - |] + |] <> pprLinkCtx rInfo RedirectRuleError chain mOn -> [int|| #{redirect} found: #{interpolateIndentF 2 $ attachToRedirectChain chain "stopped before this one"} - |] + |] <> pprLinkCtx rInfo where redirect :: Text redirect = case mOn of @@ -304,15 +304,52 @@ incTotalCounter rc = rc {rcTotalRetries = rcTotalRetries rc + 1} incTimeoutCounter :: RetryCounter -> RetryCounter incTimeoutCounter rc = rc {rcTimeoutRetries = rcTimeoutRetries rc + 1} +pprVerifyErr :: Given ColorMode => WithReferenceLoc VerifyError -> Builder +pprVerifyErr wrl = hdr <> "\n" <> interpolateIndentF 2 msg + where + WithReferenceLoc{wrlReference, wrlItem} = wrl + Reference{rName, rInfo} = wrlReference + + hdr, msg :: Builder + hdr = + styleIfNeeded Bold (build (rPos wrlReference) <> ": ") <> + colorIfNeeded Red "bad reference:" + msg = + "The reference to " <> show rName <> " failed verification.\n" <> + pprVerifyErr' rInfo wrlItem + +pprLink :: Given ColorMode => ReferenceInfo -> Maybe Builder +pprLink = \case + RIFile ReferenceInfoFile{..} -> + case rifLink of + FLLocal -> Nothing + FLRelative link -> Just $ "a " <> styleIfNeeded Faint "relative" <> " link: " <> build link + FLAbsolute link -> Just $ "a " <> styleIfNeeded Faint "absolute" <> " link: " <> build link + RIExternal (ELUrl url) -> Just $ "an " <> styleIfNeeded Faint "external" <> " link: " <> build url + RIExternal (ELOther url) -> Just $ "a link: " <> build url + +pprLinkTyp :: Given ColorMode => ReferenceInfo -> Builder +pprLinkTyp rInfo = + paren $ styleIfNeeded Faint $ case rInfo of + RIFile ReferenceInfoFile{rifLink} -> + case rifLink of + FLLocal -> "file-local" + FLRelative _ -> "relative" + FLAbsolute _ -> "absolute" + RIExternal _ -> "external" + +pprLinkCtx :: Given ColorMode => ReferenceInfo -> Builder +pprLinkCtx rInfo = + case pprLink rInfo of + Nothing -> mempty + Just b -> "when processing " <> b <> "\n" + reportVerifyErrs :: Given ColorMode => NonEmpty (WithReferenceLoc VerifyError) -> IO () -reportVerifyErrs errs = fmt - [int|| - === Invalid references found === - - #{interpolateIndentF 2 (interpolateBlockListF' "➥ " build errs)} - Invalid references dumped, #{length errs} in total. - |] +reportVerifyErrs errs = do + traverse_ (fmtLn . pprVerifyErr) errs + fmtLn $ colorIfNeeded Red $ + "Invalid references dumped, " <> build (length errs) <> " in total." data RetryAfter = Date UTCTime | Seconds (Time Second) deriving stock (Show, Eq) @@ -708,7 +745,7 @@ checkExternalResource followed config@Config{..} link let maxTime = Time @Second $ unTime ncExternalRefCheckTimeout * timeoutFrac reqRes <- catch (liftIO (timeout maxTime $ reqLink $> RRDone)) $ - (Just <$>) <$> interpretErrors uri + (Just <$>) <$> interpretHttpErrors uri case reqRes of Nothing -> throwError $ ExternalHttpTimeout $ extractHost uri @@ -730,9 +767,13 @@ checkExternalResource followed config@Config{..} link , (405 ==) -- method mismatch ] - interpretErrors uri = \case + interpretHttpErrors :: URI -> Network.HTTP.Req.HttpException -> ExceptT VerifyError IO ResponseResult + interpretHttpErrors uri = \case JsonHttpException _ -> error "External link JSON parse exception" - VanillaHttpException err -> case err of + VanillaHttpException err -> interpretHttpErrors' uri err + + interpretHttpErrors' :: URI -> Network.HTTP.Client.HttpException -> ExceptT VerifyError IO ResponseResult + interpretHttpErrors' uri = \case InvalidUrlException{} -> error "External link URL invalid exception" HttpExceptionRequest _ exc -> case exc of StatusCodeException resp _ @@ -765,6 +806,12 @@ checkExternalResource followed config@Config{..} link redirectLocation = fmap decodeUtf8 . lookup "Location" $ responseHeaders resp + + ConnectionFailure _ -> throwError ExternalResourceConnectionFailure + InternalException e + | Just (N.C.HostCannotConnect _ _) <- fromException e + -> throwError ExternalResourceConnectionFailure + other -> throwError $ ExternalResourceSomeError $ show other where retryAfterInfo :: Response a -> Maybe RetryAfter diff --git a/tests/golden/check-anchors/expected1.gold b/tests/golden/check-anchors/expected1.gold index 22a065b8..d1ae7c2a 100644 --- a/tests/golden/check-anchors/expected1.gold +++ b/tests/golden/check-anchors/expected1.gold @@ -1,32 +1,23 @@ -=== Invalid references found === +ambiguous-anchors/a.md:16:1-43: bad reference: + The reference to "ambiguous anchor in this file" failed verification. + Ambiguous reference to anchor 'some-text' + in file a.md + It could refer to either: + - some-text (header I) at ambiguous-anchors/a.md:6:1-11 + - some-text (header I) at ambiguous-anchors/a.md:8:1-15 + - some-text (header II) at ambiguous-anchors/a.md:12:1-12 + Use of ambiguous anchors is discouraged because the target + can change silently while the document containing it evolves. - ➥ In file a.md - bad reference (file-local) at src:16:1-43: - - text: "ambiguous anchor in this file" - - anchor: some-text - - Ambiguous reference to anchor 'some-text' - In file a.md - It could refer to either: - - some-text (header I) at src:6:1-11 - - some-text (header I) at src:8:1-15 - - some-text (header II) at src:12:1-12 - Use of ambiguous anchors is discouraged because the target - can change silently while the document containing it evolves. - - ➥ In file b.md - bad reference (relative) at src:7:1-48: - - text: "ambiguous anchor in other file" - - link: a.md - - anchor: some-text - - Ambiguous reference to anchor 'some-text' - In file a.md - It could refer to either: - - some-text (header I) at src:6:1-11 - - some-text (header I) at src:8:1-15 - - some-text (header II) at src:12:1-12 - Use of ambiguous anchors is discouraged because the target - can change silently while the document containing it evolves. +ambiguous-anchors/b.md:7:1-48: bad reference: + The reference to "ambiguous anchor in other file" failed verification. + Ambiguous reference to anchor 'some-text' + in file a.md + It could refer to either: + - some-text (header I) at ambiguous-anchors/a.md:6:1-11 + - some-text (header I) at ambiguous-anchors/a.md:8:1-15 + - some-text (header II) at ambiguous-anchors/a.md:12:1-12 + Use of ambiguous anchors is discouraged because the target + can change silently while the document containing it evolves. Invalid references dumped, 2 in total. diff --git a/tests/golden/check-anchors/expected2.gold b/tests/golden/check-anchors/expected2.gold index 0e4d0b23..529fb283 100644 --- a/tests/golden/check-anchors/expected2.gold +++ b/tests/golden/check-anchors/expected2.gold @@ -1,27 +1,16 @@ -=== Invalid references found === +non-existing-anchors/a.md:12:1-13: bad reference: + The reference to "broken" failed verification. + Anchor 'h3' is not present, did you mean: + - h1 (header I) at non-existing-anchors/a.md:6:1-4 + - h2 (header II) at non-existing-anchors/a.md:8:1-5 - ➥ In file a.md - bad reference (file-local) at src:12:1-13: - - text: "broken" - - anchor: h3 +non-existing-anchors/a.md:14:1-18: bad reference: + The reference to "broken" failed verification. + Anchor 'heading' is not present, did you mean: + - the-heading (header I) at non-existing-anchors/a.md:10:1-13 - Anchor 'h3' is not present, did you mean: - - h1 (header I) at src:6:1-4 - - h2 (header II) at src:8:1-5 - - ➥ In file a.md - bad reference (file-local) at src:14:1-18: - - text: "broken" - - anchor: heading - - Anchor 'heading' is not present, did you mean: - - the-heading (header I) at src:10:1-13 - - ➥ In file a.md - bad reference (file-local) at src:16:1-31: - - text: "broken" - - anchor: really-unique-anchor - - Anchor 'really-unique-anchor' is not present +non-existing-anchors/a.md:16:1-31: bad reference: + The reference to "broken" failed verification. + Anchor 'really-unique-anchor' is not present Invalid references dumped, 3 in total. diff --git a/tests/golden/check-autolinks/expected.gold b/tests/golden/check-autolinks/expected.gold index 6c5d93b0..7e22a4c2 100644 --- a/tests/golden/check-autolinks/expected.gold +++ b/tests/golden/check-autolinks/expected.gold @@ -2,25 +2,21 @@ file-with-autolinks.md: - references: - - reference (external): + - reference (external) at file-with-autolinks.md: - text: "https://www.google.com/doodles" - link: https://www.google.com/doodles - - reference (external) at src:8:0-18: + - reference (external) at file-with-autolinks.md:8:0-18: - text: "www.commonmark.org" - link: http://www.commonmark.org - anchors: none -=== Invalid references found === - - ➥ In file file-with-autolinks.md - bad reference (external) at src:8:0-18: - - text: "www.commonmark.org" - - link: http://www.commonmark.org - - Permanent redirect found: - -| http://www.commonmark.org - -> https://commonmark.org - ^-- stopped before this one +file-with-autolinks.md:8:0-18: bad reference: + The reference to "www.commonmark.org" failed verification. + Permanent redirect found: + -| http://www.commonmark.org + -> https://commonmark.org + ^-- stopped before this one + when processing an external link: http://www.commonmark.org Invalid references dumped, 1 in total. diff --git a/tests/golden/check-backslash/expected.gold b/tests/golden/check-backslash/expected.gold index f97bb61d..2fee0911 100644 --- a/tests/golden/check-backslash/expected.gold +++ b/tests/golden/check-backslash/expected.gold @@ -2,40 +2,34 @@ a.md: - references: - - reference (relative) at src:8:1-33: + - reference (relative) at a.md:8:1-33: - text: "Reference to a\\a" - link: a\a.md - anchor: header - - reference (relative) at src:10:1-30: + - reference (relative) at a.md:10:1-30: - text: "Bad reference to a\\b" - link: a\b.md - anchor: - - anchors: - - header (header I) at src:6:1-8 + - header (header I) at a.md:6:1-8 a\a.md: - references: - - reference (relative) at src:2:1-22: + - reference (relative) at a\a.md:2:1-22: - text: "Reference to a" - link: a.md - anchor: - - - reference (relative) at src:3:1-29: + - reference (relative) at a\a.md:3:1-29: - text: "Reference to myself" - link: a\a.md - anchor: - - anchors: - - header (header I) at src:1:1-8 + - header (header I) at a\a.md:1:1-8 -=== Invalid references found === - - ➥ In file a.md - bad reference (relative) at src:10:1-30: - - text: "Bad reference to a\\b" - - link: a\b.md - - anchor: - - - File does not exist: - a\b.md - Its reference contains a backslash. Maybe it uses the wrong path separator. +a.md:10:1-30: bad reference: + The reference to "Bad reference to a\\b" failed verification. + File does not exist: + a\b.md + Its reference contains a backslash. Maybe it uses the wrong path separator. Invalid references dumped, 1 in total. diff --git a/tests/golden/check-case-sensitivity-anchor/expected1.gold b/tests/golden/check-case-sensitivity-anchor/expected1.gold index 18629ce5..7c8a0464 100644 --- a/tests/golden/check-case-sensitivity-anchor/expected1.gold +++ b/tests/golden/check-case-sensitivity-anchor/expected1.gold @@ -1,28 +1,20 @@ -=== Invalid references found === +a.md:18:1-36: bad reference: + The reference to "Mixing case reference" failed verification. + Anchor 'SomE-HEADr' is not present, did you mean: + - some-header (header I) at a.md:6:1-13 + - another-header (header I) at a.md:10:1-16 + - custom-header (header I) at a.md:12:1-43 + - Another-header (handmade) at a.md:12:3-27 + - custom-header (header I) at a.md:14:1-43 - ➥ In file a.md - bad reference (file-local) at src:18:1-36: - - text: "Mixing case reference" - - anchor: SomE-HEADr - - Anchor 'SomE-HEADr' is not present, did you mean: - - some-header (header I) at src:6:1-13 - - another-header (header I) at src:10:1-16 - - custom-header (header I) at src:12:1-43 - - Another-header (hand made) at src:12:3-27 - - custom-header (header I) at src:14:1-43 - - ➥ In file a.md - bad reference (file-local) at src:24:1-44: - - text: "Maybe ambiguous reference" - - anchor: another-header - - Ambiguous reference to anchor 'another-header' - In file a.md - It could refer to either: - - another-header (header I) at src:10:1-16 - - Another-header (hand made) at src:12:3-27 - Use of ambiguous anchors is discouraged because the target - can change silently while the document containing it evolves. +a.md:24:1-44: bad reference: + The reference to "Maybe ambiguous reference" failed verification. + Ambiguous reference to anchor 'another-header' + in file a.md + It could refer to either: + - another-header (header I) at a.md:10:1-16 + - Another-header (handmade) at a.md:12:3-27 + Use of ambiguous anchors is discouraged because the target + can change silently while the document containing it evolves. Invalid references dumped, 2 in total. diff --git a/tests/golden/check-case-sensitivity-anchor/expected2.gold b/tests/golden/check-case-sensitivity-anchor/expected2.gold index 53e4cb35..290b0f0a 100644 --- a/tests/golden/check-case-sensitivity-anchor/expected2.gold +++ b/tests/golden/check-case-sensitivity-anchor/expected2.gold @@ -1,35 +1,24 @@ -=== Invalid references found === +a.md:16:1-37: bad reference: + The reference to "Mixing case reference" failed verification. + Anchor 'SomE-HEADer' is not present, did you mean: + - some-header (header I) at a.md:6:1-13 + - another-header (header I) at a.md:10:1-16 + - custom-header (header I) at a.md:12:1-43 + - Another-header (handmade) at a.md:12:3-27 + - custom-header (header I) at a.md:14:1-43 - ➥ In file a.md - bad reference (file-local) at src:16:1-37: - - text: "Mixing case reference" - - anchor: SomE-HEADer +a.md:18:1-36: bad reference: + The reference to "Mixing case reference" failed verification. + Anchor 'SomE-HEADr' is not present, did you mean: + - some-header (header I) at a.md:6:1-13 + - another-header (header I) at a.md:10:1-16 + - custom-header (header I) at a.md:12:1-43 + - Another-header (handmade) at a.md:12:3-27 + - custom-header (header I) at a.md:14:1-43 - Anchor 'SomE-HEADer' is not present, did you mean: - - some-header (header I) at src:6:1-13 - - another-header (header I) at src:10:1-16 - - custom-header (header I) at src:12:1-43 - - Another-header (hand made) at src:12:3-27 - - custom-header (header I) at src:14:1-43 - - ➥ In file a.md - bad reference (file-local) at src:18:1-36: - - text: "Mixing case reference" - - anchor: SomE-HEADr - - Anchor 'SomE-HEADr' is not present, did you mean: - - some-header (header I) at src:6:1-13 - - another-header (header I) at src:10:1-16 - - custom-header (header I) at src:12:1-43 - - Another-header (hand made) at src:12:3-27 - - custom-header (header I) at src:14:1-43 - - ➥ In file a.md - bad reference (file-local) at src:22:1-36: - - text: "Reference lowered" - - anchor: uppercase-name - - Anchor 'uppercase-name' is not present, did you mean: - - UPPERCASE-NAME (hand made) at src:14:3-27 +a.md:22:1-36: bad reference: + The reference to "Reference lowered" failed verification. + Anchor 'uppercase-name' is not present, did you mean: + - UPPERCASE-NAME (handmade) at a.md:14:3-27 Invalid references dumped, 3 in total. diff --git a/tests/golden/check-case-sensitivity-path/expected.gold b/tests/golden/check-case-sensitivity-path/expected.gold index c5d3bac7..24bc19c8 100644 --- a/tests/golden/check-case-sensitivity-path/expected.gold +++ b/tests/golden/check-case-sensitivity-path/expected.gold @@ -2,129 +2,99 @@ a.md: - references: - - reference (relative) at src:8:3-11: + - reference (relative) at a.md:8:3-11: - text: "a" - link: a.md - anchor: - - - reference (relative) at src:9:3-29: + - reference (relative) at a.md:9:3-29: - text: "Header a" - link: dir/b.md - anchor: header - - reference (relative) at src:10:3-15: + - reference (relative) at a.md:10:3-15: - text: "b" - link: dir/b.md - anchor: - - - reference (relative) at src:11:3-29: + - reference (relative) at a.md:11:3-29: - text: "Header b" - link: dir/b.md - anchor: header - - reference (relative) at src:12:3-17: + - reference (relative) at a.md:12:3-17: - text: "Wrong a" - link: A.md - anchor: - - - reference (relative) at src:13:3-27: + - reference (relative) at a.md:13:3-27: - text: "Wrong a extension" - link: a.Md - anchor: - - - reference (relative) at src:14:3-21: + - reference (relative) at a.md:14:3-21: - text: "Wrong b" - link: dir/B.md - anchor: - - - reference (absolute) at src:15:3-26: + - reference (absolute) at a.md:15:3-26: - text: "Wrong b dir" - link: /dIr/b.md - anchor: - - - reference (absolute) at src:16:3-32: + - reference (absolute) at a.md:16:3-32: - text: "Wrong b extension" - link: /dir/b.mD - anchor: - - anchors: - - header (header I) at src:6:1-8 + - header (header I) at a.md:6:1-8 dir/b.md: - references: - - reference (relative) at src:8:3-20: + - reference (relative) at dir/b.md:8:3-20: - text: "Right a" - link: ../a.md - anchor: - - - reference (relative) at src:9:3-19: + - reference (relative) at dir/b.md:9:3-19: - text: "Right b" - link: ./b.md - anchor: - - - reference (relative) at src:10:3-20: + - reference (relative) at dir/b.md:10:3-20: - text: "Wrong a" - link: ../A.md - anchor: - - - reference (relative) at src:11:3-19: + - reference (relative) at dir/b.md:11:3-19: - text: "Wrong b" - link: ./B.md - anchor: - - anchors: - - header (header I) at src:6:1-8 - -=== Invalid references found === - - ➥ In file a.md - bad reference (relative) at src:12:3-17: - - text: "Wrong a" - - link: A.md - - anchor: - - - File does not exist: - A.md - - ➥ In file a.md - bad reference (relative) at src:13:3-27: - - text: "Wrong a extension" - - link: a.Md - - anchor: - - - File does not exist: - a.Md - - ➥ In file a.md - bad reference (relative) at src:14:3-21: - - text: "Wrong b" - - link: dir/B.md - - anchor: - - - File does not exist: - dir/B.md - - ➥ In file a.md - bad reference (absolute) at src:15:3-26: - - text: "Wrong b dir" - - link: /dIr/b.md - - anchor: - - - File does not exist: - dIr/b.md - - ➥ In file a.md - bad reference (absolute) at src:16:3-32: - - text: "Wrong b extension" - - link: /dir/b.mD - - anchor: - - - File does not exist: - dir/b.mD - - ➥ In file dir/b.md - bad reference (relative) at src:10:3-20: - - text: "Wrong a" - - link: ../A.md - - anchor: - - - File does not exist: - dir/../A.md - - ➥ In file dir/b.md - bad reference (relative) at src:11:3-19: - - text: "Wrong b" - - link: ./B.md - - anchor: - - - File does not exist: - dir/./B.md + - header (header I) at dir/b.md:6:1-8 + +a.md:12:3-17: bad reference: + The reference to "Wrong a" failed verification. + File does not exist: + A.md + +a.md:13:3-27: bad reference: + The reference to "Wrong a extension" failed verification. + File does not exist: + a.Md + +a.md:14:3-21: bad reference: + The reference to "Wrong b" failed verification. + File does not exist: + dir/B.md + +a.md:15:3-26: bad reference: + The reference to "Wrong b dir" failed verification. + File does not exist: + dIr/b.md + +a.md:16:3-32: bad reference: + The reference to "Wrong b extension" failed verification. + File does not exist: + dir/b.mD + +dir/b.md:10:3-20: bad reference: + The reference to "Wrong a" failed verification. + File does not exist: + dir/../A.md + +dir/b.md:11:3-19: bad reference: + The reference to "Wrong b" failed verification. + File does not exist: + dir/./B.md Invalid references dumped, 7 in total. diff --git a/tests/golden/check-cli/expected1.gold b/tests/golden/check-cli/expected1.gold index 268089a2..1ee32281 100644 --- a/tests/golden/check-cli/expected1.gold +++ b/tests/golden/check-cli/expected1.gold @@ -1,12 +1,6 @@ -=== Invalid references found === - - ➥ In file to-ignore/broken-link.md - bad reference (absolute) at src:7:1-25: - - text: "my link" - - link: /one/two/three - - anchor: - - - File does not exist: - one/two/three +to-ignore/broken-link.md:7:1-25: bad reference: + The reference to "my link" failed verification. + File does not exist: + one/two/three Invalid references dumped, 1 in total. diff --git a/tests/golden/check-cli/expected2.gold b/tests/golden/check-cli/expected2.gold index 268089a2..e69de29b 100644 --- a/tests/golden/check-cli/expected2.gold +++ b/tests/golden/check-cli/expected2.gold @@ -1,12 +0,0 @@ -=== Invalid references found === - - ➥ In file to-ignore/broken-link.md - bad reference (absolute) at src:7:1-25: - - text: "my link" - - link: /one/two/three - - anchor: - - - File does not exist: - one/two/three - -Invalid references dumped, 1 in total. diff --git a/tests/golden/check-cli/expected3.gold b/tests/golden/check-cli/expected3.gold index 268089a2..1ee32281 100644 --- a/tests/golden/check-cli/expected3.gold +++ b/tests/golden/check-cli/expected3.gold @@ -1,12 +1,6 @@ -=== Invalid references found === - - ➥ In file to-ignore/broken-link.md - bad reference (absolute) at src:7:1-25: - - text: "my link" - - link: /one/two/three - - anchor: - - - File does not exist: - one/two/three +to-ignore/broken-link.md:7:1-25: bad reference: + The reference to "my link" failed verification. + File does not exist: + one/two/three Invalid references dumped, 1 in total. diff --git a/tests/golden/check-color/expected-color.gold b/tests/golden/check-color/expected-color.gold index 1add363a..d0352478 100644 --- a/tests/golden/check-color/expected-color.gold +++ b/tests/golden/check-color/expected-color.gold @@ -2,10 +2,10 @@ color.md: - references: - - reference (file-local) at src:9:1-15: + - reference (file-local) at color.md:9:1-15: - text: "Color" - anchor: Color - anchors: - - color (header I) at src:7:1-7 + - color (header I) at color.md:7:1-7 -All repository links are valid. +All repository links are valid. diff --git a/tests/golden/check-color/expected-no-color.gold b/tests/golden/check-color/expected-no-color.gold index 4d892eed..973dc433 100644 --- a/tests/golden/check-color/expected-no-color.gold +++ b/tests/golden/check-color/expected-no-color.gold @@ -2,10 +2,10 @@ color.md: - references: - - reference (file-local) at src:9:1-15: + - reference (file-local) at color.md:9:1-15: - text: "Color" - anchor: Color - anchors: - - color (header I) at src:7:1-7 + - color (header I) at color.md:7:1-7 All repository links are valid. diff --git a/tests/golden/check-footnotes/expected.gold b/tests/golden/check-footnotes/expected.gold index 5da88571..fe1b6e0e 100644 --- a/tests/golden/check-footnotes/expected.gold +++ b/tests/golden/check-footnotes/expected.gold @@ -1,12 +1,6 @@ -=== Invalid references found === - - ➥ In file file-with-footnote-with-broken-link.md - bad reference (relative) at src:8:9-43: - - text: "bad link in footnote" - - link: ./notExists - - anchor: - - - File does not exist: - ./notExists +broken-link-in-footnote/file-with-footnote-with-broken-link.md:8:9-43: bad reference: + The reference to "bad link in footnote" failed verification. + File does not exist: + ./notExists Invalid references dumped, 1 in total. diff --git a/tests/golden/check-git/expected1.gold b/tests/golden/check-git/expected1.gold index f0898822..851ec1a0 100644 --- a/tests/golden/check-git/expected1.gold +++ b/tests/golden/check-git/expected1.gold @@ -1,12 +1,6 @@ -=== Invalid references found === - - ➥ In file git.md - bad reference (relative) at src:1:1-11: - - text: "a" - - link: ./a.md - - anchor: - - - File does not exist: - ./a.md +git.md:1:1-11: bad reference: + The reference to "a" failed verification. + File does not exist: + ./a.md Invalid references dumped, 1 in total. diff --git a/tests/golden/check-git/expected2.gold b/tests/golden/check-git/expected2.gold index f0898822..851ec1a0 100644 --- a/tests/golden/check-git/expected2.gold +++ b/tests/golden/check-git/expected2.gold @@ -1,12 +1,6 @@ -=== Invalid references found === - - ➥ In file git.md - bad reference (relative) at src:1:1-11: - - text: "a" - - link: ./a.md - - anchor: - - - File does not exist: - ./a.md +git.md:1:1-11: bad reference: + The reference to "a" failed verification. + File does not exist: + ./a.md Invalid references dumped, 1 in total. diff --git a/tests/golden/check-git/expected3.gold b/tests/golden/check-git/expected3.gold index 5c6140e6..e4ada6f4 100644 --- a/tests/golden/check-git/expected3.gold +++ b/tests/golden/check-git/expected3.gold @@ -1,13 +1,7 @@ -=== Invalid references found === - - ➥ In file git.md - bad reference (relative) at src:1:1-11: - - text: "a" - - link: ./a.md - - anchor: - - - Link target is not tracked by Git: - ./a.md - Please run "git add" before running xrefcheck or enable --include-untracked CLI option. +git.md:1:1-11: bad reference: + The reference to "a" failed verification. + Link (relative) targets a file not tracked by Git: + ./a.md + Please run "git add" before running xrefcheck or enable --include-untracked CLI option. Invalid references dumped, 1 in total. diff --git a/tests/golden/check-ignore/expected1.gold b/tests/golden/check-ignore/expected1.gold index 864a9b18..e447d074 100644 --- a/tests/golden/check-ignore/expected1.gold +++ b/tests/golden/check-ignore/expected1.gold @@ -1,8 +1,4 @@ -=== Scan errors found === - - ➥ In file to-ignore/inner-directory/broken_annotation.md - scan error at src:9:1-29: - - Annotation "ignore all" must be at the top of markdown or right after comments at the top +to-ignore/inner-directory/broken_annotation.md:9:1-29: scan error: + Annotation "ignore all" must be at the top of markdown or right after comments at the top Scan errors dumped, 1 in total. diff --git a/tests/golden/check-ignore/expected2.gold b/tests/golden/check-ignore/expected2.gold index 7fc99c69..c4a6044f 100644 --- a/tests/golden/check-ignore/expected2.gold +++ b/tests/golden/check-ignore/expected2.gold @@ -1,21 +1,11 @@ -=== Scan errors found === - - ➥ In file to-ignore/inner-directory/broken_annotation.md - scan error at src:9:1-29: - - Annotation "ignore all" must be at the top of markdown or right after comments at the top +to-ignore/inner-directory/broken_annotation.md:9:1-29: scan error: + Annotation "ignore all" must be at the top of markdown or right after comments at the top Scan errors dumped, 1 in total. -=== Invalid references found === - - ➥ In file check-ignore.md - bad reference (absolute) at src:7:1-37: - - text: "Good reference" - - link: /referenced-file.md - - anchor: - - - File does not exist: - referenced-file.md +check-ignore.md:7:1-37: bad reference: + The reference to "Good reference" failed verification. + File does not exist: + referenced-file.md Invalid references dumped, 1 in total. diff --git a/tests/golden/check-ignoreExternalRefsTo/check-ignoreExternalRefsTo.bats b/tests/golden/check-ignoreExternalRefsTo/check-ignoreExternalRefsTo.bats index e7afaa95..c129130b 100644 --- a/tests/golden/check-ignoreExternalRefsTo/check-ignoreExternalRefsTo.bats +++ b/tests/golden/check-ignoreExternalRefsTo/check-ignoreExternalRefsTo.bats @@ -18,18 +18,7 @@ load '../helpers' } @test "Ignore localhost, check errors" { - uname_out=$(uname) - case "${uname_out}" in - Linux*) platform_suffix=linux;; - Darwin*) platform_suffix=darwin;; - CYGWIN*) platform_suffix=windows;; - MINGW*) platform_suffix=windows;; - MSYS_NT*) platform_suffix=windows;; - *) machine="UNKNOWN:${unameOut}" - esac - echo "platform_suffix=${platform_suffix}" - - golden_file=$(realpath expected_${platform_suffix}.gold) + golden_file=$(realpath expected.gold) to_temp xrefcheck \ -c config-check-enabled.yaml \ diff --git a/tests/golden/check-ignoreExternalRefsTo/expected.gold b/tests/golden/check-ignoreExternalRefsTo/expected.gold new file mode 100644 index 00000000..84f54719 --- /dev/null +++ b/tests/golden/check-ignoreExternalRefsTo/expected.gold @@ -0,0 +1,21 @@ +check-ignoreExternalRefsTo.md:7:10-53: bad reference: + The reference to "web-site" failed verification. + Connection failure + when processing an external link: https://localhost:20000/web-site + +check-ignoreExternalRefsTo.md:9:10-45: bad reference: + The reference to "team" failed verification. + Connection failure + when processing an external link: https://127.0.0.1:20000/team + +check-ignoreExternalRefsTo.md:11:10-44: bad reference: + The reference to "blog" failed verification. + Connection failure + when processing an external link: http://localhost:20000/blog + +check-ignoreExternalRefsTo.md:13:10-44: bad reference: + The reference to "labs" failed verification. + Connection failure + when processing an external link: http://127.0.0.1:20000/labs + +Invalid references dumped, 4 in total. diff --git a/tests/golden/check-ignoreExternalRefsTo/expected_linux.gold b/tests/golden/check-ignoreExternalRefsTo/expected_linux.gold deleted file mode 100644 index 25a1dd1b..00000000 --- a/tests/golden/check-ignoreExternalRefsTo/expected_linux.gold +++ /dev/null @@ -1,31 +0,0 @@ -=== Invalid references found === - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:7:10-53: - - text: "web-site" - - link: https://localhost:20000/web-site - - InternalException (HostCannotConnect "localhost" [Network.Socket.connect: : does not exist (Connection refused)]) - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:9:10-45: - - text: "team" - - link: https://127.0.0.1:20000/team - - InternalException (HostCannotConnect "127.0.0.1" [Network.Socket.connect: : does not exist (Connection refused)]) - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:11:10-44: - - text: "blog" - - link: http://localhost:20000/blog - - ConnectionFailure Network.Socket.connect: : does not exist (Connection refused) - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:13:10-44: - - text: "labs" - - link: http://127.0.0.1:20000/labs - - ConnectionFailure Network.Socket.connect: : does not exist (Connection refused) - -Invalid references dumped, 4 in total. diff --git a/tests/golden/check-ignoreExternalRefsTo/expected_windows.gold b/tests/golden/check-ignoreExternalRefsTo/expected_windows.gold deleted file mode 100644 index 06cf5edd..00000000 --- a/tests/golden/check-ignoreExternalRefsTo/expected_windows.gold +++ /dev/null @@ -1,31 +0,0 @@ -=== Invalid references found === - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:7:10-53: - - text: "web-site" - - link: https://localhost:20000/web-site - - InternalException (HostCannotConnect "localhost" [Network.Socket.connect: : failed (Connection refused (WSAECONNREFUSED)),Network.Socket.connect: : failed (Connection refused (WSAECONNREFUSED))]) - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:9:10-45: - - text: "team" - - link: https://127.0.0.1:20000/team - - InternalException (HostCannotConnect "127.0.0.1" [Network.Socket.connect: : failed (Connection refused (WSAECONNREFUSED))]) - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:11:10-44: - - text: "blog" - - link: http://localhost:20000/blog - - ConnectionFailure Network.Socket.connect: : failed (Connection refused (WSAECONNREFUSED)) - - ➥ In file check-ignoreExternalRefsTo.md - bad reference (external) at src:13:10-44: - - text: "labs" - - link: http://127.0.0.1:20000/labs - - ConnectionFailure Network.Socket.connect: : failed (Connection refused (WSAECONNREFUSED)) - -Invalid references dumped, 4 in total. diff --git a/tests/golden/check-ignoreLocalRefsTo/expected.gold b/tests/golden/check-ignoreLocalRefsTo/expected.gold index a2d8e536..37d7b8b2 100644 --- a/tests/golden/check-ignoreLocalRefsTo/expected.gold +++ b/tests/golden/check-ignoreLocalRefsTo/expected.gold @@ -1,66 +1,36 @@ -=== Invalid references found === - - ➥ In file check-ignoreLocalRefsTo.md - bad reference (absolute) at src:7:1-22: - - text: "full path" - - link: /one/a.md - - anchor: - - - File does not exist: - one/a.md - - ➥ In file check-ignoreLocalRefsTo.md - bad reference (absolute) at src:9:1-26: - - text: "glob wildcard" - - link: /two/b.md - - anchor: - - - File does not exist: - two/b.md - - ➥ In file check-ignoreLocalRefsTo.md - bad reference (absolute) at src:11:1-39: - - text: "recursive directory glob" - - link: /three/c.md - - anchor: - - - File does not exist: - three/c.md - - ➥ In file check-ignoreLocalRefsTo.md - bad reference (absolute) at src:13:1-51: - - text: "recursive nested directory glob" - - link: /three/four/d.md - - anchor: - - - File does not exist: - three/four/d.md - - ➥ In file check-ignoreLocalRefsTo.md - bad reference (absolute) at src:15:1-59: - - text: "another recursive nested directory glob" - - link: /three/five/e.md - - anchor: - - - File does not exist: - three/five/e.md - - ➥ In file one/file.md - bad reference (relative) at src:7:1-58: - - text: "check ignoreLocalRefsTo are relative to the root" - - link: ./a.md - - anchor: - - - File does not exist: - one/./a.md - - ➥ In file one/file.md - bad reference (relative) at src:9:1-23: - - text: "one more" - - link: ../two/b.md - - anchor: - - - File does not exist: - one/../two/b.md +check-ignoreLocalRefsTo.md:7:1-22: bad reference: + The reference to "full path" failed verification. + File does not exist: + one/a.md + +check-ignoreLocalRefsTo.md:9:1-26: bad reference: + The reference to "glob wildcard" failed verification. + File does not exist: + two/b.md + +check-ignoreLocalRefsTo.md:11:1-39: bad reference: + The reference to "recursive directory glob" failed verification. + File does not exist: + three/c.md + +check-ignoreLocalRefsTo.md:13:1-51: bad reference: + The reference to "recursive nested directory glob" failed verification. + File does not exist: + three/four/d.md + +check-ignoreLocalRefsTo.md:15:1-59: bad reference: + The reference to "another recursive nested directory glob" failed verification. + File does not exist: + three/five/e.md + +one/file.md:7:1-58: bad reference: + The reference to "check ignoreLocalRefsTo are relative to the root" failed verification. + File does not exist: + one/./a.md + +one/file.md:9:1-23: bad reference: + The reference to "one more" failed verification. + File does not exist: + one/../two/b.md Invalid references dumped, 7 in total. diff --git a/tests/golden/check-ignoreRefsFrom/expected.gold b/tests/golden/check-ignoreRefsFrom/expected.gold index c60e3f25..509fa941 100644 --- a/tests/golden/check-ignoreRefsFrom/expected.gold +++ b/tests/golden/check-ignoreRefsFrom/expected.gold @@ -1,12 +1,6 @@ -=== Invalid references found === - - ➥ In file ignoreRefsFrom/inner-directory/bad-reference.md - bad reference (absolute) at src:7:1-28: - - text: "Bad reference" - - link: /no-file.md - - anchor: - - - File does not exist: - no-file.md +ignoreRefsFrom/inner-directory/bad-reference.md:7:1-28: bad reference: + The reference to "Bad reference" failed verification. + File does not exist: + no-file.md Invalid references dumped, 1 in total. diff --git a/tests/golden/check-images/expected.gold b/tests/golden/check-images/expected.gold index 0413e83c..58ed2ce0 100644 --- a/tests/golden/check-images/expected.gold +++ b/tests/golden/check-images/expected.gold @@ -2,61 +2,47 @@ check-images.md: - references: - - reference (external) at src:7:1-76: + - reference (external) at check-images.md:7:1-76: - text: "good image ref 1" - link: https://avatars.githubusercontent.com/u/13840520 - - reference (external) at src:9:1-35: + - reference (external) at check-images.md:9:1-35: - text: "good image ref 2" - link: https://avatars.githubusercontent.com/u/13840520 - - reference (external) at src:14:1-52: + - reference (external) at check-images.md:14:1-52: - text: "bad image ref 1" - link: https://serokell.io/1.png - - reference (external) at src:16:1-33: + - reference (external) at check-images.md:16:1-33: - text: "bad image ref 2" - link: https://serokell.io/2.png - - reference (relative) at src:20:1-34: + - reference (relative) at check-images.md:20:1-34: - text: "bad image ref 3" - link: ./3.png - anchor: - - - reference (relative) at src:21:1-33: + - reference (relative) at check-images.md:21:1-33: - text: "bad image ref 4" - link: ./4.png - anchor: - - anchors: none -=== Invalid references found === - - ➥ In file check-images.md - bad reference (external) at src:14:1-52: - - text: "bad image ref 1" - - link: https://serokell.io/1.png - - Resource unavailable (404 Not Found) - - ➥ In file check-images.md - bad reference (external) at src:16:1-33: - - text: "bad image ref 2" - - link: https://serokell.io/2.png - - Resource unavailable (404 Not Found) - - ➥ In file check-images.md - bad reference (relative) at src:20:1-34: - - text: "bad image ref 3" - - link: ./3.png - - anchor: - - - File does not exist: - ./3.png - - ➥ In file check-images.md - bad reference (relative) at src:21:1-33: - - text: "bad image ref 4" - - link: ./4.png - - anchor: - - - File does not exist: - ./4.png +check-images.md:14:1-52: bad reference: + The reference to "bad image ref 1" failed verification. + Resource unavailable (404 Not Found) + when processing an external link: https://serokell.io/1.png + +check-images.md:16:1-33: bad reference: + The reference to "bad image ref 2" failed verification. + Resource unavailable (404 Not Found) + when processing an external link: https://serokell.io/2.png + +check-images.md:20:1-34: bad reference: + The reference to "bad image ref 3" failed verification. + File does not exist: + ./3.png + +check-images.md:21:1-33: bad reference: + The reference to "bad image ref 4" failed verification. + File does not exist: + ./4.png Invalid references dumped, 4 in total. diff --git a/tests/golden/check-local-refs/expected1.gold b/tests/golden/check-local-refs/expected1.gold index f4648a51..580bf51e 100644 --- a/tests/golden/check-local-refs/expected1.gold +++ b/tests/golden/check-local-refs/expected1.gold @@ -1,117 +1,64 @@ -=== Invalid references found === - - ➥ In file dir1/dir2/d2f1.md - bad reference (file-local) at src:9:1-18: - - text: "bad-cf-ref" - - anchor: bad - - Anchor 'bad' is not present - - ➥ In file dir1/dir2/d2f1.md - bad reference (relative) at src:27:1-43: - - text: "bad-file-rel" - - link: ../a/b/c/unexisting-file.md - - anchor: - - - File does not exist: - dir1/dir2/../a/b/c/unexisting-file.md - - ➥ In file dir1/dir2/d2f1.md - bad reference (relative) at src:28:1-31: - - text: "bad-casing-file-rel" - - link: D2F2.md/ - - anchor: - - - File does not exist: - dir1/dir2/D2F2.md/ - - ➥ In file dir1/dir2/d2f1.md - bad reference (relative) at src:29:1-32: - - text: "bad-casing-folder-rel" - - link: ../DIR2 - - anchor: - - - File does not exist: - dir1/dir2/../DIR2 - - ➥ In file dir1/dir2/d2f1.md - bad reference (relative) at src:31:1-38: - - text: "bad-anchor-rel-1" - - link: d2f2.md - - anchor: bad-anchor - - Anchor 'bad-anchor' is not present - - ➥ In file dir1/dir2/d2f1.md - bad reference (relative) at src:32:1-49: - - text: "bad-anchor-rel-2" - - link: unexisting-file.md - - anchor: bad-anchor - - File does not exist: - dir1/dir2/unexisting-file.md - - ➥ In file dir1/dir2/d2f1.md - bad reference (absolute) at src:42:1-22: - - text: "file-abs-2" - - link: /d1f1.md - - anchor: - - - File does not exist: - d1f1.md - - ➥ In file dir1/dir2/d2f1.md - bad reference (absolute) at src:43:1-27: - - text: "file-abs-3" - - link: /dir2/d2f2.md - - anchor: - - - File does not exist: - dir2/d2f2.md - - ➥ In file dir1/dir2/d2f1.md - bad reference (absolute) at src:44:1-32: - - text: "file-abs-4" - - link: /./dir2/../d1f1.md - - anchor: - - - File does not exist: - ./dir2/../d1f1.md - - ➥ In file dir1/dir2/d2f1.md - bad reference (absolute) at src:45:1-37: - - text: "file-abs-slash" - - link: /./dir2/../d1f1.md/ - - anchor: - - - File does not exist: - ./dir2/../d1f1.md/ - - ➥ In file dir1/dir2/d2f1.md - bad reference (absolute) at src:46:1-55: - - text: "anchor-abs-3" - - link: /./dir2/../d1f1.md - - anchor: existing-anchor-d1f1 - - File does not exist: - ./dir2/../d1f1.md - - ➥ In file dir1/dir2/d2f1.md - bad reference (absolute) at src:57:1-16: - - text: "A" - - link: /../../a.md - - anchor: - - - Link targets a local file outside repository: - ../../a.md - - ➥ In file dir1/dir2/d2f1.md - bad reference (absolute) at src:58:1-18: - - text: "B" - - link: /b/../../b.md - - anchor: - - - Link targets a local file outside repository: - b/../../b.md +dir1/dir2/d2f1.md:9:1-18: bad reference: + The reference to "bad-cf-ref" failed verification. + Anchor 'bad' is not present + +dir1/dir2/d2f1.md:27:1-43: bad reference: + The reference to "bad-file-rel" failed verification. + File does not exist: + dir1/dir2/../a/b/c/unexisting-file.md + +dir1/dir2/d2f1.md:28:1-31: bad reference: + The reference to "bad-casing-file-rel" failed verification. + File does not exist: + dir1/dir2/D2F2.md/ + +dir1/dir2/d2f1.md:29:1-32: bad reference: + The reference to "bad-casing-folder-rel" failed verification. + File does not exist: + dir1/dir2/../DIR2 + +dir1/dir2/d2f1.md:31:1-38: bad reference: + The reference to "bad-anchor-rel-1" failed verification. + Anchor 'bad-anchor' is not present + +dir1/dir2/d2f1.md:32:1-49: bad reference: + The reference to "bad-anchor-rel-2" failed verification. + File does not exist: + dir1/dir2/unexisting-file.md + +dir1/dir2/d2f1.md:42:1-22: bad reference: + The reference to "file-abs-2" failed verification. + File does not exist: + d1f1.md + +dir1/dir2/d2f1.md:43:1-27: bad reference: + The reference to "file-abs-3" failed verification. + File does not exist: + dir2/d2f2.md + +dir1/dir2/d2f1.md:44:1-32: bad reference: + The reference to "file-abs-4" failed verification. + File does not exist: + ./dir2/../d1f1.md + +dir1/dir2/d2f1.md:45:1-37: bad reference: + The reference to "file-abs-slash" failed verification. + File does not exist: + ./dir2/../d1f1.md/ + +dir1/dir2/d2f1.md:46:1-55: bad reference: + The reference to "anchor-abs-3" failed verification. + File does not exist: + ./dir2/../d1f1.md + +dir1/dir2/d2f1.md:57:1-16: bad reference: + The reference to "A" failed verification. + Link (absolute) targets a local file outside the repository: + ../../a.md + +dir1/dir2/d2f1.md:58:1-18: bad reference: + The reference to "B" failed verification. + Link (absolute) targets a local file outside the repository: + b/../../b.md Invalid references dumped, 13 in total. diff --git a/tests/golden/check-local-refs/expected2.gold b/tests/golden/check-local-refs/expected2.gold index 7c3bf062..5745b2f6 100644 --- a/tests/golden/check-local-refs/expected2.gold +++ b/tests/golden/check-local-refs/expected2.gold @@ -1,144 +1,79 @@ -=== Invalid references found === - - ➥ In file dir2/d2f1.md - bad reference (file-local) at src:9:1-18: - - text: "bad-cf-ref" - - anchor: bad - - Anchor 'bad' is not present - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:27:1-43: - - text: "bad-file-rel" - - link: ../a/b/c/unexisting-file.md - - anchor: - - - File does not exist: - dir2/../a/b/c/unexisting-file.md - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:28:1-31: - - text: "bad-casing-file-rel" - - link: D2F2.md/ - - anchor: - - - File does not exist: - dir2/D2F2.md/ - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:29:1-32: - - text: "bad-casing-folder-rel" - - link: ../DIR2 - - anchor: - - - File does not exist: - dir2/../DIR2 - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:31:1-38: - - text: "bad-anchor-rel-1" - - link: d2f2.md - - anchor: bad-anchor - - Anchor 'bad-anchor' is not present - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:32:1-49: - - text: "bad-anchor-rel-2" - - link: unexisting-file.md - - anchor: bad-anchor - - File does not exist: - dir2/unexisting-file.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:36:1-29: - - text: "file-abs-1" - - link: /dir1/./d1f1.md - - anchor: - - - File does not exist: - dir1/./d1f1.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:37:1-21: - - text: "folder-abs-1" - - link: /dir1 - - anchor: - - - File does not exist: - dir1 - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:38:1-30: - - text: "folder-abs-2" - - link: /dir1/dir2/../ - - anchor: - - - File does not exist: - dir1/dir2/../ - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:39:1-58: - - text: "anchor-abs-1" - - link: /dir1/../dir1/d1f1.md - - anchor: existing-anchor-d1f1 - - File does not exist: - dir1/../dir1/d1f1.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:40:1-73: - - text: "anchor-abs-2" - - link: /dir1/dir2/../../dir1/./dir2/d2f2.md - - anchor: existing-anchor-d2f2 - - File does not exist: - dir1/dir2/../../dir1/./dir2/d2f2.md - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:51:1-42: - - text: "path-through-top-dir" - - link: ../../dir1/d1f1.md - - anchor: - - - Link targets a local file outside repository: - dir2/../../dir1/d1f1.md - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:52:1-75: - - text: "path-through-top-dir-with-anchor" - - link: ../../dir1/d1f1.md - - anchor: existing-anchor-d1f1 - - Link targets a local file outside repository: - dir2/../../dir1/d1f1.md - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:53:1-26: - - text: "ref-to-d0" - - link: ../../d0f1.md - - anchor: - - - Link targets a local file outside repository: - dir2/../../d0f1.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:57:1-16: - - text: "A" - - link: /../../a.md - - anchor: - - - Link targets a local file outside repository: - ../../a.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:58:1-18: - - text: "B" - - link: /b/../../b.md - - anchor: - - - Link targets a local file outside repository: - b/../../b.md +dir1/dir2/d2f1.md:9:1-18: bad reference: + The reference to "bad-cf-ref" failed verification. + Anchor 'bad' is not present + +dir1/dir2/d2f1.md:27:1-43: bad reference: + The reference to "bad-file-rel" failed verification. + File does not exist: + dir2/../a/b/c/unexisting-file.md + +dir1/dir2/d2f1.md:28:1-31: bad reference: + The reference to "bad-casing-file-rel" failed verification. + File does not exist: + dir2/D2F2.md/ + +dir1/dir2/d2f1.md:29:1-32: bad reference: + The reference to "bad-casing-folder-rel" failed verification. + File does not exist: + dir2/../DIR2 + +dir1/dir2/d2f1.md:31:1-38: bad reference: + The reference to "bad-anchor-rel-1" failed verification. + Anchor 'bad-anchor' is not present + +dir1/dir2/d2f1.md:32:1-49: bad reference: + The reference to "bad-anchor-rel-2" failed verification. + File does not exist: + dir2/unexisting-file.md + +dir1/dir2/d2f1.md:36:1-29: bad reference: + The reference to "file-abs-1" failed verification. + File does not exist: + dir1/./d1f1.md + +dir1/dir2/d2f1.md:37:1-21: bad reference: + The reference to "folder-abs-1" failed verification. + File does not exist: + dir1 + +dir1/dir2/d2f1.md:38:1-30: bad reference: + The reference to "folder-abs-2" failed verification. + File does not exist: + dir1/dir2/../ + +dir1/dir2/d2f1.md:39:1-58: bad reference: + The reference to "anchor-abs-1" failed verification. + File does not exist: + dir1/../dir1/d1f1.md + +dir1/dir2/d2f1.md:40:1-73: bad reference: + The reference to "anchor-abs-2" failed verification. + File does not exist: + dir1/dir2/../../dir1/./dir2/d2f2.md + +dir1/dir2/d2f1.md:51:1-42: bad reference: + The reference to "path-through-top-dir" failed verification. + Link (relative) targets a local file outside the repository: + dir2/../../dir1/d1f1.md + +dir1/dir2/d2f1.md:52:1-75: bad reference: + The reference to "path-through-top-dir-with-anchor" failed verification. + Link (relative) targets a local file outside the repository: + dir2/../../dir1/d1f1.md + +dir1/dir2/d2f1.md:53:1-26: bad reference: + The reference to "ref-to-d0" failed verification. + Link (relative) targets a local file outside the repository: + dir2/../../d0f1.md + +dir1/dir2/d2f1.md:57:1-16: bad reference: + The reference to "A" failed verification. + Link (absolute) targets a local file outside the repository: + ../../a.md + +dir1/dir2/d2f1.md:58:1-18: bad reference: + The reference to "B" failed verification. + Link (absolute) targets a local file outside the repository: + b/../../b.md Invalid references dumped, 16 in total. diff --git a/tests/golden/check-local-refs/expected3.gold b/tests/golden/check-local-refs/expected3.gold index 5f551918..29cb29a6 100644 --- a/tests/golden/check-local-refs/expected3.gold +++ b/tests/golden/check-local-refs/expected3.gold @@ -1,108 +1,59 @@ -=== Invalid references found === - - ➥ In file dir2/d2f1.md - bad reference (file-local) at src:9:1-18: - - text: "bad-cf-ref" - - anchor: bad - - Anchor 'bad' is not present - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:27:1-43: - - text: "bad-file-rel" - - link: ../a/b/c/unexisting-file.md - - anchor: - - - File does not exist: - dir2/../a/b/c/unexisting-file.md - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:28:1-31: - - text: "bad-casing-file-rel" - - link: D2F2.md/ - - anchor: - - - File does not exist: - dir2/D2F2.md/ - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:31:1-38: - - text: "bad-anchor-rel-1" - - link: d2f2.md - - anchor: bad-anchor - - Anchor 'bad-anchor' is not present - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:32:1-49: - - text: "bad-anchor-rel-2" - - link: unexisting-file.md - - anchor: bad-anchor - - File does not exist: - dir2/unexisting-file.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:36:1-29: - - text: "file-abs-1" - - link: /dir1/./d1f1.md - - anchor: - - - File does not exist: - dir1/./d1f1.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:37:1-21: - - text: "folder-abs-1" - - link: /dir1 - - anchor: - - - File does not exist: - dir1 - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:38:1-30: - - text: "folder-abs-2" - - link: /dir1/dir2/../ - - anchor: - - - File does not exist: - dir1/dir2/../ - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:39:1-58: - - text: "anchor-abs-1" - - link: /dir1/../dir1/d1f1.md - - anchor: existing-anchor-d1f1 - - File does not exist: - dir1/../dir1/d1f1.md - - ➥ In file dir2/d2f1.md - bad reference (absolute) at src:40:1-73: - - text: "anchor-abs-2" - - link: /dir1/dir2/../../dir1/./dir2/d2f2.md - - anchor: existing-anchor-d2f2 - - File does not exist: - dir1/dir2/../../dir1/./dir2/d2f2.md - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:51:1-42: - - text: "path-through-top-dir" - - link: ../../dir1/d1f1.md - - anchor: - - - Link targets a local file outside repository: - dir2/../../dir1/d1f1.md - - ➥ In file dir2/d2f1.md - bad reference (relative) at src:52:1-75: - - text: "path-through-top-dir-with-anchor" - - link: ../../dir1/d1f1.md - - anchor: existing-anchor-d1f1 - - Link targets a local file outside repository: - dir2/../../dir1/d1f1.md +dir1/dir2/d2f1.md:9:1-18: bad reference: + The reference to "bad-cf-ref" failed verification. + Anchor 'bad' is not present + +dir1/dir2/d2f1.md:27:1-43: bad reference: + The reference to "bad-file-rel" failed verification. + File does not exist: + dir2/../a/b/c/unexisting-file.md + +dir1/dir2/d2f1.md:28:1-31: bad reference: + The reference to "bad-casing-file-rel" failed verification. + File does not exist: + dir2/D2F2.md/ + +dir1/dir2/d2f1.md:31:1-38: bad reference: + The reference to "bad-anchor-rel-1" failed verification. + Anchor 'bad-anchor' is not present + +dir1/dir2/d2f1.md:32:1-49: bad reference: + The reference to "bad-anchor-rel-2" failed verification. + File does not exist: + dir2/unexisting-file.md + +dir1/dir2/d2f1.md:36:1-29: bad reference: + The reference to "file-abs-1" failed verification. + File does not exist: + dir1/./d1f1.md + +dir1/dir2/d2f1.md:37:1-21: bad reference: + The reference to "folder-abs-1" failed verification. + File does not exist: + dir1 + +dir1/dir2/d2f1.md:38:1-30: bad reference: + The reference to "folder-abs-2" failed verification. + File does not exist: + dir1/dir2/../ + +dir1/dir2/d2f1.md:39:1-58: bad reference: + The reference to "anchor-abs-1" failed verification. + File does not exist: + dir1/../dir1/d1f1.md + +dir1/dir2/d2f1.md:40:1-73: bad reference: + The reference to "anchor-abs-2" failed verification. + File does not exist: + dir1/dir2/../../dir1/./dir2/d2f2.md + +dir1/dir2/d2f1.md:51:1-42: bad reference: + The reference to "path-through-top-dir" failed verification. + Link (relative) targets a local file outside the repository: + dir2/../../dir1/d1f1.md + +dir1/dir2/d2f1.md:52:1-75: bad reference: + The reference to "path-through-top-dir-with-anchor" failed verification. + Link (relative) targets a local file outside the repository: + dir2/../../dir1/d1f1.md Invalid references dumped, 12 in total. diff --git a/tests/golden/check-scan-errors/expected.gold b/tests/golden/check-scan-errors/expected.gold index 2fbc1375..77bc0a55 100644 --- a/tests/golden/check-scan-errors/expected.gold +++ b/tests/golden/check-scan-errors/expected.gold @@ -1,69 +1,40 @@ -=== Scan errors found === +check-scan-errors.md:9:1-29: scan error: + Annotation "ignore all" must be at the top of markdown or right after comments at the top - ➥ In file check-scan-errors.md - scan error at src:9:1-29: +check-scan-errors.md:13:1-36: scan error: + Expected a PARAGRAPH after "ignore paragraph" annotation, but found HEADING - Annotation "ignore all" must be at the top of markdown or right after comments at the top +check-scan-errors.md:17:1-31: scan error: + Expected a LINK after "ignore link" annotation - ➥ In file check-scan-errors.md - scan error at src:13:1-36: +check-scan-errors.md:21:1-50: scan error: + Unrecognised option "unrecognised-annotation" + Perhaps you meant <"ignore link"|"ignore paragraph"|"ignore all"> - Expected a PARAGRAPH after "ignore paragraph" annotation, but found HEADING +check-second-file.md:9:1-29: scan error: + Annotation "ignore all" must be at the top of markdown or right after comments at the top - ➥ In file check-scan-errors.md - scan error at src:17:1-31: +no_link_eof.md:9:1-31: scan error: + Expected a LINK after "ignore link" annotation - Expected a LINK after "ignore link" annotation - - ➥ In file check-scan-errors.md - scan error at src:21:1-50: - - Unrecognised option "unrecognised-annotation" perhaps you meant <"ignore link"|"ignore paragraph"|"ignore all"> - - ➥ In file check-second-file.md - scan error at src:9:1-29: - - Annotation "ignore all" must be at the top of markdown or right after comments at the top - - ➥ In file no_link_eof.md - scan error at src:9:1-31: - - Expected a LINK after "ignore link" annotation - - ➥ In file no_paragraph_eof.md - scan error at src:9:1-36: - - Expected a PARAGRAPH after "ignore paragraph" annotation, but found EOF +no_paragraph_eof.md:9:1-36: scan error: + Expected a PARAGRAPH after "ignore paragraph" annotation, but found EOF Scan errors dumped, 7 in total. -=== Invalid references found === - - ➥ In file check-scan-errors.md - bad reference (absolute) at src:11:1-28: - - text: "Bad reference" - - link: /no-file.md - - anchor: - - - File does not exist: - no-file.md - - ➥ In file check-scan-errors.md - bad reference (relative) at src:23:1-24: - - text: "Bad link" - - link: bad.link.com - - anchor: - - - File does not exist: - bad.link.com +check-scan-errors.md:11:1-28: bad reference: + The reference to "Bad reference" failed verification. + File does not exist: + no-file.md - ➥ In file check-second-file.md - bad reference (absolute) at src:11:1-30: - - text: "Another bad reference" - - link: /a.md - - anchor: - +check-scan-errors.md:23:1-24: bad reference: + The reference to "Bad link" failed verification. + File does not exist: + bad.link.com - File does not exist: - a.md +check-second-file.md:11:1-30: bad reference: + The reference to "Another bad reference" failed verification. + File does not exist: + a.md Invalid references dumped, 3 in total. diff --git a/tests/golden/check-symlinks/expected1.gold b/tests/golden/check-symlinks/expected1.gold index 9a8e30e7..7f2350a2 100644 --- a/tests/golden/check-symlinks/expected1.gold +++ b/tests/golden/check-symlinks/expected1.gold @@ -2,11 +2,11 @@ dir/b.md: - references: - - reference (relative) at src:7:1-15: + - reference (relative) at dir/b.md:7:1-15: - text: "Empty file" - link: a - anchor: - - - reference (relative) at src:9:1-24: + - reference (relative) at dir/b.md:9:1-24: - text: "Some symlink" - link: ../ok.md - anchor: - @@ -15,7 +15,7 @@ ok.md: - references: - - reference (relative): + - reference (relative) at ok.md: - text: "Symbolic Link" - link: dir/b.md - anchor: - diff --git a/tests/golden/check-symlinks/expected2.gold b/tests/golden/check-symlinks/expected2.gold index ef837184..b589e969 100644 --- a/tests/golden/check-symlinks/expected2.gold +++ b/tests/golden/check-symlinks/expected2.gold @@ -2,7 +2,7 @@ broken.md: - references: - - reference (relative): + - reference (relative) at broken.md: - text: "Symbolic Link" - link: dir/c.md - anchor: - @@ -11,11 +11,11 @@ dir/b.md: - references: - - reference (relative) at src:7:1-15: + - reference (relative) at dir/b.md:7:1-15: - text: "Empty file" - link: a - anchor: - - - reference (relative) at src:9:1-24: + - reference (relative) at dir/b.md:9:1-24: - text: "Some symlink" - link: ../ok.md - anchor: - @@ -24,7 +24,7 @@ ok.md: - references: - - reference (relative): + - reference (relative) at ok.md: - text: "Symbolic Link" - link: dir/b.md - anchor: - @@ -33,31 +33,21 @@ outside.md: - references: - - reference (relative): + - reference (relative) at outside.md: - text: "Symbolic Link" - link: ../d.md - anchor: - - anchors: none -=== Invalid references found === +broken.md: bad reference: + The reference to "Symbolic Link" failed verification. + File does not exist: + dir/c.md - ➥ In file broken.md - bad reference (relative): - - text: "Symbolic Link" - - link: dir/c.md - - anchor: - - - File does not exist: - dir/c.md - - ➥ In file outside.md - bad reference (relative): - - text: "Symbolic Link" - - link: ../d.md - - anchor: - - - Link targets a local file outside repository: - ../d.md +outside.md: bad reference: + The reference to "Symbolic Link" failed verification. + Link (relative) targets a local file outside the repository: + ../d.md Invalid references dumped, 2 in total.