mirror of
https://github.com/github/semantic.git
synced 2024-12-26 16:33:03 +03:00
Refactor IO back out into Source and SemanticDiff
This commit is contained in:
parent
bfe1181acb
commit
fff9b6d3ef
@ -49,7 +49,6 @@ library
|
|||||||
, Renderer.SExpression
|
, Renderer.SExpression
|
||||||
, Renderer.TOC
|
, Renderer.TOC
|
||||||
, SemanticDiff
|
, SemanticDiff
|
||||||
, SemanticDiff.IO
|
|
||||||
, SES
|
, SES
|
||||||
, Source
|
, Source
|
||||||
, SourceSpan
|
, SourceSpan
|
||||||
|
@ -32,7 +32,6 @@ import Renderer.SExpression
|
|||||||
import Renderer.Split
|
import Renderer.Split
|
||||||
import Renderer.Summary
|
import Renderer.Summary
|
||||||
import Renderer.TOC
|
import Renderer.TOC
|
||||||
import SemanticDiff.IO
|
|
||||||
import Source
|
import Source
|
||||||
import Syntax
|
import Syntax
|
||||||
import Term
|
import Term
|
||||||
|
@ -24,7 +24,6 @@ import Text.Parser.TreeSitter.C
|
|||||||
import Text.Parser.TreeSitter.Go
|
import Text.Parser.TreeSitter.Go
|
||||||
import Text.Parser.TreeSitter.JavaScript
|
import Text.Parser.TreeSitter.JavaScript
|
||||||
import Text.Parser.TreeSitter.Ruby
|
import Text.Parser.TreeSitter.Ruby
|
||||||
import SemanticDiff.IO
|
|
||||||
|
|
||||||
data ParseJSON = ParseJSON
|
data ParseJSON = ParseJSON
|
||||||
{ category :: Text
|
{ category :: Text
|
||||||
|
@ -13,7 +13,9 @@ import qualified Renderer as R
|
|||||||
import Development.GitRev
|
import Development.GitRev
|
||||||
import DiffCommand
|
import DiffCommand
|
||||||
import ParseCommand
|
import ParseCommand
|
||||||
import SemanticDiff.IO
|
import qualified Data.Text.IO as TextIO
|
||||||
|
import System.IO
|
||||||
|
import System.Environment (lookupEnv)
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
@ -56,3 +58,18 @@ versionString = "semantic-diff version " <> showVersion Library.version <> " ("
|
|||||||
|
|
||||||
version :: Parser (a -> a)
|
version :: Parser (a -> a)
|
||||||
version = infoOption versionString (long "version" <> short 'V' <> help "output the version of the program")
|
version = infoOption versionString (long "version" <> short 'V' <> help "output the version of the program")
|
||||||
|
|
||||||
|
writeToOutput :: Maybe FilePath -> Text -> IO ()
|
||||||
|
writeToOutput output text = case output of
|
||||||
|
Nothing -> do
|
||||||
|
setEncoding
|
||||||
|
TextIO.hPutStrLn stdout text
|
||||||
|
Just path -> withFile path WriteMode (`TextIO.hPutStr` text)
|
||||||
|
where
|
||||||
|
setEncoding = do
|
||||||
|
lang <- lookupEnv "LANG"
|
||||||
|
case lang of
|
||||||
|
-- If LANG is set and isn't the empty string, leave the encoding.
|
||||||
|
Just x | x /= "" -> pure ()
|
||||||
|
-- Otherwise default to utf8.
|
||||||
|
_ -> hSetEncoding stdout utf8
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
module SemanticDiff.IO where
|
|
||||||
|
|
||||||
import Prelude
|
|
||||||
import Data.Text
|
|
||||||
import qualified Data.Text.IO as TextIO
|
|
||||||
import System.IO
|
|
||||||
import System.Environment (lookupEnv)
|
|
||||||
|
|
||||||
import Control.Exception (catch, IOException)
|
|
||||||
import qualified Data.ByteString as B1
|
|
||||||
import qualified Data.Text.ICU.Convert as Convert
|
|
||||||
import qualified Data.Text.ICU.Detect as Detect
|
|
||||||
|
|
||||||
import Source
|
|
||||||
|
|
||||||
writeToOutput :: Maybe FilePath -> Text -> IO ()
|
|
||||||
writeToOutput output text = case output of
|
|
||||||
Nothing -> do
|
|
||||||
setEncoding
|
|
||||||
TextIO.hPutStrLn stdout text
|
|
||||||
Just path -> withFile path WriteMode (`TextIO.hPutStr` text)
|
|
||||||
|
|
||||||
where
|
|
||||||
setEncoding = do
|
|
||||||
lang <- lookupEnv "LANG"
|
|
||||||
case lang of
|
|
||||||
-- If LANG is set and isn't the empty string, leave the encoding.
|
|
||||||
Just x | x /= "" -> pure ()
|
|
||||||
-- Otherwise default to utf8.
|
|
||||||
_ -> hSetEncoding stdout utf8
|
|
||||||
|
|
||||||
-- | Read the file and convert it to Unicode.
|
|
||||||
readAndTranscodeFile :: FilePath -> IO Source
|
|
||||||
readAndTranscodeFile path = do
|
|
||||||
size <- fileSize path
|
|
||||||
text <- case size of
|
|
||||||
0 -> pure B1.empty
|
|
||||||
_ -> B1.readFile path
|
|
||||||
transcode text
|
|
||||||
|
|
||||||
-- From https://github.com/haskell/bytestring/pull/79/files
|
|
||||||
fileSize :: FilePath -> IO Integer
|
|
||||||
fileSize f = withBinaryFile f ReadMode $ \h -> do
|
|
||||||
-- hFileSize fails if file is not regular file (like /dev/null). Catch
|
|
||||||
-- exception and try reading anyway.
|
|
||||||
filesz <- catch (hFileSize h) useZeroIfNotRegularFile
|
|
||||||
pure $ fromIntegral filesz `max` 0
|
|
||||||
where useZeroIfNotRegularFile :: IOException -> IO Integer
|
|
||||||
useZeroIfNotRegularFile _ = pure 0
|
|
||||||
|
|
||||||
-- | Transcode a file to a unicode source.
|
|
||||||
transcode :: B1.ByteString -> IO Source
|
|
||||||
transcode text = fromText <$> do
|
|
||||||
match <- Detect.detectCharset text
|
|
||||||
converter <- Convert.open match Nothing
|
|
||||||
pure $ Convert.toUnicode converter text
|
|
@ -2,6 +2,7 @@
|
|||||||
{-# OPTIONS_GHC -funbox-strict-fields #-}
|
{-# OPTIONS_GHC -funbox-strict-fields #-}
|
||||||
module Source where
|
module Source where
|
||||||
|
|
||||||
|
import Prelude (FilePath, fromIntegral)
|
||||||
import Prologue
|
import Prologue
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
@ -9,6 +10,10 @@ import Numeric
|
|||||||
import Range
|
import Range
|
||||||
import SourceSpan
|
import SourceSpan
|
||||||
import Test.LeanCheck
|
import Test.LeanCheck
|
||||||
|
import System.IO
|
||||||
|
import Control.Exception (catch, IOException)
|
||||||
|
import qualified Data.Text.ICU.Convert as Convert
|
||||||
|
import qualified Data.Text.ICU.Detect as Detect
|
||||||
|
|
||||||
-- | The source, oid, path, and Maybe SourceKind of a blob in a Git repo.
|
-- | The source, oid, path, and Maybe SourceKind of a blob in a Git repo.
|
||||||
data SourceBlob = SourceBlob { source :: Source, oid :: T.Text, path :: FilePath, blobKind :: Maybe SourceKind }
|
data SourceBlob = SourceBlob { source :: Source, oid :: T.Text, path :: FilePath, blobKind :: Maybe SourceKind }
|
||||||
@ -22,12 +27,37 @@ newtype Source = Source { sourceText :: B.ByteString }
|
|||||||
data SourceKind = PlainBlob Word32 | ExecutableBlob Word32 | SymlinkBlob Word32
|
data SourceKind = PlainBlob Word32 | ExecutableBlob Word32 | SymlinkBlob Word32
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
-- | Read the file and convert it to Unicode.
|
||||||
|
readAndTranscodeFile :: FilePath -> IO Source
|
||||||
|
readAndTranscodeFile path = do
|
||||||
|
size <- fileSize path
|
||||||
|
text <- case size of
|
||||||
|
0 -> pure B.empty
|
||||||
|
_ -> B.readFile path
|
||||||
|
transcode text
|
||||||
|
|
||||||
|
-- From https://github.com/haskell/bytestring/pull/79/files
|
||||||
|
fileSize :: FilePath -> IO Integer
|
||||||
|
fileSize f = withBinaryFile f ReadMode $ \h -> do
|
||||||
|
-- hFileSize fails if file is not regular file (like /dev/null). Catch
|
||||||
|
-- exception and try reading anyway.
|
||||||
|
filesz <- catch (hFileSize h) useZeroIfNotRegularFile
|
||||||
|
pure $ fromIntegral filesz `max` 0
|
||||||
|
where useZeroIfNotRegularFile :: IOException -> IO Integer
|
||||||
|
useZeroIfNotRegularFile _ = pure 0
|
||||||
|
|
||||||
|
-- | Transcode a file to a unicode source.
|
||||||
|
transcode :: B.ByteString -> IO Source
|
||||||
|
transcode text = fromText <$> do
|
||||||
|
match <- Detect.detectCharset text
|
||||||
|
converter <- Convert.open match Nothing
|
||||||
|
pure $ Convert.toUnicode converter text
|
||||||
|
|
||||||
modeToDigits :: SourceKind -> Text
|
modeToDigits :: SourceKind -> Text
|
||||||
modeToDigits (PlainBlob mode) = toS $ showOct mode ""
|
modeToDigits (PlainBlob mode) = toS $ showOct mode ""
|
||||||
modeToDigits (ExecutableBlob mode) = toS $ showOct mode ""
|
modeToDigits (ExecutableBlob mode) = toS $ showOct mode ""
|
||||||
modeToDigits (SymlinkBlob mode) = toS $ showOct mode ""
|
modeToDigits (SymlinkBlob mode) = toS $ showOct mode ""
|
||||||
|
|
||||||
|
|
||||||
-- | The default plain blob mode
|
-- | The default plain blob mode
|
||||||
defaultPlainBlob :: SourceKind
|
defaultPlainBlob :: SourceKind
|
||||||
defaultPlainBlob = PlainBlob 0o100644
|
defaultPlainBlob = PlainBlob 0o100644
|
||||||
|
@ -14,7 +14,6 @@ import Renderer
|
|||||||
import Renderer.SExpression as Renderer
|
import Renderer.SExpression as Renderer
|
||||||
import Source
|
import Source
|
||||||
import DiffCommand
|
import DiffCommand
|
||||||
import SemanticDiff.IO (readAndTranscodeFile)
|
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.FilePath.Glob
|
import System.FilePath.Glob
|
||||||
import Test.Hspec (Spec, describe, it, SpecWith, runIO, parallel)
|
import Test.Hspec (Spec, describe, it, SpecWith, runIO, parallel)
|
||||||
|
@ -10,7 +10,6 @@ import Data.Record
|
|||||||
import Data.String
|
import Data.String
|
||||||
import Diff
|
import Diff
|
||||||
import DiffCommand
|
import DiffCommand
|
||||||
import SemanticDiff.IO (readAndTranscodeFile)
|
|
||||||
import Info
|
import Info
|
||||||
import Interpreter
|
import Interpreter
|
||||||
import ParseCommand
|
import ParseCommand
|
||||||
|
Loading…
Reference in New Issue
Block a user