Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.

Commit e7084c5

Browse files
authored
Merge branch 'master' into build-docker-image
2 parents 15f6889 + 23e8d3a commit e7084c5

File tree

13 files changed

+85
-42
lines changed

13 files changed

+85
-42
lines changed

.travis.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ before_install:
2828
- cabal --version
2929

3030
install:
31-
- cabal new-update hackage.haskell.org,HEAD
31+
- cabal new-update hackage.haskell.org
3232
- cabal new-configure --enable-tests --write-ghc-environment-files=always
3333
- cabal new-build --only-dependencies -j
3434

3535
script:
36-
- cabal new-build -j semantic-core semantic:exe:semantic
37-
- cabal new-test semantic:test semantic-core:spec
38-
- cabal new-run semantic:parse-examples
36+
- cabal new-build -j
37+
- cabal new-run semantic:test
38+
- cabal new-run semantic-core:spec
39+
# parse-examples is disabled because it slaughters our CI
40+
# - cabal new-run semantic:parse-examples
3941

4042
# Any branch linked with a pull request will be built, as well as the non-PR
4143
# branches listed below:

cabal.project

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ packages: . semantic-core
22

33
jobs: $ncpus
44

5+
package semantic
6+
ghc-options: +RTS -A128m -n2m -RTS
7+
58
source-repository-package
69
type: git
710
location: https://github.com/joshvera/proto3-suite.git

docs/development.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
# Development Guide
22

3-
`semantic` is built using the [`stack`](https://github.com/commercialhaskell/stack) build system and the [ghc](https://www.haskell.org/ghc/) compiler. It’s packaged using [Cabal](https://www.haskell.org/cabal/), and uses dependencies from [Hackage](http://hackage.haskell.org/).
3+
`semantic` is compiled with the [ghc](https://www.haskell.org/ghc/) compiler and built/packaged with [`cabal`](https://cabal.readthedocs.io/en/latest/). It uses Cabal's [Nix-style local builds](https://www.haskell.org/cabal/users-guide/nix-local-build-overview.html) and uses dependencies from [Hackage](http://hackage.haskell.org/). We recommend using [`ghcup`](https://www.haskell.org/ghcup/) to sandbox your installation of GHC.
44

55
| Tool | Explanation |
66
| :-------------: |-------------|
77
| [`ghc`](https://www.haskell.org/ghc/) | The Glasgow Haskell Compiler is the open source compiler and interactive environment for the Haskell programming language. |
88
| [`cabal`](https://www.haskell.org/cabal/) | Cabal is a system for building and packaging Haskell libraries and programs. It is similar to having `make` files instead of having to type several complicated calls to `ghc` to compile and link a project. |
9-
| [`stack`](https://docs.haskellstack.org/en/stable/README/) | Stack is used to develop Haskell projects. It is a layer on top of `cabal` and `ghc` that aims to make it much easier to build cross-platform Haskell projects. It lets us use different versions of `ghc` and has snapshots of packages that are known to work together. It defers to `cabal` for much of its work. Historically, we used `cabal` directly, but ran into a variety of tooling issues that [brought us back to stack](https://github.com/github/semantic/pull/1335). Officially, `stack` uses [stackage](https://www.stackage.org/) as its package archive, and `cabal-install` uses hackage. |
109
| [`hackage`](https://hackage.haskell.org/) | Hackage is the most widely used package archive of open source libraries and programs. `cabal-install` is used to download and install packages. |
10+
| [`ghcup`](https://www.haskell.org/ghcup/) | `ghcup` takes care of managing different versions of GHC on your system. We aggressively track new versions of GHC; sandboxing makes upgrading to new versions safe and easy. |
1111
| [`ghci`](https://downloads.haskell.org/~ghc/5.04/docs/html/users_guide/ghci.html) | `ghci` is GHC's interactive environment. This is where Haskell expressions can be interactively evaluated and programs can be interpreted. |
1212

13+
### Nix-style local builds
14+
15+
`semantic` is a complicated app with a very large dependency tree. Because managing large dependency trees in a system-wide `ghc` installation is difficult, especially when developing on multiple Haskell projects, `cabal` enables "local" builds: each dependency is linked in per-project, not globally. In practice, this means that you should prefix your commands with the `new-` prefix: `cabal new-build` builds the project, `new-clean` purges its build artifacts, etc. (With versions of the `cabal` command line tool newer than 2.6, local builds become the default, with the `v1-` prefix required to yield old behavior.)
16+
1317
### Running a REPL
1418

15-
Running `stack ghci semantic` will boot a GHCi with the right environment for Semantic set up.
19+
Running `cabal new-repl semantic:lib` will boot a GHCi with the right environment for Semantic set up.
1620

1721
See the [💡ProTips](💡ProTip!.md#ghci) for more info.
1822

script/clone-example-repos

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
set -e
1414
cd $(dirname "$0")/..
1515

16-
dir="vendor/haskell-tree-sitter/languages"
16+
mkdir -p test/examplerepos || true
17+
git clone --single-branch --recurse-submodules https://github.com/tree-sitter/haskell-tree-sitter.git tmp/haskell-tree-sitter || true
18+
19+
dir="tmp/haskell-tree-sitter/languages"
1720

1821
# clone_repo LOCAL_PATH URL SHA
1922
function clone_repo {

semantic.cabal

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ common dependencies
4949
, bytestring ^>= 0.10.8.2
5050
, containers ^>= 0.6.0.1
5151
, directory ^>= 1.3.3.0
52-
, fastsum
52+
, fastsum ^>= 0.1.1.0
5353
, filepath ^>= 1.4.2.1
5454
, free ^>= 5.1
5555
, fused-effects ^>= 0.4.0.0
@@ -59,11 +59,11 @@ common dependencies
5959
, machines ^>= 0.6.4
6060
, mtl ^>= 2.2.2
6161
, network ^>= 2.8.0.0
62-
, process
62+
, process ^>= 1.6.3.0
6363
, recursion-schemes ^>= 5.1
6464
, scientific ^>= 0.3.6.2
65-
, safe-exceptions
66-
, semilattices
65+
, safe-exceptions ^>= 0.1.7.0
66+
, semilattices ^>= 0.0.0.3
6767
, text ^>= 1.2.3.1
6868
, these >= 0.7 && <1
6969
, unix ^>= 2.7.2.2
@@ -309,11 +309,11 @@ library
309309
, stm-chans ^>= 3.0.0.4
310310
, template-haskell ^>= 2.14
311311
, time ^>= 1.8.0.2
312-
, unliftio-core
312+
, unliftio-core ^>= 0.1.2.0
313313
, unordered-containers ^>= 0.2.9.0
314314
, vector ^>= 0.12.0.2
315315
, tree-sitter-go ^>= 0.1.0.0
316-
, tree-sitter-haskell
316+
, tree-sitter-haskell ^>= 0.1.0.0
317317
, tree-sitter-json ^>= 0.1.0.0
318318
, tree-sitter-php ^>= 0.1.0.0
319319
, tree-sitter-python ^>= 0.1.0.1

src/Semantic/Git.hs

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@ module Semantic.Git
99
, ObjectType(..)
1010
, ObjectMode(..)
1111
, OID(..)
12+
13+
-- Testing Purposes
14+
, parseEntries
15+
, parseEntry
1216
) where
1317

1418
import Control.Monad.IO.Class
15-
import Data.Text as Text
16-
import Shelly hiding (FilePath)
17-
import System.IO (hSetBinaryMode)
19+
import Data.Attoparsec.Text (Parser)
20+
import Data.Attoparsec.Text as AP
21+
import Data.Char
22+
import Data.Text as Text
23+
import Shelly hiding (FilePath)
24+
import System.IO (hSetBinaryMode)
1825

1926
-- | git clone --bare
2027
clone :: Text -> FilePath -> IO ()
@@ -24,22 +31,38 @@ clone url path = sh $ do
2431
-- | git cat-file -p
2532
catFile :: FilePath -> OID -> IO Text
2633
catFile gitDir (OID oid) = sh $ do
27-
run "git" [pack ("--git-dir=" <> gitDir), "cat-file", "-p", oid]
34+
run "git" ["-C", pack gitDir, "cat-file", "-p", oid]
2835

2936
-- | git ls-tree -rz
3037
lsTree :: FilePath -> OID -> IO [TreeEntry]
31-
lsTree gitDir (OID sha) = sh $ do
32-
out <- run "git" [pack ("--git-dir=" <> gitDir), "ls-tree", "-rz", sha]
33-
pure $ mkEntry <$> splitOn "\NUL" out
34-
where
35-
mkEntry row | [mode, ty, rest] <- splitOn " " row
36-
, [oid, path] <- splitOn "\t" rest
37-
= TreeEntry (objectMode mode) (objectType ty) (OID oid) (unpack path)
38-
| otherwise = nullTreeEntry
38+
lsTree gitDir (OID sha) = sh $ parseEntries <$> run "git" ["-C", pack gitDir, "ls-tree", "-rz", sha]
3939

4040
sh :: MonadIO m => Sh a -> m a
4141
sh = shelly . silently . onCommandHandles (initOutputHandles (`hSetBinaryMode` True))
4242

43+
-- | Parses an list of entries separated by \NUL, and on failure return []
44+
parseEntries :: Text -> [TreeEntry]
45+
parseEntries = either (const []) id . AP.parseOnly everything
46+
where
47+
everything = AP.sepBy entryParser "\NUL" <* "\NUL\n" <* AP.endOfInput
48+
49+
-- | Parse the entire input with entryParser, and on failure return a default
50+
-- For testing purposes only
51+
parseEntry :: Text -> Either String TreeEntry
52+
parseEntry = AP.parseOnly (entryParser <* AP.endOfInput)
53+
54+
-- | Parses a TreeEntry
55+
entryParser :: Parser TreeEntry
56+
entryParser = TreeEntry
57+
<$> modeParser <* AP.char ' '
58+
<*> typeParser <* AP.char ' '
59+
<*> oidParser <* AP.char '\t'
60+
<*> (unpack <$> AP.takeWhile (/= '\NUL'))
61+
where
62+
typeParser = AP.choice [BlobObject <$ "blob", TreeObject <$ "tree"]
63+
modeParser = AP.choice [NormalMode <$ "100644", ExecutableMode <$ "100755", SymlinkMode <$ "120000", TreeMode <$ "040000"]
64+
oidParser = OID <$> AP.takeWhile isHexDigit
65+
4366
newtype OID = OID Text
4467
deriving (Eq, Show, Ord)
4568

@@ -51,24 +74,12 @@ data ObjectMode
5174
| OtherMode
5275
deriving (Eq, Show)
5376

54-
objectMode :: Text -> ObjectMode
55-
objectMode "100644" = NormalMode
56-
objectMode "100755" = ExecutableMode
57-
objectMode "120000" = SymlinkMode
58-
objectMode "040000" = TreeMode
59-
objectMode _ = OtherMode
60-
6177
data ObjectType
6278
= BlobObject
6379
| TreeObject
6480
| OtherObjectType
6581
deriving (Eq, Show)
6682

67-
objectType :: Text -> ObjectType
68-
objectType "blob" = BlobObject
69-
objectType "tree" = TreeObject
70-
objectType _ = OtherObjectType
71-
7283
data TreeEntry
7384
= TreeEntry
7485
{ treeEntryMode :: ObjectMode
@@ -77,5 +88,3 @@ data TreeEntry
7788
, treeEntryPath :: FilePath
7889
} deriving (Eq, Show)
7990

80-
nullTreeEntry :: TreeEntry
81-
nullTreeEntry = TreeEntry OtherMode OtherObjectType (OID mempty) mempty

test/Analysis/Go/Spec.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# OPTIONS_GHC -O0 #-}
12
module Analysis.Go.Spec (spec) where
23

34
import Data.Abstract.Evaluatable (EvalError(..))

test/Analysis/PHP/Spec.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# OPTIONS_GHC -O0 #-}
12
module Analysis.PHP.Spec (spec) where
23

34
import Control.Abstract

test/Analysis/Ruby/Spec.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# OPTIONS_GHC -O0 #-}
12
{-# LANGUAGE TupleSections #-}
23
module Analysis.Ruby.Spec (spec) where
34

test/Analysis/TypeScript/Spec.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# OPTIONS_GHC -O0 #-}
2+
13
module Analysis.TypeScript.Spec (spec) where
24

35
import Data.Syntax.Statement (StatementBlock(..))

0 commit comments

Comments
 (0)