Skip to content

Commit 7a39719

Browse files
committed
fix: adapt hsec-tools to new layout
1 parent ea8517a commit 7a39719

File tree

3 files changed

+24
-36
lines changed

3 files changed

+24
-36
lines changed

code/hsec-tools/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Move `isVersionAffectedBy` and `isVersionRangeAffectedBy` to `Security.Advisories.Core` (`hsec-core`)
44
* Add support for GHC component in `query is-affected`
55
* Add `model.database_specific.{repository,osvs,home}` and `model.affected.database_specific.{osv,human_link}` in OSV exports
6+
* Adapt to new security-advisories layout
67

78
## 0.2.0.2
89

code/hsec-tools/hsec-tools.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ library
7373
, pandoc >=2.0 && <3.8
7474
, pandoc-types >=1.22 && <2
7575
, parsec >=3 && <4
76-
, pathwalk >=0.3 && <0.4
7776
, pretty >=1.0 && <1.2
7877
, prettyprinter >=1.7 && <1.8
7978
, process >=1.6 && <1.7

code/hsec-tools/src/Security/Advisories/Filesystem.hs

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module Security.Advisories.Filesystem
1313
(
1414
dirNameAdvisories
1515
, dirNameReserved
16+
, dirNamePublished
1617
, isSecurityAdvisoriesRepo
1718
, getReservedIds
1819
, getAdvisoryIds
@@ -36,12 +37,10 @@ import Data.Semigroup (Max(Max, getMax))
3637
import Data.Traversable (for)
3738

3839
import Control.Monad.IO.Class (MonadIO, liftIO)
39-
import Control.Monad.Writer.Strict (execWriterT, tell)
4040
import qualified Data.Text as T
4141
import qualified Data.Text.IO as T
42-
import System.FilePath ((</>), takeBaseName, splitDirectories)
43-
import System.Directory (doesDirectoryExist, pathIsSymbolicLink)
44-
import System.Directory.PathWalk
42+
import System.FilePath ((</>), splitDirectories)
43+
import System.Directory (doesDirectoryExist, listDirectory)
4544
import Validation (Validation (..))
4645

4746
import Security.Advisories (Advisory, AttributeOverridePolicy (NoOverrides), OutOfBandAttributes (..), ParseAdvisoryError, parseAdvisory, ComponentIdentifier(..))
@@ -58,6 +57,9 @@ dirNameAdvisories = "advisories"
5857
dirNameReserved :: FilePath
5958
dirNameReserved = "reserved"
6059

60+
dirNamePublished :: FilePath
61+
dirNamePublished = "published"
62+
6163
-- | Check whether the directory appears to be the root of a
6264
-- /security-advisories/ filesystem. Only checks that the
6365
-- @advisories@ subdirectory exists.
@@ -109,7 +111,7 @@ forReserved
109111
:: (MonadIO m, Monoid r)
110112
=> FilePath -> (FilePath -> HsecId -> m r) -> m r
111113
forReserved root =
112-
_forFiles (root </> dirNameAdvisories </> dirNameReserved)
114+
_forFilesByYear (root </> dirNameAdvisories </> dirNameReserved)
113115

114116
-- | Invoke a callback for each HSEC ID under each of the advisory
115117
-- subdirectories, excluding the @reserved@ directory. The results
@@ -121,23 +123,17 @@ forReserved root =
121123
forAdvisory
122124
:: (MonadIO m, Monoid r)
123125
=> FilePath -> (FilePath -> HsecId -> m r) -> m r
124-
forAdvisory root go = do
125-
let dir = root </> dirNameAdvisories
126-
subdirs <- filter (/= dirNameReserved) <$> _getSubdirs dir
127-
fmap fold $ for subdirs $ \subdir -> _forFiles (dir </> subdir) go
126+
forAdvisory root =
127+
_forFilesByYear (root </> dirNameAdvisories </> dirNamePublished)
128128

129-
-- | List deduplicated parsed Advisories
129+
-- | List parsed Advisories
130130
listAdvisories
131131
:: (MonadIO m)
132132
=> FilePath -> m (Validation [(FilePath, ParseAdvisoryError)] [Advisory])
133133
listAdvisories root =
134-
forAdvisory root $ \advisoryPath _advisoryId -> do
135-
isSym <- liftIO $ pathIsSymbolicLink advisoryPath
136-
if isSym
137-
then return $ pure []
138-
else
139-
bimap (\err -> [(advisoryPath, err)]) pure
140-
<$> advisoryFromFile advisoryPath
134+
forAdvisory root $ \advisoryPath _advisoryId ->
135+
bimap (\err -> [(advisoryPath, err)]) pure
136+
<$> advisoryFromFile advisoryPath
141137

142138
-- | Parse an advisory from a file system path
143139
advisoryFromFile
@@ -158,28 +154,20 @@ advisoryFromFile advisoryPath = do
158154
$ either Failure Success
159155
$ parseAdvisory NoOverrides oob fileContent
160156

161-
-- | Get names (not paths) of subdirectories of the given directory
162-
-- (one level). There's no monoidal, interruptible variant of
163-
-- @pathWalk@ so we use @WriterT@ to smuggle the result out.
164-
--
165-
_getSubdirs :: (MonadIO m) => FilePath -> m [FilePath]
166-
_getSubdirs root =
167-
execWriterT $
168-
pathWalkInterruptible root $ \_ subdirs _ -> do
169-
tell subdirs
170-
pure Stop
171-
172-
_forFiles
157+
_forFilesByYear
173158
:: (MonadIO m, Monoid r)
174159
=> FilePath -- ^ (sub)directory name
175160
-> (FilePath -> HsecId -> m r)
176161
-> m r
177-
_forFiles root go =
178-
pathWalkAccumulate root $ \dir _ files ->
179-
fmap fold $ for files $ \file ->
180-
case parseHsecId (takeBaseName file) of
181-
Nothing -> pure mempty
182-
Just hsid -> go (dir </> file) hsid
162+
_forFilesByYear root go = do
163+
yearsFile <- liftIO $ listDirectory root
164+
fmap (foldMap fold) $
165+
for yearsFile $ \year -> do
166+
files <- liftIO $ listDirectory (root </> year)
167+
for files $ \file ->
168+
case parseHsecId ("HSEC-" <> year <> "-" <> file) of
169+
Nothing -> pure mempty
170+
Just hsid -> go (root </> year </> file) hsid
183171

184172
parseComponentIdentifier :: Monad m => FilePath -> ExceptT OOBError m (Maybe ComponentIdentifier)
185173
parseComponentIdentifier fp = ExceptT . pure $ case drop 1 $ reverse $ splitDirectories fp of

0 commit comments

Comments
 (0)