Skip to content

Commit d75f173

Browse files
committed
Sync to/from file
1 parent 4324c53 commit d75f173

File tree

36 files changed

+1283
-44
lines changed

36 files changed

+1283
-44
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dist-newstyle
2727
*.prof.html
2828
*.hp
2929
*.ps
30+
*.profiterole.*
3031
/.direnv/
3132
/.envrc
3233

codebase2/codebase-sqlite/U/Codebase/Sqlite/Branch/Format.hs

+2-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ data BranchLocalIds' t d p c = LocalIds
101101
branchPatchLookup :: Vector p,
102102
branchChildLookup :: Vector c
103103
}
104-
deriving (Show)
104+
deriving (Show, Eq)
105105

106106
-- | Bytes encoding a LocalBranch
107107
newtype LocalBranchBytes = LocalBranchBytes ByteString
@@ -110,6 +110,7 @@ newtype LocalBranchBytes = LocalBranchBytes ByteString
110110
data SyncBranchFormat' parent text defn patch child
111111
= SyncFull (BranchLocalIds' text defn patch child) LocalBranchBytes
112112
| SyncDiff parent (BranchLocalIds' text defn patch child) LocalBranchBytes
113+
deriving (Eq, Show)
113114

114115
type SyncBranchFormat = SyncBranchFormat' BranchObjectId TextId ObjectId PatchObjectId (BranchObjectId, CausalHashId)
115116

codebase2/codebase-sqlite/U/Codebase/Sqlite/Causal.hs

+1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ data SyncCausalFormat' causalHash valueHash = SyncCausalFormat
2222
{ valueHash :: valueHash,
2323
parents :: Vector causalHash
2424
}
25+
deriving stock (Eq, Show)
2526

2627
type SyncCausalFormat = SyncCausalFormat' CausalHashId BranchHashId

codebase2/codebase-sqlite/U/Codebase/Sqlite/Decl/Format.hs

+2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ type SyncDeclFormat =
3636

3737
data SyncDeclFormat' t d
3838
= SyncDecl (SyncLocallyIndexedComponent' t d)
39+
deriving stock (Eq, Show)
3940

4041
newtype SyncLocallyIndexedComponent' t d
4142
= SyncLocallyIndexedComponent (Vector (LocalIds' t d, ByteString))
43+
deriving stock (Eq, Show)
4244

4345
-- [OldDecl] ==map==> [NewDecl] ==number==> [(NewDecl, Int)] ==sort==> [(NewDecl, Int)] ==> permutation is map snd of that
4446

codebase2/codebase-sqlite/U/Codebase/Sqlite/Entity.hs

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ data SyncEntity' text hash defn patch branchh branch causal
2424
| N (Namespace.SyncBranchFormat' branch text defn patch (branch, causal))
2525
| P (Patch.SyncPatchFormat' patch text hash defn)
2626
| C (Causal.SyncCausalFormat' causal branchh)
27+
deriving stock (Eq, Show)
2728

2829
entityType :: SyncEntity' text hash defn patch branchh branch causal -> TempEntityType
2930
entityType = \case

codebase2/codebase-sqlite/U/Codebase/Sqlite/LocalIds.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ data LocalIds' t h = LocalIds
1515
{ textLookup :: Vector t,
1616
defnLookup :: Vector h
1717
}
18-
deriving (Functor, Show)
18+
deriving stock (Functor, Show, Eq)
1919

2020
type LocalIds = LocalIds' TextId ObjectId
2121

codebase2/codebase-sqlite/U/Codebase/Sqlite/Patch/Format.hs

+2
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ data PatchLocalIds' t h d = LocalIds
4040
patchHashLookup :: Vector h,
4141
patchDefnLookup :: Vector d
4242
}
43+
deriving stock (Eq, Show)
4344

4445
type SyncPatchFormat = SyncPatchFormat' PatchObjectId TextId HashId ObjectId
4546

4647
data SyncPatchFormat' parent text hash defn
4748
= SyncFull (PatchLocalIds' text hash defn) ByteString
4849
| -- | p is the identity of the thing that the diff is relative to
4950
SyncDiff parent (PatchLocalIds' text hash defn) ByteString
51+
deriving stock (Eq, Show)
5052

5153
-- | Apply a list of patch diffs to a patch, left to right.
5254
applyPatchDiffs :: Patch -> [PatchDiff] -> Patch

codebase2/codebase-sqlite/U/Codebase/Sqlite/Term/Format.hs

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ newtype LocallyIndexedComponent' t d = LocallyIndexedComponent
4949

5050
newtype SyncLocallyIndexedComponent' t d
5151
= SyncLocallyIndexedComponent (Vector (LocalIds' t d, ByteString))
52+
deriving stock (Eq, Show)
5253

5354
{-
5455
message = "hello, world" -> ABT { ... { Term.F.Text "hello, world" } } -> hashes to (#abc, 0)
@@ -127,6 +128,7 @@ data TermFormat' t d = Term (LocallyIndexedComponent' t d)
127128
type SyncTermFormat = SyncTermFormat' TextId ObjectId
128129

129130
data SyncTermFormat' t d = SyncTerm (SyncLocallyIndexedComponent' t d)
131+
deriving stock (Eq, Show)
130132

131133
data WatchResultFormat
132134
= WatchResult WatchLocalIds Term

codebase2/codebase-sqlite/unison-codebase-sqlite.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 1.12
22

3-
-- This file has been generated from package.yaml by hpack version 0.36.0.
3+
-- This file has been generated from package.yaml by hpack version 0.37.0.
44
--
55
-- see: https://github.com/sol/hpack
66

hie.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ cradle:
140140
- path: "unison-share-api/src"
141141
component: "unison-share-api:lib"
142142

143+
- path: "unison-share-api/tests"
144+
component: "unison-share-api:test:unison-share-api-tests"
145+
143146
- path: "unison-share-projects-api/src"
144147
component: "unison-share-projects-api:lib"
145148

lib/unison-sqlite/src/Unison/Sqlite.hs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module Unison.Sqlite
1919
Transaction,
2020
runTransaction,
2121
runTransactionWithRollback,
22+
runTransactionExceptT,
2223
runReadOnlyTransaction,
2324
runWriteTransaction,
2425
cacheTransaction,

lib/unison-sqlite/src/Unison/Sqlite/Transaction.hs

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Unison.Sqlite.Transaction
33
Transaction,
44
runTransaction,
55
runTransactionWithRollback,
6+
runTransactionExceptT,
67
runReadOnlyTransaction,
78
runWriteTransaction,
89
cacheTransaction,
@@ -44,6 +45,7 @@ where
4445

4546
import Control.Concurrent (threadDelay)
4647
import Control.Exception (Exception (fromException), onException, throwIO)
48+
import Control.Monad.Trans.Except (ExceptT, runExceptT)
4749
import Control.Monad.Trans.Reader (ReaderT (..))
4850
import Data.Text qualified as Text
4951
import Data.Unique (Unique, newUnique)
@@ -130,6 +132,13 @@ runTransactionWithRollback conn transaction = liftIO do
130132
Right x -> pure x
131133
{-# SPECIALIZE runTransactionWithRollback :: Connection -> ((forall void. a -> Transaction void) -> Transaction a) -> IO a #-}
132134

135+
-- | Run a transaction wrapped in an 'ExceptT'. If the ExceptT fails, the transaction is rolled back.
136+
runTransactionExceptT :: (MonadIO m, HasCallStack) => Connection -> ExceptT e Transaction a -> m (Either e a)
137+
runTransactionExceptT conn transaction = runTransactionWithRollback conn \rollback -> do
138+
runExceptT transaction >>= \case
139+
Left e -> rollback (Left e)
140+
Right a -> pure (Right a)
141+
133142
-- | Run a transaction that is known to only perform reads.
134143
--
135144
-- The action is provided a function that peels off the 'Transaction' newtype without sending the corresponding

parser-typechecker/src/Unison/Codebase.hs

+10
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ module Unison.Codebase
9999
-- * Direct codebase access
100100
runTransaction,
101101
runTransactionWithRollback,
102+
runTransactionExceptT,
102103
withConnection,
103104
withConnectionIO,
104105

@@ -112,6 +113,7 @@ module Unison.Codebase
112113
)
113114
where
114115

116+
import Control.Monad.Except (ExceptT)
115117
import Data.Map qualified as Map
116118
import Data.Set qualified as Set
117119
import U.Codebase.Branch qualified as V2Branch
@@ -174,6 +176,14 @@ runTransactionWithRollback ::
174176
runTransactionWithRollback Codebase {withConnection} action =
175177
withConnection \conn -> Sqlite.runTransactionWithRollback conn action
176178

179+
runTransactionExceptT ::
180+
(MonadIO m) =>
181+
Codebase m v a ->
182+
ExceptT e Sqlite.Transaction b ->
183+
m (Either e b)
184+
runTransactionExceptT Codebase {withConnection} action =
185+
withConnection \conn -> Sqlite.runTransactionExceptT conn action
186+
177187
getShallowCausalAtPathFromRootHash ::
178188
-- Causal to start at, if Nothing use the codebase's root branch.
179189
CausalHash ->

unison-cli/package.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ library:
2020
- condition: "!os(windows)"
2121
dependencies: unix
2222
dependencies:
23+
- attoparsec
2324
- Diff
2425
- IntervalMap
2526
- ListLike
@@ -32,7 +33,10 @@ library:
3233
- co-log-core
3334
- code-page
3435
- concurrent-output
36+
- conduit
3537
- containers >= 0.6.3
38+
- conduit
39+
- conduit-extra
3640
- cryptonite
3741
- either
3842
- errors
@@ -65,8 +69,10 @@ library:
6569
- recover-rtti
6670
- regex-tdfa
6771
- semialign
72+
- serialise
6873
- servant
6974
- servant-client
75+
- servant-conduit
7076
- stm
7177
- temporary
7278
- text-ansi

unison-cli/src/Unison/Cli/DownloadUtils.hs

+34-12
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
module Unison.Cli.DownloadUtils
55
( downloadProjectBranchFromShare,
66
downloadLooseCodeFromShare,
7+
SyncVersion (..),
78
)
89
where
910

1011
import Control.Concurrent.STM (atomically)
1112
import Control.Concurrent.STM.TVar (modifyTVar', newTVarIO, readTVar, readTVarIO)
1213
import Data.List.NonEmpty (pattern (:|))
14+
import Data.Set qualified as Set
1315
import System.Console.Regions qualified as Console.Regions
1416
import U.Codebase.HashTags (CausalHash)
1517
import U.Codebase.Sqlite.Queries qualified as Queries
@@ -28,37 +30,57 @@ import Unison.Share.API.Hash qualified as Share
2830
import Unison.Share.Codeserver qualified as Codeserver
2931
import Unison.Share.Sync qualified as Share
3032
import Unison.Share.Sync.Types qualified as Share
33+
import Unison.Share.SyncV2 qualified as SyncV2
3134
import Unison.Share.Types (codeserverBaseURL)
3235
import Unison.Sync.Common qualified as Sync.Common
3336
import Unison.Sync.Types qualified as Share
37+
import Unison.SyncV2.Types qualified as SyncV2
38+
39+
data SyncVersion = SyncV1 | SyncV2
3440

3541
-- | Download a project/branch from Share.
3642
downloadProjectBranchFromShare ::
3743
(HasCallStack) =>
44+
SyncVersion ->
3845
Share.IncludeSquashedHead ->
3946
Share.RemoteProjectBranch ->
4047
Cli (Either Output.ShareError CausalHash)
41-
downloadProjectBranchFromShare useSquashed branch =
48+
downloadProjectBranchFromShare syncVersion useSquashed branch =
4249
Cli.labelE \done -> do
4350
let remoteProjectBranchName = branch.branchName
44-
let repoInfo = Share.RepoInfo (into @Text (ProjectAndBranch branch.projectName remoteProjectBranchName))
4551
causalHashJwt <-
4652
case (useSquashed, branch.squashedBranchHead) of
4753
(Share.IncludeSquashedHead, Nothing) -> done Output.ShareExpectedSquashedHead
4854
(Share.IncludeSquashedHead, Just squashedHead) -> pure squashedHead
4955
(Share.NoSquashedHead, _) -> pure branch.branchHead
5056
exists <- Cli.runTransaction (Queries.causalExistsByHash32 (Share.hashJWTHash causalHashJwt))
5157
when (not exists) do
52-
(result, numDownloaded) <-
53-
Cli.with withEntitiesDownloadedProgressCallback \(downloadedCallback, getNumDownloaded) -> do
54-
result <- Share.downloadEntities Share.hardCodedBaseUrl repoInfo causalHashJwt downloadedCallback
55-
numDownloaded <- liftIO getNumDownloaded
56-
pure (result, numDownloaded)
57-
result & onLeft \err0 -> do
58-
done case err0 of
59-
Share.SyncError err -> Output.ShareErrorDownloadEntities err
60-
Share.TransportError err -> Output.ShareErrorTransport err
61-
Cli.respond (Output.DownloadedEntities numDownloaded)
58+
case syncVersion of
59+
SyncV1 -> do
60+
let repoInfo = Share.RepoInfo (into @Text (ProjectAndBranch branch.projectName remoteProjectBranchName))
61+
Cli.with withEntitiesDownloadedProgressCallback \(downloadedCallback, getNumDownloaded) -> do
62+
result <- Share.downloadEntities Share.hardCodedBaseUrl repoInfo causalHashJwt downloadedCallback
63+
numDownloaded <- liftIO getNumDownloaded
64+
result & onLeft \err0 -> do
65+
done case err0 of
66+
Share.SyncError err -> Output.ShareErrorDownloadEntities err
67+
Share.TransportError err -> Output.ShareErrorTransport err
68+
Cli.respond (Output.DownloadedEntities numDownloaded)
69+
SyncV2 -> do
70+
-- Cli.with withEntitiesDownloadedProgressCallback \(downloadedCallback, getNumDownloaded) -> do
71+
let branchRef = SyncV2.BranchRef (into @Text (ProjectAndBranch branch.projectName remoteProjectBranchName))
72+
-- TODO: Fill this in.
73+
let knownHashes = Set.empty
74+
let downloadedCallback = \_ -> pure ()
75+
let shouldValidate = not $ Codeserver.isCustomCodeserver Codeserver.defaultCodeserver
76+
result <- SyncV2.syncFromCodeserver shouldValidate Share.hardCodedBaseUrl branchRef causalHashJwt knownHashes downloadedCallback
77+
result & onLeft \err0 -> do
78+
done case err0 of
79+
Share.SyncError err ->
80+
-- TODO: Fix this
81+
error (show err)
82+
-- Output.ShareErrorDownloadEntities err
83+
Share.TransportError err -> Output.ShareErrorTransport err
6284
pure (Sync.Common.hash32ToCausalHash (Share.hashJWTHash causalHashJwt))
6385

6486
-- | Download loose code from Share.

unison-cli/src/Unison/Cli/MonadUtils.hs

+8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ module Unison.Cli.MonadUtils
4949
stepManyAtM,
5050
updateProjectBranchRoot,
5151
updateProjectBranchRoot_,
52+
setProjectBranchRootToCausalHash,
5253
updateAtM,
5354
updateAt,
5455
updateAndStepAt,
@@ -447,6 +448,13 @@ updateProjectBranchRoot projectBranch reason f = do
447448
Q.setProjectBranchHead reason (projectBranch ^. #projectId) (projectBranch ^. #branchId) causalHashId
448449
pure result
449450

451+
setProjectBranchRootToCausalHash :: ProjectBranch -> Text -> CausalHash -> Cli ()
452+
setProjectBranchRootToCausalHash projectBranch reason targetCH = do
453+
Cli.time "setProjectBranchRootToCausalHash" do
454+
Cli.runTransaction $ do
455+
targetCHID <- Q.expectCausalHashIdByCausalHash targetCH
456+
Q.setProjectBranchHead reason (projectBranch ^. #projectId) (projectBranch ^. #branchId) targetCHID
457+
450458
updateProjectBranchRoot_ :: ProjectBranch -> Text -> (Branch IO -> Branch IO) -> Cli ()
451459
updateProjectBranchRoot_ projectBranch reason f = do
452460
updateProjectBranchRoot projectBranch reason (\b -> pure (f b, ()))

unison-cli/src/Unison/Codebase/Editor/HandleInput.hs

+18-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ import Unison.Codebase.Editor.HandleInput.DeleteBranch (handleDeleteBranch)
5959
import Unison.Codebase.Editor.HandleInput.DeleteNamespace (getEndangeredDependents, handleDeleteNamespace)
6060
import Unison.Codebase.Editor.HandleInput.DeleteProject (handleDeleteProject)
6161
import Unison.Codebase.Editor.HandleInput.Dependents (handleDependents)
62-
import Unison.Codebase.Editor.HandleInput.EditNamespace (handleEditNamespace)
6362
import Unison.Codebase.Editor.HandleInput.EditDependents (handleEditDependents)
63+
import Unison.Codebase.Editor.HandleInput.EditNamespace (handleEditNamespace)
6464
import Unison.Codebase.Editor.HandleInput.FindAndReplace (handleStructuredFindI, handleStructuredFindReplaceI, handleTextFindI)
6565
import Unison.Codebase.Editor.HandleInput.FormatFile qualified as Format
6666
import Unison.Codebase.Editor.HandleInput.Global qualified as Global
@@ -87,6 +87,7 @@ import Unison.Codebase.Editor.HandleInput.ReleaseDraft (handleReleaseDraft)
8787
import Unison.Codebase.Editor.HandleInput.Run (handleRun)
8888
import Unison.Codebase.Editor.HandleInput.RuntimeUtils qualified as RuntimeUtils
8989
import Unison.Codebase.Editor.HandleInput.ShowDefinition (handleShowDefinition)
90+
import Unison.Codebase.Editor.HandleInput.SyncV2 qualified as SyncV2
9091
import Unison.Codebase.Editor.HandleInput.TermResolution (resolveMainRef)
9192
import Unison.Codebase.Editor.HandleInput.Tests qualified as Tests
9293
import Unison.Codebase.Editor.HandleInput.Todo (handleTodo)
@@ -688,6 +689,17 @@ loop e = do
688689
Cli.respond Success
689690
PullI sourceTarget pullMode -> handlePull sourceTarget pullMode
690691
PushRemoteBranchI pushRemoteBranchInput -> handlePushRemoteBranch pushRemoteBranchInput
692+
SyncToFileI syncFileDest projectBranchName -> SyncV2.handleSyncToFile syncFileDest projectBranchName
693+
SyncFromFileI syncFileSrc projectBranchName -> do
694+
description <- inputDescription input
695+
SyncV2.handleSyncFromFile description syncFileSrc projectBranchName
696+
SyncFromCodebaseI srcCodebasePath srcBranch destBranch -> do
697+
description <- inputDescription input
698+
let srcBranch' =
699+
srcBranch & over #project \case
700+
Nothing -> error "todo"
701+
Just proj -> proj
702+
SyncV2.handleSyncFromCodebase description srcCodebasePath srcBranch' destBranch
691703
ListDependentsI hq -> handleDependents hq
692704
ListDependenciesI hq -> handleDependencies hq
693705
NamespaceDependenciesI path -> handleNamespaceDependencies path
@@ -1012,6 +1024,11 @@ inputDescription input =
10121024
ProjectsI -> wat
10131025
PullI {} -> wat
10141026
PushRemoteBranchI {} -> wat
1027+
SyncToFileI {} -> wat
1028+
SyncFromFileI fp pab ->
1029+
pure $ "sync.from-file " <> into @Text fp <> " " <> into @Text pab
1030+
SyncFromCodebaseI fp srcBranch destBranch -> do
1031+
pure $ "sync.from-file " <> into @Text fp <> " " <> into @Text srcBranch <> " " <> into @Text destBranch
10151032
QuitI {} -> wat
10161033
ReleaseDraftI {} -> wat
10171034
ShowDefinitionI {} -> wat

unison-cli/src/Unison/Codebase/Editor/HandleInput/InstallLib.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ handleInstallLib remind (ProjectAndBranch libdepProjectName unresolvedLibdepBran
6060
Cli.Env {codebase} <- ask
6161

6262
causalHash <-
63-
downloadProjectBranchFromShare Share.IncludeSquashedHead libdepProjectBranch
63+
downloadProjectBranchFromShare SyncV1 Share.IncludeSquashedHead libdepProjectBranch
6464
& onLeftM (Cli.returnEarly . Output.ShareError)
6565

6666
remoteBranchObject <- liftIO (Codebase.expectBranchForHash codebase causalHash)

unison-cli/src/Unison/Codebase/Editor/HandleInput/ProjectClone.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import U.Codebase.Sqlite.Project qualified as Sqlite (Project (..))
1313
import U.Codebase.Sqlite.ProjectBranch qualified as Sqlite
1414
import U.Codebase.Sqlite.Queries qualified as Q
1515
import U.Codebase.Sqlite.Queries qualified as Queries
16-
import Unison.Cli.DownloadUtils (downloadProjectBranchFromShare)
16+
import Unison.Cli.DownloadUtils (SyncVersion (..), downloadProjectBranchFromShare)
1717
import Unison.Cli.Monad (Cli)
1818
import Unison.Cli.Monad qualified as Cli
1919
import Unison.Cli.MonadUtils qualified as Cli (getCurrentProjectAndBranch)
@@ -225,7 +225,7 @@ cloneInto localProjectBranch remoteProjectBranch = do
225225
let remoteProjectBranchNames = ProjectAndBranch remoteProjectName remoteBranchName
226226

227227
branchHead <-
228-
downloadProjectBranchFromShare Share.NoSquashedHead remoteProjectBranch
228+
downloadProjectBranchFromShare SyncV1 Share.NoSquashedHead remoteProjectBranch
229229
& onLeftM (Cli.returnEarly . Output.ShareError)
230230

231231
localProjectAndBranch <-

0 commit comments

Comments
 (0)