From 3bd72feec27c98c714122b4efec3b5690306d1a9 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sat, 6 Sep 2025 22:16:08 +0900 Subject: [PATCH 01/70] remove all --- .gitignore | 85 -------- ChangeLog.md | 5 - README.md | 45 ---- answers-script.cabal | 81 ------- app/Main.hs | 41 ---- default.nix | 25 --- shell.nix | 43 ---- src/Lib.hs | 198 ------------------ src/MyGit.hs | 119 ----------- test/Spec.hs | 38 ---- ...0547dca2710d76a885c5ee667ad981dbe31db.json | 51 ----- ...d26ddc4b6cf08bd3542ce232fc43acf6004d7.json | 20 -- ...86f0cdc45005f4cd9e4c3bd67870fa7c4c3a1.json | 20 -- ...fede2220bcd326aee3e86ddfd4ebd0fe58cb9.json | 32 --- test/expect/some book/img.png | Bin 4239 -> 0 bytes test/src/.hidden/hidden.html | 1 - test/src/.hidden/hidden.md | 1 - test/src/h.html | 1 - test/src/q.md | 1 - test/src/some book/author.txt | 1 - test/src/some book/chapter 1/a.md | 1 - test/src/some book/chapter 1/q.md | 1 - test/src/some book/chapter2/a.md | 1 - test/src/some book/chapter2/q.md | 1 - test/src/some book/img.png | Bin 4239 -> 0 bytes test/src/some book/q.md | 7 - 26 files changed, 819 deletions(-) delete mode 100644 .gitignore delete mode 100644 ChangeLog.md delete mode 100644 README.md delete mode 100644 answers-script.cabal delete mode 100644 app/Main.hs delete mode 100644 default.nix delete mode 100644 shell.nix delete mode 100644 src/Lib.hs delete mode 100644 src/MyGit.hs delete mode 100644 test/Spec.hs delete mode 100644 test/expect/db/22c0547dca2710d76a885c5ee667ad981dbe31db.json delete mode 100644 test/expect/db/262d26ddc4b6cf08bd3542ce232fc43acf6004d7.json delete mode 100644 test/expect/db/d2786f0cdc45005f4cd9e4c3bd67870fa7c4c3a1.json delete mode 100644 test/expect/db/f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9.json delete mode 100644 test/expect/some book/img.png delete mode 100644 test/src/.hidden/hidden.html delete mode 100644 test/src/.hidden/hidden.md delete mode 100644 test/src/h.html delete mode 100644 test/src/q.md delete mode 100644 test/src/some book/author.txt delete mode 100644 test/src/some book/chapter 1/a.md delete mode 100644 test/src/some book/chapter 1/q.md delete mode 100644 test/src/some book/chapter2/a.md delete mode 100644 test/src/some book/chapter2/q.md delete mode 100644 test/src/some book/img.png delete mode 100644 test/src/some book/q.md diff --git a/.gitignore b/.gitignore deleted file mode 100644 index df50a24..0000000 --- a/.gitignore +++ /dev/null @@ -1,85 +0,0 @@ -.cabal-sandbox/ -cabal.sandbox.config -cabal.project.local -.ghc.environment.* -cabal-dev/ -.hpc/ -*.hi -*.o -*.p_hi -*.prof -*.tix -dist -dist-* -register.sh -./cabal.config -cabal-tests.log -bootstrap/*.plan.json - -/Cabal/dist/ -/Cabal/tests/Setup -/Cabal/Setup -/Cabal/source-file-list - -/cabal-install/dist/ -/cabal-install/Setup -/cabal-install/source-file-list - -.stylish-haskell.yaml -.stylish-haskell.yml -.ghci -.ghcid - -# Output of release and bootstrap -_build - -# editor temp files - -*# -.#* -*~ -.*.swp -*.bak - -# GHC build - -Cabal/GNUmakefile -Cabal/dist-boot/ -Cabal/dist-install/ -Cabal/ghc.mk - - -# TAGS files -TAGS -tags -ctags - -# stack artifacts -/.stack-work/ -stack.yaml.lock - -# Shake artifacts -.shake* -progress.txt - -# test files -register.sh - -# windows test artifacts -cabal-testsuite/**/*.exe -cabal-testsuite/**/*.bat - -# python artifacts from documentation builds -*.pyc -.python-sphinx-virtualenv/ -/doc/.skjold_cache/ - -# macOS folder metadata -.DS_Store - -# benchmarks -bench.html - -# Emacs -.projectile -/test/dst/ \ No newline at end of file diff --git a/ChangeLog.md b/ChangeLog.md deleted file mode 100644 index 14619d5..0000000 --- a/ChangeLog.md +++ /dev/null @@ -1,5 +0,0 @@ -# Revision history for answers-script - -## 0.1.0.0 -- YYYY-mm-dd - -* First version. Released on an unsuspecting world. diff --git a/README.md b/README.md deleted file mode 100644 index 93334bf..0000000 --- a/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Answers Script - -## Generate default.nix - -```shell -nix-shell -p cabal2nix -cabal2nix --no-check ./. > default.nix -``` - -## Generate shell.nix - -```shell -nix-shell -p cabal2nix -cabal2nix --shell --no-check ./. > shell.nix -``` - -## Build - -**Don't just build using Cabal!!** it will take forever because of Pandoc. - -Build in Nix environment - -```shell -# Enter Nix environment defined in shell.nix -nix-shell -# Use executable -answers-script ... -``` - -## Test - -```shell -nix-shell -cabal --enable-nix test -``` - -## Install from other machines - -```shell -TAR="https://github.com/ingun37/answers-script/archive/refs/tags/1.0.1.tar.gz" -# sandboxing -nix-shell -p "with import {}; let f = import (fetchTarball $TAR); in haskellPackages.callPackage f {}" -# no sandboxing -nix-env --install -E "with import {}; let f = import (fetchTarball $TAR); in _: (haskellPackages.callPackage f {})" -``` diff --git a/answers-script.cabal b/answers-script.cabal deleted file mode 100644 index 2817267..0000000 --- a/answers-script.cabal +++ /dev/null @@ -1,81 +0,0 @@ -cabal-version: 3.0 -name: answers-script -version: 0.1.0.0 - --- A short (one-line) description of the package. --- synopsis: - --- A longer description of the package. --- description: - --- A URL where users can report bugs. --- bug-reports: - --- The license under which the package is released. --- license: -author: Ingun Jon -maintainer: ingun37@gmail.com - --- A copyright notice. --- copyright: --- category: -extra-source-files: CHANGELOG.md - -library - exposed-modules: Lib, MyGit - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: - base ^>=4.16.4.0, - aeson, - hlibgit2, - containers, - lens, - cryptohash-sha1, - directory, - directory-tree, - pandoc, - pcre-heavy, - pcre-light, - filepath, - text, - bytestring, - base16-bytestring, - aeson-pretty - hs-source-dirs: src - default-language: Haskell2010 - -executable answers-script - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: - base ^>=4.16.4.0, - answers-script, - optparse-applicative - - hs-source-dirs: app - default-language: Haskell2010 - -Test-Suite test - type: exitcode-stdio-1.0 - main-is: Spec.hs - hs-source-dirs: test - default-language: Haskell2010 - build-depends: - base ^>=4.16.4.0, - answers-script, - hspec, - QuickCheck, - directory, - filepath, - bytestring, - directory-tree \ No newline at end of file diff --git a/app/Main.hs b/app/Main.hs deleted file mode 100644 index 50bbe09..0000000 --- a/app/Main.hs +++ /dev/null @@ -1,41 +0,0 @@ -module Main where - -import Lib (someFunc) -import Options.Applicative - -data Sample = Sample - { prefixPath :: String, - src :: String, - dst :: String - } - -sample :: Parser Sample -sample = - Sample - <$> strOption - ( long "prefixpath" - <> value "" - <> help "prefix path of webserver" - ) - <*> strOption - ( long "src" - <> help "path to answers-db root directory" - ) - <*> strOption - ( long "dst" - <> help "path to static directory" - ) - -greet :: Sample -> IO () -greet (Sample prefixPath src dst) = someFunc prefixPath src dst - -main :: IO () -main = greet =<< execParser opts - where - opts = - info - (sample <**> helper) - ( fullDesc - <> progDesc "import answers-db into answers static asset" - <> header "what is header?" - ) diff --git a/default.nix b/default.nix deleted file mode 100644 index b248047..0000000 --- a/default.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ mkDerivation, aeson, aeson-pretty, base, base16-bytestring -, bytestring, containers, cryptohash-sha1, directory -, directory-tree, filepath, hlibgit2, hspec, lens, lib -, optparse-applicative, pandoc, pcre-heavy, pcre-light, QuickCheck -, text -}: -mkDerivation { - pname = "answers-script"; - version = "0.1.0.0"; - src = ./.; - isLibrary = true; - isExecutable = true; - libraryHaskellDepends = [ - aeson aeson-pretty base base16-bytestring bytestring containers - cryptohash-sha1 directory directory-tree filepath hlibgit2 lens - pandoc pcre-heavy pcre-light text - ]; - executableHaskellDepends = [ base optparse-applicative ]; - testHaskellDepends = [ - base bytestring directory directory-tree filepath hspec QuickCheck - ]; - doCheck = false; - license = "unknown"; - mainProgram = "answers-script"; -} diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 0ee0bd5..0000000 --- a/shell.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ nixpkgs ? import {}, compiler ? "default", doBenchmark ? false }: - -let - - inherit (nixpkgs) pkgs; - - f = { mkDerivation, aeson, aeson-pretty, base, base16-bytestring - , bytestring, containers, cryptohash-sha1, directory - , directory-tree, filepath, hlibgit2, hspec, lens, lib - , optparse-applicative, pandoc, pcre-heavy, pcre-light, QuickCheck - , text - }: - mkDerivation { - pname = "answers-script"; - version = "0.1.0.0"; - src = ./.; - isLibrary = true; - isExecutable = true; - libraryHaskellDepends = [ - aeson aeson-pretty base base16-bytestring bytestring containers - cryptohash-sha1 directory directory-tree filepath hlibgit2 lens - pandoc pcre-heavy pcre-light text - ]; - executableHaskellDepends = [ base optparse-applicative ]; - testHaskellDepends = [ - base bytestring directory directory-tree filepath hspec QuickCheck - ]; - doCheck = false; - license = "unknown"; - mainProgram = "answers-script"; - }; - - haskellPackages = if compiler == "default" - then pkgs.haskellPackages - else pkgs.haskell.packages.${compiler}; - - variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id; - - drv = variant (haskellPackages.callPackage f {}); - -in - - if pkgs.lib.inNixShell then drv.env else drv diff --git a/src/Lib.hs b/src/Lib.hs deleted file mode 100644 index 781b259..0000000 --- a/src/Lib.hs +++ /dev/null @@ -1,198 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE OverloadedStrings #-} - -module Lib - ( someFunc, - ) -where - -import Control.Lens (over, (^.)) -import Control.Monad (forM, when, (<=<)) -import qualified Crypto.Hash.SHA1 as SHA (hash) -import Data.Aeson (ToJSON) -import Data.Aeson.Encode.Pretty (encodePretty) -import Data.ByteString (readFile) -import qualified Data.ByteString.Base16 as B16 (encode) -import qualified Data.ByteString.Char8 as C8 (pack, unpack) -import Data.ByteString.Lazy (writeFile) -import Data.Map (Map, fromList, keys, lookup, mapKeys) -import Data.Monoid (Sum (Sum), getSum) -import Data.Text (Text, pack, strip, unpack) -import Data.Text.Encoding (decodeUtf8) -import Data.Tree (Tree (Node), flatten, rootLabel) -import GHC.Generics (Generic) -import MyGit (creationTime) -import System.Directory - ( canonicalizePath, - copyFile, - createDirectoryIfMissing, - removePathForcibly, - ) -import System.Directory.Tree - ( DirTree (Dir, File), - filterDir, - readDirectoryWithL, - _dirTree, - ) -import System.FilePath - ( FilePath, - dropFileName, - isExtensionOf, - joinPath, - makeRelative, - splitDirectories, - takeBaseName, - takeExtension, - takeFileName, - (-<.>), - (), - ) -import qualified System.FilePath as FilePath -import System.FilePath.Posix (joinPath, ()) -import Text.Pandoc - ( Extension (Ext_pipe_tables, Ext_tex_math_double_backslash), - HTMLMathMethod (KaTeX), - def, - defaultKaTeXURL, - extensionsFromList, - githubMarkdownExtensions, - readMarkdown, - readerExtensions, - runIOorExplode, - writeHtml5String, - writerHTMLMathMethod, - ) -import Text.Regex.PCRE.Heavy (gsub, scan) -import Text.Regex.PCRE.Light (compile, dotall, multiline) -import Prelude hiding (lookup, readFile, writeFile) - -data AttributeFile = AttributeFile - { posixTime :: Integer, - content :: Text - } - deriving (Generic, Show) - -instance ToJSON AttributeFile - -data Item = Item - { title :: String, - sha1 :: String, - attr :: Map String AttributeFile, - numAnswer :: Int - } - deriving (Generic, Show) - -data TemTree = TemTree - { path :: String, - item :: Item, - kids :: [Item], - parentSha1 :: String - } - deriving (Generic, Show) - -instance ToJSON Item - -instance ToJSON TemTree - -sha1InHex :: String -> [Char] -sha1InHex = C8.unpack . B16.encode . SHA.hash . C8.pack - -theReader :: String -> String -> String -> FilePath -> IO Text -theReader sitePrefix srcDir dstDir fp = - let ext = takeExtension fp - readWorth = ext == ".md" || ext == ".txt" - content = if readWorth then decodeUtf8 <$> readFile fp else return "" - func = - if ext == ".md" - then mdToHTML <=< copyMDMedia sitePrefix srcDir (dropFileName fp) dstDir . subInlineMathBlock . subDisplayMathBlock - else return - in content >>= func - -theFilter :: DirTree a -> DirTree a -theFilter = - filterDir - ( \case - Dir name _ -> head name /= '.' - File name _ -> ".md" `isExtensionOf` name || ".txt" `isExtensionOf` name - _ -> False - ) - -writeJson :: String -> TemTree -> IO () -writeJson dst tt = writeFile (dst (sha1 (item tt) -<.> ".json")) (encodePretty tt) - -someFunc :: String -> FilePath -> FilePath -> IO () -someFunc prefixPath src'' dst = do - src <- canonicalizePath src'' - anchored <- readDirectoryWithL (theReader prefixPath src dst) src - let anchored' = over _dirTree theFilter anchored - let dbDst = dst "db" - removePathForcibly dbDst >> createDirectoryIfMissing True dbDst - let (Dir name entries) = anchored' ^. _dirTree - putStrLn "===============================" - putStrLn $ "canonical src :" ++ src - putStrLn $ "dst :" ++ dst - putStrLn $ "Prefix :" ++ prefixPath - putStrLn $ "Name of src dir :" ++ name - putStrLn "===============================" - creationTimeForFiles <- mapKeys (name ) <$> creationTime src - mapM_ (writeJson dbDst) (flatten (makeTr creationTimeForFiles name "" entries)) - -subInlineMathBlock :: Text -> Text -subInlineMathBlock = - let imgRegex = compile "\\$`(.+?)`\\$" [] - in gsub imgRegex (\(d : _) -> "\\\\(" ++ d ++ "\\\\)" :: String) - -stripString :: String -> String -stripString = unpack . strip . pack - -subDisplayMathBlock :: Text -> Text -subDisplayMathBlock = - let imgRegex = compile "^```math$(.+?)^```$" [multiline, dotall] - in gsub imgRegex (\(d : _) -> "\\\\[" ++ stripString d ++ "\\\\]" :: String) - -copyMDMedia :: String -> FilePath -> FilePath -> FilePath -> Text -> IO Text -copyMDMedia sitePrefix srcDir mdDir dstDir content = do - let imgRegex = compile "!\\[\\]\\((?!http)(.+?)\\)" [] - let imgNames = map (unpack . head . snd) $ scan imgRegex content - if null imgNames - then return content - else do - let rel = makeRelative srcDir mdDir - let relToDst = dstDir rel - createDirectoryIfMissing True relToDst - mapM_ (\x -> copyFile (mdDir x) (relToDst x)) imgNames - let g x = joinPath $ filter (/= "/") ([sitePrefix, rel, x] >>= splitDirectories) - let f x = mconcat ["![](/", g x, ")"] - return $ gsub imgRegex (f . head) content - -mdToHTML :: Text -> IO Text -mdToHTML txt = - runIOorExplode $ - readMarkdown - def - { readerExtensions = githubMarkdownExtensions <> extensionsFromList [Ext_tex_math_double_backslash, Ext_pipe_tables] - } - txt - >>= writeHtml5String - def - { writerHTMLMathMethod = KaTeX defaultKaTeXURL - } - -countAnswer :: Item -> Sum Int -countAnswer = maybe 0 (const 1) . lookup "a" . attr - -makeTr :: Map FilePath Integer -> String -> String -> [DirTree Text] -> Tree TemTree -makeTr time path parentSha1 entries = - let sha1 = sha1InHex path - kidTrs = [makeTr time (path title) sha1 entries' | Dir title entries' <- entries] - kidItems = map (item . rootLabel) kidTrs - answerNumber = getSum $ countAnswer thisItem <> foldMap (Sum . numAnswer) kidItems - f filename = - let entry = path filename - in case lookup entry time of - Just x -> x - Nothing -> error $ "Failed to read entry : " ++ entry - thisItem = Item (takeFileName path) sha1 (fromList [(takeBaseName name', AttributeFile (f name') file) | File name' file <- entries]) answerNumber - thisNode = TemTree path thisItem kidItems parentSha1 - in Node thisNode kidTrs diff --git a/src/MyGit.hs b/src/MyGit.hs deleted file mode 100644 index b446c15..0000000 --- a/src/MyGit.hs +++ /dev/null @@ -1,119 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} - -module MyGit - ( creationTime, - ) -where - -import Bindings.Libgit2 -import Control.Lens (makeLenses, (<&>), (^.)) -import Control.Monad (when, (>=>)) -import Data.List (isPrefixOf) -import Data.Map (Map) -import qualified Data.Map as Map -import Foreign (Ptr, Storable (peek), alloca) -import Foreign.C.String (CString, peekCString, withCString) -import System.Directory (canonicalizePath, doesDirectoryExist) -import System.FilePath (makeRelative, takeDirectory, ()) -import System.FilePath.Posix (takeDirectory, ()) - --- import Data.Set (Set) --- import qualified Data.Set as Set -data Pointers = Pointers - { _repoP :: Ptr (Ptr C'git_repository), - _headP :: Ptr (Ptr C'git_reference), - _commitP :: Ptr (Ptr C'git_commit) - } - -makeLenses ''Pointers - -withPointers f = alloca $ \x -> do - alloca $ \y -> do - alloca $ \z -> do - f (Pointers x y z) - -creationTime :: FilePath -> IO (Map FilePath Integer) -creationTime src = withLibGitDo $ do - dotGitPath <- canonicalizePath =<< getDotGitPath src - repoPath <- canonicalizePath $ takeDirectory dotGitPath - let require = if repoPath == src then "" else makeRelative repoPath src - withCString dotGitPath $ \csrc -> do - putStrLn "============================" - putStrLn $ "src :" ++ src - putStrLn $ "require :" ++ require - putStrLn $ "repoPath :" ++ repoPath - putStrLn "============================" - withPointers (func require csrc) - -getDotGitPath :: FilePath -> IO FilePath -getDotGitPath fp = do - putStrLn $ "testing .git: " ++ fp - e <- doesDirectoryExist (fp ".git") - let dirName = takeDirectory fp - when (dirName == fp) $ error "Failed to find .git" - if e - then return $ fp ".git" - else getDotGitPath dirName - -func :: String -> CString -> Pointers -> IO (Map FilePath Integer) -func matchPrefix repoPath pointers = do - c'git_repository_open (pointers ^. repoP) repoPath >>= errorCheck - repo <- peek $ pointers ^. repoP - c'git_repository_head (pointers ^. headP) repo >>= errorCheck - headOid <- peek (pointers ^. headP) >>= c'git_reference_target - c'git_commit_lookup (pointers ^. commitP) repo headOid >>= errorCheck - headCommit <- peek (pointers ^. commitP) - lineage <- unfoldCommits headCommit - let constructEntryMap' = constructEntrymap matchPrefix repo - maps <- mapM (getRootAndTime >=> uncurry constructEntryMap') lineage - c'git_repository_free repo - return $ Map.unionsWith min maps - -getRootAndTime :: Ptr C'git_commit -> IO (Ptr C'git_tree, Integer) -getRootAndTime commit = do - alloca $ \rootP -> do - c'git_commit_tree rootP commit >>= errorCheck - root <- peek rootP - time <- c'git_commit_time commit - return (root, toInteger time) - -unfoldCommits :: Ptr C'git_commit -> IO [Ptr C'git_commit] -unfoldCommits commit = alloca $ \parentP -> do - result <- c'git_commit_parent parentP commit 0 - if result == 0 - then peek parentP >>= unfoldCommits <&> (++ [commit]) - else return [commit] - -constructEntrymap :: String -> Ptr C'git_repository -> Ptr C'git_tree -> Integer -> IO (Map FilePath Integer) -constructEntrymap matchPrefix repo root time = - let makeEntryMap'' :: String -> Ptr C'git_tree_entry -> IO (Map FilePath Integer) - makeEntryMap'' parentDir entry = do - entryType <- c'git_tree_entry_type entry - name <- c'git_tree_entry_name entry >>= peekCString - let next = parentDir ++ name ++ "/" - if entryType == c'GIT_OBJ_TREE - then do - eoid <- c'git_tree_entry_id entry - alloca $ \subTreeP -> do - c'git_tree_lookup subTreeP repo eoid >>= errorCheck - subTree <- peek subTreeP - if next `isPrefixOf` matchPrefix || matchPrefix `isPrefixOf` next - then makeEntryMap' (parentDir ++ name ++ "/") subTree - else return Map.empty - else do - if matchPrefix `isPrefixOf` parentDir - then do - let relPath = makeRelative matchPrefix (parentDir ++ name) - return $ Map.singleton relPath time - else return Map.empty - - makeEntryMap' :: String -> Ptr C'git_tree -> IO (Map FilePath Integer) - makeEntryMap' parentDir tree = do - entryCountC <- c'git_tree_entrycount tree - let f = c'git_tree_entry_byindex tree - foldMap (f >=> makeEntryMap'' parentDir) [0 .. (entryCountC - 1)] - in makeEntryMap' "" root - -errorCheck r = when (r /= 0) $ error "fail" - --- printMessage = c'git_commit_message >=> peekCString >=> print \ No newline at end of file diff --git a/test/Spec.hs b/test/Spec.hs deleted file mode 100644 index ff9900b..0000000 --- a/test/Spec.hs +++ /dev/null @@ -1,38 +0,0 @@ -import Lib - -import System.Directory (removeDirectoryRecursive, createDirectoryIfMissing, doesDirectoryExist) -import Test.Hspec -import Test.QuickCheck -import qualified System.Directory.Tree as DT -import qualified Data.ByteString as B -import Control.Monad (when) -import System.FilePath (takeExtension, takeFileName) -src :: FilePath -src = "test/src" - -dst :: FilePath -dst = "test/dst" - -prefix :: String -prefix = "prefix" - -expect :: FilePath -expect = "test/expect" - -simpleReader :: FilePath -> IO String -simpleReader fp = case takeExtension fp of - ".json" -> readFile fp - _ -> return (takeFileName fp) - -main :: IO () -main = hspec $ do - describe "Prelude.head" $ do - it "returns the first element of a list" $ do - dstExist <- doesDirectoryExist dst - when dstExist (removeDirectoryRecursive dst) - createDirectoryIfMissing True dst - someFunc prefix src dst - -- Top directory names are different, hence (_ :/ (Dir _ toDT)) - (_ DT.:/ (DT.Dir _ toDT)) <- DT.readDirectoryWith simpleReader dst - (_ DT.:/ (DT.Dir _ beDT)) <- DT.readDirectoryWith simpleReader expect - toDT `shouldBe` beDT \ No newline at end of file diff --git a/test/expect/db/22c0547dca2710d76a885c5ee667ad981dbe31db.json b/test/expect/db/22c0547dca2710d76a885c5ee667ad981dbe31db.json deleted file mode 100644 index 96d4d77..0000000 --- a/test/expect/db/22c0547dca2710d76a885c5ee667ad981dbe31db.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "item": { - "attr": { - "author": { - "content": "Ingun Jon", - "posixTime": 1668403786 - }, - "q": { - "content": "

some book's q.md

\n

\\cdots

\n

", - "posixTime": 1668403786 - } - }, - "numAnswer": 2, - "sha1": "22c0547dca2710d76a885c5ee667ad981dbe31db", - "title": "some book" - }, - "kids": [ - { - "attr": { - "a": { - "content": "

it's 3

", - "posixTime": 1668403786 - }, - "q": { - "content": "

What is 1 + 1?

", - "posixTime": 1668403786 - } - }, - "numAnswer": 1, - "sha1": "262d26ddc4b6cf08bd3542ce232fc43acf6004d7", - "title": "chapter 1" - }, - { - "attr": { - "a": { - "content": "

it's 5

", - "posixTime": 1674358503 - }, - "q": { - "content": "

What is 2+2?

", - "posixTime": 1674358503 - } - }, - "numAnswer": 1, - "sha1": "d2786f0cdc45005f4cd9e4c3bd67870fa7c4c3a1", - "title": "chapter2" - } - ], - "parentSha1": "f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9", - "path": "src/some book" -} \ No newline at end of file diff --git a/test/expect/db/262d26ddc4b6cf08bd3542ce232fc43acf6004d7.json b/test/expect/db/262d26ddc4b6cf08bd3542ce232fc43acf6004d7.json deleted file mode 100644 index 1b3d7d2..0000000 --- a/test/expect/db/262d26ddc4b6cf08bd3542ce232fc43acf6004d7.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "item": { - "attr": { - "a": { - "content": "

it's 3

", - "posixTime": 1668403786 - }, - "q": { - "content": "

What is 1 + 1?

", - "posixTime": 1668403786 - } - }, - "numAnswer": 1, - "sha1": "262d26ddc4b6cf08bd3542ce232fc43acf6004d7", - "title": "chapter 1" - }, - "kids": [], - "parentSha1": "22c0547dca2710d76a885c5ee667ad981dbe31db", - "path": "src/some book/chapter 1" -} \ No newline at end of file diff --git a/test/expect/db/d2786f0cdc45005f4cd9e4c3bd67870fa7c4c3a1.json b/test/expect/db/d2786f0cdc45005f4cd9e4c3bd67870fa7c4c3a1.json deleted file mode 100644 index ec0bc31..0000000 --- a/test/expect/db/d2786f0cdc45005f4cd9e4c3bd67870fa7c4c3a1.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "item": { - "attr": { - "a": { - "content": "

it's 5

", - "posixTime": 1674358503 - }, - "q": { - "content": "

What is 2+2?

", - "posixTime": 1674358503 - } - }, - "numAnswer": 1, - "sha1": "d2786f0cdc45005f4cd9e4c3bd67870fa7c4c3a1", - "title": "chapter2" - }, - "kids": [], - "parentSha1": "22c0547dca2710d76a885c5ee667ad981dbe31db", - "path": "src/some book/chapter2" -} \ No newline at end of file diff --git a/test/expect/db/f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9.json b/test/expect/db/f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9.json deleted file mode 100644 index 6ff4d52..0000000 --- a/test/expect/db/f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "item": { - "attr": { - "q": { - "content": "

top q.md

", - "posixTime": 1668403786 - } - }, - "numAnswer": 2, - "sha1": "f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9", - "title": "src" - }, - "kids": [ - { - "attr": { - "author": { - "content": "Ingun Jon", - "posixTime": 1668403786 - }, - "q": { - "content": "

some book's q.md

\n

\\cdots

\n

", - "posixTime": 1668403786 - } - }, - "numAnswer": 2, - "sha1": "22c0547dca2710d76a885c5ee667ad981dbe31db", - "title": "some book" - } - ], - "parentSha1": "", - "path": "src" -} \ No newline at end of file diff --git a/test/expect/some book/img.png b/test/expect/some book/img.png deleted file mode 100644 index bb5ea35c8338951102a26a757ae614a41e360970..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4239 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