From d1ac9024bf3d4a8d4a600fba8c0fdc61d3be28b2 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Wed, 29 May 2024 13:12:54 -0700 Subject: [PATCH 01/11] Add onlyLib combinator to Branch --- parser-typechecker/src/Unison/Codebase/Branch.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/parser-typechecker/src/Unison/Codebase/Branch.hs b/parser-typechecker/src/Unison/Codebase/Branch.hs index b9a0e625a9..52b0e3dbb9 100644 --- a/parser-typechecker/src/Unison/Codebase/Branch.hs +++ b/parser-typechecker/src/Unison/Codebase/Branch.hs @@ -72,6 +72,7 @@ module Unison.Codebase.Branch -- *** Libdep manipulations withoutLib, withoutTransitiveLibs, + onlyLib, deleteLibdep, deleteLibdeps, @@ -178,6 +179,10 @@ withoutTransitiveLibs Branch0 {..} = ) in branch0 _terms _types newChildren _edits +onlyLib :: Branch0 m -> Branch0 m +onlyLib Branch0 {..} = + branch0 _terms _types (Map.singleton NameSegment.libSegment (fromMaybe empty $ Map.lookup NameSegment.libSegment _children)) _edits + -- | @deleteLibdep name branch@ deletes the libdep named @name@ from @branch@, if it exists. deleteLibdep :: NameSegment -> Branch0 m -> Branch0 m deleteLibdep dep = From 41ab309935ccdae7ab31d156ccc01ec920ba84d7 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Wed, 29 May 2024 13:17:42 -0700 Subject: [PATCH 02/11] Add 'commit' command --- .../src/Unison/Codebase/Editor/HandleInput.hs | 22 +- .../src/Unison/Codebase/Editor/Input.hs | 1 + .../src/Unison/CommandLine/InputPatterns.hs | 16 ++ unison-src/transcripts/commit-command.md | 62 ++++++ .../transcripts/commit-command.output.md | 207 ++++++++++++++++++ 5 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 unison-src/transcripts/commit-command.md create mode 100644 unison-src/transcripts/commit-command.output.md diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs index 088062ce24..7764f50c98 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs @@ -195,7 +195,7 @@ loop e = do -- We skip this update if it was programmatically generated Cli.getLatestFile >>= \case Just (_, True) -> (#latestFile . _Just . _2) .= False - _ -> loadUnisonFile sourceName text + _ -> void $ loadUnisonFile sourceName text Right input -> let previewResponse sourceName sr uf = do names <- Cli.currentNames @@ -717,7 +717,7 @@ loop e = do FindI isVerbose fscope ws -> handleFindI isVerbose fscope ws input StructuredFindI _fscope ws -> handleStructuredFindI ws StructuredFindReplaceI ws -> handleStructuredFindReplaceI ws - LoadI maybePath -> handleLoad maybePath + LoadI maybePath -> void $ handleLoad maybePath ClearI -> Cli.respond ClearScreen AddI requestedNames -> do description <- inputDescription input @@ -742,6 +742,23 @@ loop e = do currentNames <- Branch.toNames <$> Cli.getCurrentBranch0 let sr = Slurp.slurpFile uf vars Slurp.AddOp currentNames previewResponse sourceName sr uf + CommitI mayScratchFile -> do + uf <- handleLoad mayScratchFile + description <- inputDescription input + Cli.Env {codebase} <- ask + currentPath <- Cli.getCurrentPath + libNames <- + Cli.getCurrentBranch0 + <&> Branch.onlyLib + <&> Branch.toNames + let sr = Slurp.slurpFile uf mempty Slurp.AddOp libNames + let adds = SlurpResult.adds sr + Cli.stepAtNoSync (Path.unabsolute currentPath, doSlurpAdds adds uf . Branch.onlyLib) + Cli.runTransaction . Codebase.addDefsToCodebase codebase . SlurpResult.filterUnisonFile sr $ uf + pped <- Cli.prettyPrintEnvDeclFromNames $ UF.addNamesFromTypeCheckedUnisonFile uf libNames + let suffixifiedPPE = PPED.suffixifiedPPE pped + Cli.respond $ SlurpOutput input suffixifiedPPE sr + Cli.syncRoot description UpdateI optionalPatch requestedNames -> handleUpdate input optionalPatch requestedNames Update2I -> handleUpdate2 PreviewUpdateI requestedNames -> do @@ -1062,6 +1079,7 @@ inputDescription input = DeleteTarget'ProjectBranch _ -> wat DeleteTarget'Project _ -> wat AddI _selection -> pure "add" + CommitI -> pure "commit" UpdateI p0 _selection -> do p <- case p0 of diff --git a/unison-cli/src/Unison/Codebase/Editor/Input.hs b/unison-cli/src/Unison/Codebase/Editor/Input.hs index 4f0e384da8..847b26f179 100644 --- a/unison-cli/src/Unison/Codebase/Editor/Input.hs +++ b/unison-cli/src/Unison/Codebase/Editor/Input.hs @@ -148,6 +148,7 @@ data Input | ClearI | AddI (Set Name) | PreviewAddI (Set Name) + | CommitI (Maybe FilePath) | UpdateI OptionalPatch (Set Name) | Update2I | PreviewUpdateI (Set Name) diff --git a/unison-cli/src/Unison/CommandLine/InputPatterns.hs b/unison-cli/src/Unison/CommandLine/InputPatterns.hs index 6615506446..05fa5efb27 100644 --- a/unison-cli/src/Unison/CommandLine/InputPatterns.hs +++ b/unison-cli/src/Unison/CommandLine/InputPatterns.hs @@ -18,6 +18,7 @@ module Unison.CommandLine.InputPatterns cd, clear, clone, + commit, compileScheme, createAuthor, debugClearWatchCache, @@ -375,6 +376,20 @@ previewAdd = ) \ws -> pure $ Input.PreviewAddI (Set.fromList $ map (Name.unsafeParseText . Text.pack) ws) +commit :: InputPattern +commit = + InputPattern + "experimental.commit" + [] + I.Visible + [("scratch file", Optional, filePathArg)] + ( "`experimental.commit` *replaces* all your existing non-lib code with the code from a scratch file. Any code which is not present within the file (aside from your libs) will be removed." + ) + \case + [] -> pure $ Input.CommitI Nothing + [file] -> pure $ Input.CommitI . Just $ file + _ -> Left (I.help load) + update :: InputPattern update = InputPattern @@ -2927,6 +2942,7 @@ validInputs = clear, clone, compileScheme, + commit, createAuthor, debugClearWatchCache, debugDoctor, diff --git a/unison-src/transcripts/commit-command.md b/unison-src/transcripts/commit-command.md new file mode 100644 index 0000000000..c162f115ff --- /dev/null +++ b/unison-src/transcripts/commit-command.md @@ -0,0 +1,62 @@ +```ucm:hide +.> builtins.merge +``` + +Add some definitions to the codebase for us to later update. + +```unison +type MyRecord = + { nat : Nat + , text : Text + , bool : Boolean + } + +lib.dep.dependency = 1 +termOne = lib.dep.dependency + 2 +termTwo = lib.dep.dependency + 3 + +addToRecordField : MyRecord -> Nat +addToRecordField rec = nat rec + 10 + +> addToRecordField (MyRecord 9 "hi" true) +``` + +```ucm +.> add +``` + +Should be able to easily change and remove record fields and definitions in a single commit. + +```unison +-- Rename and re-type the `nat` field to `getNat` +-- Remove the `bool` field +type MyRecord = + { getNat : () -> Nat + , text : Text + } + + +-- Update termOne, +termOne = dependency + 20 +-- termTwo is deleted simply by omitting it from the scratch file. + +addToRecordField : MyRecord -> Nat +addToRecordField rec = !(getNat rec) + 10 + +> addToRecordField (MyRecord '9 "hi") +``` + +```ucm +.> experimental.commit +.> find +.> view MyRecord +.> ls MyRecord +.> view addToRecordField +.> view termOne +``` + +This term should be deleted. + +```ucm:error +.> view termTwo +``` diff --git a/unison-src/transcripts/commit-command.output.md b/unison-src/transcripts/commit-command.output.md new file mode 100644 index 0000000000..50808bbff7 --- /dev/null +++ b/unison-src/transcripts/commit-command.output.md @@ -0,0 +1,207 @@ +Add some definitions to the codebase for us to later update. + +```unison +type MyRecord = + { nat : Nat + , text : Text + , bool : Boolean + } + +lib.dep.dependency = 1 +termOne = lib.dep.dependency + 2 +termTwo = lib.dep.dependency + 3 + +addToRecordField : MyRecord -> Nat +addToRecordField rec = nat rec + 10 + +> addToRecordField (MyRecord 9 "hi" true) +``` + +```ucm + + Loading changes detected in scratch.u. + + I found and typechecked these definitions in scratch.u. If you + do an `add` or `update`, here's how your codebase would + change: + + ⍟ These new definitions are ok to `add`: + + type MyRecord + MyRecord.bool : MyRecord -> Boolean + MyRecord.bool.modify : (Boolean ->{g} Boolean) + -> MyRecord + ->{g} MyRecord + MyRecord.bool.set : Boolean -> MyRecord -> MyRecord + MyRecord.nat : MyRecord -> Nat + MyRecord.nat.modify : (Nat ->{g} Nat) + -> MyRecord + ->{g} MyRecord + MyRecord.nat.set : Nat -> MyRecord -> MyRecord + MyRecord.text : MyRecord -> Text + MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + MyRecord.text.set : Text -> MyRecord -> MyRecord + addToRecordField : MyRecord -> Nat + lib.dep.dependency : Nat + termOne : Nat + termTwo : Nat + + Now evaluating any watch expressions (lines starting with + `>`)... Ctrl+C cancels. + + 14 | > addToRecordField (MyRecord 9 "hi" true) + ⧩ + 19 + +``` +```ucm +.> add + + ⍟ I've added these definitions: + + type MyRecord + MyRecord.bool : MyRecord -> Boolean + MyRecord.bool.modify : (Boolean ->{g} Boolean) + -> MyRecord + ->{g} MyRecord + MyRecord.bool.set : Boolean -> MyRecord -> MyRecord + MyRecord.nat : MyRecord -> Nat + MyRecord.nat.modify : (Nat ->{g} Nat) + -> MyRecord + ->{g} MyRecord + MyRecord.nat.set : Nat -> MyRecord -> MyRecord + MyRecord.text : MyRecord -> Text + MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + MyRecord.text.set : Text -> MyRecord -> MyRecord + addToRecordField : MyRecord -> Nat + lib.dep.dependency : Nat + termOne : Nat + termTwo : Nat + +``` +Should be able to easily change and remove record fields and definitions in a single commit. + +```unison +-- Rename and re-type the `nat` field to `getNat` +-- Remove the `bool` field +type MyRecord = + { getNat : () -> Nat + , text : Text + } + + +-- Update termOne, +termOne = dependency + 20 +-- termTwo is deleted simply by omitting it from the scratch file. + +addToRecordField : MyRecord -> Nat +addToRecordField rec = !(getNat rec) + 10 + +> addToRecordField (MyRecord '9 "hi") +``` + +```ucm + + Loading changes detected in scratch.u. + + I found and typechecked these definitions in scratch.u. If you + do an `add` or `update`, here's how your codebase would + change: + + ⍟ These new definitions are ok to `add`: + + MyRecord.getNat : MyRecord -> 'Nat + MyRecord.getNat.modify : ('Nat ->{g} 'Nat) + -> MyRecord + ->{g} MyRecord + MyRecord.getNat.set : 'Nat -> MyRecord -> MyRecord + + ⍟ These names already exist. You can `update` them to your + new definition: + + type MyRecord + MyRecord.text : MyRecord -> Text + MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + MyRecord.text.set : Text -> MyRecord -> MyRecord + addToRecordField : MyRecord -> Nat + termOne : Nat + + Now evaluating any watch expressions (lines starting with + `>`)... Ctrl+C cancels. + + 16 | > addToRecordField (MyRecord '9 "hi") + ⧩ + 19 + +``` +```ucm +.> experimental.commit + + x These definitions would fail on `add` or `update`: + + Reason + needs update type MyRecord + needs update addToRecordField : MyRecord -> ##Nat + needs update termOne : ##Nat + blocked MyRecord.getNat : MyRecord -> '##Nat + blocked MyRecord.getNat.modify : ('##Nat + ->{g} '##Nat) + -> MyRecord + ->{g} MyRecord + blocked MyRecord.getNat.set : '##Nat + -> MyRecord + -> MyRecord + blocked MyRecord.text : MyRecord -> ##Text + blocked MyRecord.text.modify : (##Text + ->{g} ##Text) + -> MyRecord + ->{g} MyRecord + blocked MyRecord.text.set : ##Text + -> MyRecord + -> MyRecord + + Tip: Use `help filestatus` to learn more. + +``` + +```ucm +.> experimental.commit.> find.> view MyRecord.> ls MyRecord.> view addToRecordField.> view termOne +``` + + +🛑 + +The transcript failed due to an error in the stanza above. The error is: + + + x These definitions would fail on `add` or `update`: + + Reason + needs update type MyRecord + needs update addToRecordField : MyRecord -> ##Nat + needs update termOne : ##Nat + blocked MyRecord.getNat : MyRecord -> '##Nat + blocked MyRecord.getNat.modify : ('##Nat + ->{g} '##Nat) + -> MyRecord + ->{g} MyRecord + blocked MyRecord.getNat.set : '##Nat + -> MyRecord + -> MyRecord + blocked MyRecord.text : MyRecord -> ##Text + blocked MyRecord.text.modify : (##Text + ->{g} ##Text) + -> MyRecord + ->{g} MyRecord + blocked MyRecord.text.set : ##Text + -> MyRecord + -> MyRecord + + Tip: Use `help filestatus` to learn more. + From 9d0cde7feb10e5ad02188c6a573116ab87899a6c Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Wed, 29 May 2024 13:17:42 -0700 Subject: [PATCH 03/11] Alter behaviour of load, including UNISON_LOAD_MODE env var --- .../src/Unison/Codebase/Editor/HandleInput.hs | 14 ++++---- .../Codebase/Editor/HandleInput/Load.hs | 34 ++++++++++++++----- .../src/Unison/Codebase/TranscriptParser.hs | 3 +- unison-cli/src/Unison/CommandLine/Main.hs | 6 ++-- unison-cli/src/Unison/Main.hs | 14 +++++++- 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs index 7764f50c98..ac4444a668 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs @@ -64,7 +64,7 @@ import Unison.Codebase.Editor.HandleInput.EditNamespace (handleEditNamespace) import Unison.Codebase.Editor.HandleInput.FindAndReplace (handleStructuredFindI, handleStructuredFindReplaceI) import Unison.Codebase.Editor.HandleInput.FormatFile qualified as Format import Unison.Codebase.Editor.HandleInput.InstallLib (handleInstallLib) -import Unison.Codebase.Editor.HandleInput.Load (EvalMode (Sandboxed), evalUnisonFile, handleLoad, loadUnisonFile) +import Unison.Codebase.Editor.HandleInput.Load (EvalMode (Sandboxed), LoadMode (LoadForCommit), evalUnisonFile, handleLoad, loadUnisonFile) import Unison.Codebase.Editor.HandleInput.Merge2 (handleMerge) import Unison.Codebase.Editor.HandleInput.MoveAll (handleMoveAll) import Unison.Codebase.Editor.HandleInput.MoveBranch (doMoveBranch) @@ -188,14 +188,14 @@ import UnliftIO.Directory qualified as Directory ------------------------------------------------------------------------------------------------------------------------ -- Main loop -loop :: Either Event Input -> Cli () -loop e = do +loop :: LoadMode -> Either Event Input -> Cli () +loop loadMode e = do case e of Left (UnisonFileChanged sourceName text) -> Cli.time "UnisonFileChanged" do -- We skip this update if it was programmatically generated Cli.getLatestFile >>= \case Just (_, True) -> (#latestFile . _Just . _2) .= False - _ -> void $ loadUnisonFile sourceName text + _ -> void $ loadUnisonFile loadMode sourceName text Right input -> let previewResponse sourceName sr uf = do names <- Cli.currentNames @@ -717,7 +717,7 @@ loop e = do FindI isVerbose fscope ws -> handleFindI isVerbose fscope ws input StructuredFindI _fscope ws -> handleStructuredFindI ws StructuredFindReplaceI ws -> handleStructuredFindReplaceI ws - LoadI maybePath -> void $ handleLoad maybePath + LoadI maybePath -> void $ handleLoad loadMode maybePath ClearI -> Cli.respond ClearScreen AddI requestedNames -> do description <- inputDescription input @@ -743,7 +743,7 @@ loop e = do let sr = Slurp.slurpFile uf vars Slurp.AddOp currentNames previewResponse sourceName sr uf CommitI mayScratchFile -> do - uf <- handleLoad mayScratchFile + uf <- handleLoad LoadForCommit mayScratchFile description <- inputDescription input Cli.Env {codebase} <- ask currentPath <- Cli.getCurrentPath @@ -1079,7 +1079,7 @@ inputDescription input = DeleteTarget'ProjectBranch _ -> wat DeleteTarget'Project _ -> wat AddI _selection -> pure "add" - CommitI -> pure "commit" + CommitI mayScratchFile -> pure ("commit" <> maybe "" Text.pack mayScratchFile) UpdateI p0 _selection -> do p <- case p0 of diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs index 12d121c487..32b71a2cba 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs @@ -1,6 +1,7 @@ module Unison.Codebase.Editor.HandleInput.Load ( handleLoad, loadUnisonFile, + LoadMode (..), EvalMode (..), evalUnisonFile, ) @@ -20,6 +21,8 @@ import Unison.Cli.PrettyPrintUtils qualified as Cli import Unison.Cli.TypeCheck (computeTypecheckingEnvironment) import Unison.Cli.UniqueTypeGuidLookup qualified as Cli import Unison.Codebase qualified as Codebase +import Unison.Codebase.Branch qualified as Branch +import Unison.Codebase.Branch.Names qualified as Branch import Unison.Codebase.Editor.HandleInput.RuntimeUtils qualified as RuntimeUtils import Unison.Codebase.Editor.Output qualified as Output import Unison.Codebase.Editor.Slurp qualified as Slurp @@ -43,8 +46,15 @@ import Unison.UnisonFile (TypecheckedUnisonFile) import Unison.UnisonFile.Names qualified as UF import Unison.WatchKind qualified as WK -handleLoad :: Maybe FilePath -> Cli () -handleLoad maybePath = do +data LoadMode + = Normal + | -- Load a file without any names from the codebase except for library dependencies. + -- This mode is used for _replacing_ the current branch whole-sale with code from a scratch file. + LoadForCommit + deriving (Show, Eq, Ord) + +handleLoad :: LoadMode -> Maybe FilePath -> Cli (TypecheckedUnisonFile Symbol Ann) +handleLoad loadMode maybePath = do latestFile <- Cli.getLatestFile path <- (maybePath <|> fst <$> latestFile) & onNothing (Cli.returnEarly Output.NoUnisonFile) Cli.Env {loadSource} <- ask @@ -53,15 +63,20 @@ handleLoad maybePath = do Cli.InvalidSourceNameError -> Cli.returnEarly $ Output.InvalidSourceName path Cli.LoadError -> Cli.returnEarly $ Output.SourceLoadFailed path Cli.LoadSuccess contents -> pure contents - loadUnisonFile (Text.pack path) contents + loadUnisonFile loadMode (Text.pack path) contents -loadUnisonFile :: Text -> Text -> Cli () -loadUnisonFile sourceName text = do +loadUnisonFile :: LoadMode -> Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) +loadUnisonFile loadMode sourceName text = do Cli.respond $ Output.LoadingFile sourceName - currentNames <- Cli.currentNames - unisonFile <- withFile currentNames sourceName text - let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp currentNames - let names = UF.addNamesFromTypeCheckedUnisonFile unisonFile currentNames + names <- case loadMode of + Normal -> Cli.currentNames + LoadForCommit -> do + Cli.getCurrentBranch0 + <&> Branch.onlyLib + <&> Branch.toNames + unisonFile <- withFile names sourceName text + let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp names + let names = UF.addNamesFromTypeCheckedUnisonFile unisonFile names pped <- Cli.prettyPrintEnvDeclFromNames names let ppe = PPE.suffixifiedPPE pped Cli.respond $ Output.Typechecked sourceName ppe sr unisonFile @@ -71,6 +86,7 @@ loadUnisonFile sourceName text = do when (not (null e')) do Cli.respond $ Output.Evaluated text ppe bindings e' #latestTypecheckedFile .= Just (Right unisonFile) + pure unisonFile where withFile :: Names -> diff --git a/unison-cli/src/Unison/Codebase/TranscriptParser.hs b/unison-cli/src/Unison/Codebase/TranscriptParser.hs index 27627960ef..cfea447e55 100644 --- a/unison-cli/src/Unison/Codebase/TranscriptParser.hs +++ b/unison-cli/src/Unison/Codebase/TranscriptParser.hs @@ -50,6 +50,7 @@ import Unison.Cli.ProjectUtils qualified as ProjectUtils import Unison.Codebase (Codebase) import Unison.Codebase qualified as Codebase import Unison.Codebase.Editor.HandleInput qualified as HandleInput +import Unison.Codebase.Editor.HandleInput.Load qualified as Load import Unison.Codebase.Editor.Input (Event (UnisonFileChanged), Input (..)) import Unison.Codebase.Editor.Output qualified as Output import Unison.Codebase.Editor.UCMVersion (UCMVersion) @@ -549,7 +550,7 @@ run verbosity dir stanzas codebase runtime sbRuntime nRuntime config ucmVersion loop case input of Left _ -> s Right inp -> s & #lastInput ?~ inp - Cli.runCli env s1 (HandleInput.loop input) >>= \case + Cli.runCli env s1 (HandleInput.loop Load.Normal input) >>= \case (Cli.Success (), s2) -> next s2 (Cli.Continue, s2) -> next s2 (Cli.HaltRepl, _) -> onHalt diff --git a/unison-cli/src/Unison/CommandLine/Main.hs b/unison-cli/src/Unison/CommandLine/Main.hs index de0d7e12fb..ffc26cfbcd 100644 --- a/unison-cli/src/Unison/CommandLine/Main.hs +++ b/unison-cli/src/Unison/CommandLine/Main.hs @@ -32,6 +32,7 @@ import Unison.Codebase (Codebase) import Unison.Codebase qualified as Codebase import Unison.Codebase.Branch qualified as Branch import Unison.Codebase.Editor.HandleInput qualified as HandleInput +import Unison.Codebase.Editor.HandleInput.Load (LoadMode) import Unison.Codebase.Editor.Input (Event, Input (..)) import Unison.Codebase.Editor.Output (Output) import Unison.Codebase.Editor.UCMVersion (UCMVersion) @@ -142,8 +143,9 @@ main :: (CausalHash -> STM ()) -> (Path.Absolute -> STM ()) -> ShouldWatchFiles -> + LoadMode -> IO () -main dir welcome initialPath config initialInputs runtime sbRuntime nRuntime codebase serverBaseUrl ucmVersion notifyBranchChange notifyPathChange shouldWatchFiles = Ki.scoped \scope -> do +main dir welcome initialPath config initialInputs runtime sbRuntime nRuntime codebase serverBaseUrl ucmVersion notifyBranchChange notifyPathChange shouldWatchFiles loadMode = Ki.scoped \scope -> do rootVar <- newEmptyTMVarIO initialRootCausalHash <- Codebase.runTransaction codebase Operations.expectRootCausalHash _ <- Ki.fork scope do @@ -268,7 +270,7 @@ main dir welcome initialPath config initialInputs runtime sbRuntime nRuntime cod loop0 s0 = do let step = do input <- awaitInput s0 - (!result, resultState) <- Cli.runCli env s0 (HandleInput.loop input) + (!result, resultState) <- Cli.runCli env s0 (HandleInput.loop loadMode input) let sNext = case input of Left _ -> resultState Right inp -> resultState & #lastInput ?~ inp diff --git a/unison-cli/src/Unison/Main.hs b/unison-cli/src/Unison/Main.hs index 32e829c0b1..9e13dd63ee 100644 --- a/unison-cli/src/Unison/Main.hs +++ b/unison-cli/src/Unison/Main.hs @@ -64,6 +64,8 @@ import U.Codebase.HashTags (CausalHash) import U.Codebase.Sqlite.Queries qualified as Queries import Unison.Codebase (Codebase, CodebasePath) import Unison.Codebase qualified as Codebase +import Unison.Codebase.Editor.HandleInput.Load (LoadMode) +import Unison.Codebase.Editor.HandleInput.Load qualified as Load import Unison.Codebase.Editor.Input qualified as Input import Unison.Codebase.Execute (execute) import Unison.Codebase.Init (CodebaseInitOptions (..), InitError (..), InitResult (..), SpecifiedCodebase (..)) @@ -93,6 +95,7 @@ import Unison.Version (Version) import Unison.Version qualified as Version import UnliftIO qualified import UnliftIO.Directory (getHomeDirectory) +import UnliftIO.Environment (lookupEnv) type Runtimes = (RTI.Runtime Symbol, RTI.Runtime Symbol, RTI.Runtime Symbol) @@ -138,6 +141,10 @@ main version = do (renderUsageInfo, globalOptions, command) <- parseCLIArgs progName (Text.unpack (Version.gitDescribeWithDate version)) nrtp <- fixNativeRuntimePath (nativeRuntimePath globalOptions) let GlobalOptions {codebasePathOption = mCodePathOption, exitOption, lspFormattingConfig} = globalOptions + loadMode <- + lookupEnv "UNISON_LOAD_MODE" >>= \case + Just "commit" -> pure Load.LoadForCommit + _ -> pure Load.Normal withConfig mCodePathOption \config -> do currentDir <- getCurrentDirectory case command of @@ -190,6 +197,7 @@ main version = do noOpRootNotifier noOpPathNotifier CommandLine.ShouldNotWatchFiles + loadMode Run (RunFromPipe mainName) args -> do e <- safeReadUtf8StdIn case e of @@ -217,6 +225,7 @@ main version = do noOpRootNotifier noOpPathNotifier CommandLine.ShouldNotWatchFiles + loadMode Run (RunCompiled file) args -> BL.readFile file >>= \bs -> try (evaluate $ RTI.decodeStandalone bs) >>= \case @@ -351,6 +360,7 @@ main version = do notifyOnRootChanges notifyOnPathChanges shouldWatchFiles + loadMode Exit -> do Exit.exitSuccess where -- (runtime, sandboxed runtime) @@ -530,8 +540,9 @@ launch :: (CausalHash -> STM ()) -> (Path.Absolute -> STM ()) -> CommandLine.ShouldWatchFiles -> + LoadMode -> IO () -launch version dir config runtime sbRuntime nRuntime codebase inputs serverBaseUrl mayStartingPath initResult notifyRootChange notifyPathChange shouldWatchFiles = do +launch version dir config runtime sbRuntime nRuntime codebase inputs serverBaseUrl mayStartingPath initResult notifyRootChange notifyPathChange shouldWatchFiles loadMode = do showWelcomeHint <- Codebase.runTransaction codebase Queries.doProjectsExist let isNewCodebase = case initResult of CreatedCodebase -> NewlyCreatedCodebase @@ -553,6 +564,7 @@ launch version dir config runtime sbRuntime nRuntime codebase inputs serverBaseU notifyRootChange notifyPathChange shouldWatchFiles + loadMode newtype MarkdownFile = MarkdownFile FilePath From aee789a06a3ee47a4bef549df47f20649715e486 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Wed, 29 May 2024 14:17:12 -0700 Subject: [PATCH 04/11] Try to improve commit output --- .../src/Unison/Codebase/Editor/HandleInput.hs | 21 +++++++++++----- .../Codebase/Editor/HandleInput/Load.hs | 24 +++++++++---------- .../src/Unison/Codebase/Editor/Output.hs | 2 +- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs index ac4444a668..393fea5157 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs @@ -36,6 +36,7 @@ import Unison.Builtin qualified as Builtin import Unison.Builtin.Terms qualified as Builtin import Unison.Cli.Monad (Cli) import Unison.Cli.Monad qualified as Cli +import Unison.Cli.MonadUtils (getCurrentBranch0) import Unison.Cli.MonadUtils qualified as Cli import Unison.Cli.NamesUtils qualified as Cli import Unison.Cli.PrettyPrintUtils qualified as Cli @@ -195,7 +196,7 @@ loop loadMode e = do -- We skip this update if it was programmatically generated Cli.getLatestFile >>= \case Just (_, True) -> (#latestFile . _Just . _2) .= False - _ -> void $ loadUnisonFile loadMode sourceName text + _ -> void $ loadUnisonFile False loadMode sourceName text Right input -> let previewResponse sourceName sr uf = do names <- Cli.currentNames @@ -717,7 +718,7 @@ loop loadMode e = do FindI isVerbose fscope ws -> handleFindI isVerbose fscope ws input StructuredFindI _fscope ws -> handleStructuredFindI ws StructuredFindReplaceI ws -> handleStructuredFindReplaceI ws - LoadI maybePath -> void $ handleLoad loadMode maybePath + LoadI maybePath -> void $ handleLoad False loadMode maybePath ClearI -> Cli.respond ClearScreen AddI requestedNames -> do description <- inputDescription input @@ -743,7 +744,7 @@ loop loadMode e = do let sr = Slurp.slurpFile uf vars Slurp.AddOp currentNames previewResponse sourceName sr uf CommitI mayScratchFile -> do - uf <- handleLoad LoadForCommit mayScratchFile + uf <- handleLoad True LoadForCommit mayScratchFile description <- inputDescription input Cli.Env {codebase} <- ask currentPath <- Cli.getCurrentPath @@ -753,12 +754,20 @@ loop loadMode e = do <&> Branch.toNames let sr = Slurp.slurpFile uf mempty Slurp.AddOp libNames let adds = SlurpResult.adds sr + beforeBranch0 <- Cli.getCurrentBranch0 + beforePPED <- Cli.currentPrettyPrintEnvDecl Cli.stepAtNoSync (Path.unabsolute currentPath, doSlurpAdds adds uf . Branch.onlyLib) Cli.runTransaction . Codebase.addDefsToCodebase codebase . SlurpResult.filterUnisonFile sr $ uf - pped <- Cli.prettyPrintEnvDeclFromNames $ UF.addNamesFromTypeCheckedUnisonFile uf libNames - let suffixifiedPPE = PPED.suffixifiedPPE pped - Cli.respond $ SlurpOutput input suffixifiedPPE sr + -- pped <- Cli.prettyPrintEnvDeclFromNames $ UF.addNamesFromTypeCheckedUnisonFile uf libNames + -- let suffixifiedPPE = PPED.suffixifiedPPE pped + -- Cli.respond $ SlurpOutput input suffixifiedPPE sr Cli.syncRoot description + afterBranch0 <- getCurrentBranch0 + afterPPED <- Cli.currentPrettyPrintEnvDecl + (_ppe, diff) <- diffHelper beforeBranch0 afterBranch0 + let pped = afterPPED `PPED.addFallback` beforePPED + currentPath <- Cli.getCurrentPath + Cli.respondNumbered $ ShowDiffNamespace (Right currentPath) (Right currentPath) (PPED.suffixifiedPPE pped) diff UpdateI optionalPatch requestedNames -> handleUpdate input optionalPatch requestedNames Update2I -> handleUpdate2 PreviewUpdateI requestedNames -> do diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs index 32b71a2cba..5b9336c809 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs @@ -53,8 +53,8 @@ data LoadMode LoadForCommit deriving (Show, Eq, Ord) -handleLoad :: LoadMode -> Maybe FilePath -> Cli (TypecheckedUnisonFile Symbol Ann) -handleLoad loadMode maybePath = do +handleLoad :: Bool -> LoadMode -> Maybe FilePath -> Cli (TypecheckedUnisonFile Symbol Ann) +handleLoad silent loadMode maybePath = do latestFile <- Cli.getLatestFile path <- (maybePath <|> fst <$> latestFile) & onNothing (Cli.returnEarly Output.NoUnisonFile) Cli.Env {loadSource} <- ask @@ -63,27 +63,27 @@ handleLoad loadMode maybePath = do Cli.InvalidSourceNameError -> Cli.returnEarly $ Output.InvalidSourceName path Cli.LoadError -> Cli.returnEarly $ Output.SourceLoadFailed path Cli.LoadSuccess contents -> pure contents - loadUnisonFile loadMode (Text.pack path) contents + loadUnisonFile silent loadMode (Text.pack path) contents -loadUnisonFile :: LoadMode -> Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) -loadUnisonFile loadMode sourceName text = do - Cli.respond $ Output.LoadingFile sourceName - names <- case loadMode of +loadUnisonFile :: Bool -> LoadMode -> Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) +loadUnisonFile silent loadMode sourceName text = do + when (not silent) . Cli.respond $ Output.LoadingFile sourceName + currentNames <- case loadMode of Normal -> Cli.currentNames LoadForCommit -> do Cli.getCurrentBranch0 <&> Branch.onlyLib <&> Branch.toNames - unisonFile <- withFile names sourceName text - let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp names - let names = UF.addNamesFromTypeCheckedUnisonFile unisonFile names + unisonFile <- withFile currentNames sourceName text + let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp currentNames + let names = UF.addNamesFromTypeCheckedUnisonFile unisonFile currentNames pped <- Cli.prettyPrintEnvDeclFromNames names let ppe = PPE.suffixifiedPPE pped - Cli.respond $ Output.Typechecked sourceName ppe sr unisonFile + when (not silent) . Cli.respond $ Output.Typechecked sourceName ppe sr unisonFile (bindings, e) <- evalUnisonFile Permissive ppe unisonFile [] let e' = Map.map go e go (ann, kind, _hash, _uneval, eval, isHit) = (ann, kind, eval, isHit) - when (not (null e')) do + when (not silent && not (null e')) do Cli.respond $ Output.Evaluated text ppe bindings e' #latestTypecheckedFile .= Just (Right unisonFile) pure unisonFile diff --git a/unison-cli/src/Unison/Codebase/Editor/Output.hs b/unison-cli/src/Unison/Codebase/Editor/Output.hs index 421f39121c..3a418b88a2 100644 --- a/unison-cli/src/Unison/Codebase/Editor/Output.hs +++ b/unison-cli/src/Unison/Codebase/Editor/Output.hs @@ -27,7 +27,7 @@ import U.Codebase.HashTags (CausalHash) import U.Codebase.Sqlite.Project qualified as Sqlite import U.Codebase.Sqlite.ProjectBranch qualified as Sqlite import Unison.Auth.Types (CredentialFailure) -import Unison.Cli.MergeTypes (MergeSourceOrTarget, MergeSourceAndTarget) +import Unison.Cli.MergeTypes (MergeSourceAndTarget, MergeSourceOrTarget) import Unison.Cli.Share.Projects.Types qualified as Share import Unison.Codebase.Editor.Input import Unison.Codebase.Editor.Output.BranchDiff (BranchDiffOutput) From 2477b09db193dbd0bf112b5fc348c89bc210b36d Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Fri, 31 May 2024 09:52:24 -0700 Subject: [PATCH 05/11] Fix merge conflicts --- parser-typechecker/src/Unison/Codebase/Branch.hs | 6 ++++-- unison-cli/src/Unison/CommandLine/InputPatterns.hs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/parser-typechecker/src/Unison/Codebase/Branch.hs b/parser-typechecker/src/Unison/Codebase/Branch.hs index c532cf7292..78fb630e37 100644 --- a/parser-typechecker/src/Unison/Codebase/Branch.hs +++ b/parser-typechecker/src/Unison/Codebase/Branch.hs @@ -186,8 +186,10 @@ withoutTransitiveLibs b0 = in b0 & children .~ newChildren onlyLib :: Branch0 m -> Branch0 m -onlyLib Branch0 {..} = - branch0 _terms _types (Map.singleton NameSegment.libSegment (fromMaybe empty $ Map.lookup NameSegment.libSegment _children)) _edits +onlyLib b = + b + & children %~ \c -> + (Map.singleton NameSegment.libSegment (fromMaybe empty $ Map.lookup NameSegment.libSegment c)) -- | @deleteLibdep name branch@ deletes the libdep named @name@ from @branch@, if it exists. deleteLibdep :: NameSegment -> Branch0 m -> Branch0 m diff --git a/unison-cli/src/Unison/CommandLine/InputPatterns.hs b/unison-cli/src/Unison/CommandLine/InputPatterns.hs index 7c3bb5fe72..e034dabf4e 100644 --- a/unison-cli/src/Unison/CommandLine/InputPatterns.hs +++ b/unison-cli/src/Unison/CommandLine/InputPatterns.hs @@ -814,7 +814,7 @@ commit = ) \case [] -> pure $ Input.CommitI Nothing - [file] -> pure $ Input.CommitI . Just $ file + [file] -> Input.LoadI . Just <$> unsupportedStructuredArgument "a file name" file _ -> Left (I.help load) update :: InputPattern From 8b1265ed3ef55911ae3cc86ce1fb53243ed01c56 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Thu, 30 May 2024 10:07:02 -0700 Subject: [PATCH 06/11] Merge loadForCommit --- .../src/Unison/Codebase/Editor/HandleInput.hs | 7 +- .../Codebase/Editor/HandleInput/Commit.hs | 4 + .../Codebase/Editor/HandleInput/Load.hs | 108 ++++++++++++++++-- unison-cli/unison-cli.cabal | 1 + 4 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 unison-cli/src/Unison/Codebase/Editor/HandleInput/Commit.hs diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs index 6a915f943a..a13cc9e012 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs @@ -66,7 +66,8 @@ import Unison.Codebase.Editor.HandleInput.EditNamespace (handleEditNamespace) import Unison.Codebase.Editor.HandleInput.FindAndReplace (handleStructuredFindI, handleStructuredFindReplaceI) import Unison.Codebase.Editor.HandleInput.FormatFile qualified as Format import Unison.Codebase.Editor.HandleInput.InstallLib (handleInstallLib) -import Unison.Codebase.Editor.HandleInput.Load (EvalMode (Sandboxed), LoadMode (LoadForCommit), evalUnisonFile, handleLoad, loadUnisonFile) +import Unison.Codebase.Editor.HandleInput.Load (EvalMode (Sandboxed), LoadMode (LoadForCommit), evalUnisonFile, handleLoad) +import Unison.Codebase.Editor.HandleInput.Load qualified as Load import Unison.Codebase.Editor.HandleInput.Merge2 (handleMerge) import Unison.Codebase.Editor.HandleInput.MoveAll (handleMoveAll) import Unison.Codebase.Editor.HandleInput.MoveBranch (doMoveBranch) @@ -197,7 +198,9 @@ loop loadMode e = do -- We skip this update if it was programmatically generated Cli.getLatestFile >>= \case Just (_, True) -> (#latestFile . _Just . _2) .= False - _ -> void $ loadUnisonFile False loadMode sourceName text + _ -> case loadMode of + Load.LoadForCommit -> void $ Load.loadUnisonFileForCommit False sourceName text + Load.Normal -> void $ Load.loadUnisonFile sourceName text Right input -> let previewResponse sourceName sr uf = do names <- Cli.currentNames diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Commit.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Commit.hs new file mode 100644 index 0000000000..9778e47fe9 --- /dev/null +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Commit.hs @@ -0,0 +1,4 @@ +module Unison.Codebase.Editor.HandleInput.Commit (commitDiff) where + +commitDiff :: () +commitDiff = () diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs index bb991f32a8..bc26f1984b 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs @@ -1,6 +1,7 @@ module Unison.Codebase.Editor.HandleInput.Load ( handleLoad, loadUnisonFile, + loadUnisonFileForCommit, LoadMode (..), EvalMode (..), evalUnisonFile, @@ -23,10 +24,14 @@ import Unison.Cli.UniqueTypeGuidLookup qualified as Cli import Unison.Codebase qualified as Codebase import Unison.Codebase.Branch qualified as Branch import Unison.Codebase.Branch.Names qualified as Branch +import Unison.Codebase.Editor.HandleInput.NamespaceDiffUtils (diffHelper) import Unison.Codebase.Editor.HandleInput.RuntimeUtils qualified as RuntimeUtils +import Unison.Codebase.Editor.HandleInput.Update qualified as Update import Unison.Codebase.Editor.Output qualified as Output import Unison.Codebase.Editor.Slurp qualified as Slurp +import Unison.Codebase.Editor.SlurpResult qualified as SlurpResult import Unison.Codebase.Runtime qualified as Runtime +import Unison.Debug qualified as Debug import Unison.FileParsers qualified as FileParsers import Unison.Names (Names) import Unison.Parser.Ann (Ann) @@ -39,11 +44,13 @@ import Unison.PrettyPrintEnvDecl qualified as PPED import Unison.Reference qualified as Reference import Unison.Result qualified as Result import Unison.Symbol (Symbol) +import Unison.Syntax.Name qualified as Name import Unison.Syntax.Parser qualified as Parser import Unison.Term (Term) import Unison.Term qualified as Term import Unison.UnisonFile (TypecheckedUnisonFile) import Unison.UnisonFile.Names qualified as UF +import Unison.Util.Relation qualified as R import Unison.WatchKind qualified as WK data LoadMode @@ -63,27 +70,24 @@ handleLoad silent loadMode maybePath = do Cli.InvalidSourceNameError -> Cli.returnEarly $ Output.InvalidSourceName path Cli.LoadError -> Cli.returnEarly $ Output.SourceLoadFailed path Cli.LoadSuccess contents -> pure contents - loadUnisonFile silent loadMode (Text.pack path) contents + case loadMode of + Normal -> loadUnisonFile (Text.pack path) contents + LoadForCommit -> loadUnisonFileForCommit silent (Text.pack path) contents -loadUnisonFile :: Bool -> LoadMode -> Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) -loadUnisonFile silent loadMode sourceName text = do - when (not silent) . Cli.respond $ Output.LoadingFile sourceName - currentNames <- case loadMode of - Normal -> Cli.currentNames - LoadForCommit -> do - Cli.getCurrentBranch0 - <&> Branch.onlyLib - <&> Branch.toNames +loadUnisonFile :: Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) +loadUnisonFile sourceName text = do + Cli.respond $ Output.LoadingFile sourceName + currentNames <- Cli.currentNames unisonFile <- withFile currentNames sourceName text let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp currentNames let names = UF.addNamesFromTypeCheckedUnisonFile unisonFile currentNames pped <- Cli.prettyPrintEnvDeclFromNames names let ppe = PPE.suffixifiedPPE pped - when (not silent) . Cli.respond $ Output.Typechecked sourceName ppe sr unisonFile + Cli.respond $ Output.Typechecked sourceName ppe sr unisonFile (bindings, e) <- evalUnisonFile Permissive ppe unisonFile [] let e' = Map.map go e go (ann, kind, _hash, _uneval, eval, isHit) = (ann, kind, eval, isHit) - when (not silent && not (null e')) do + when (not (null e')) do Cli.respond $ Output.Evaluated text ppe bindings e' #latestTypecheckedFile .= Just (Right unisonFile) pure unisonFile @@ -133,6 +137,86 @@ loadUnisonFile silent loadMode sourceName text = do Cli.respond (Output.CompilerBugs text suffixifiedPPE cbs) Cli.returnEarlyWithoutOutput +loadUnisonFileForCommit :: Bool -> Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) +loadUnisonFileForCommit silent sourceName text = do + when (not silent) . Cli.respond $ Output.LoadingFile sourceName + beforeBranch0 <- Cli.getCurrentBranch0 + let beforeBranch0LibOnly = Branch.onlyLib beforeBranch0 + beforePPED <- Cli.currentPrettyPrintEnvDecl + let libNames = Branch.toNames beforeBranch0LibOnly + unisonFile <- withFile libNames sourceName text + let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp libNames + let adds = SlurpResult.adds sr + let afterBranch0 = Update.doSlurpAdds adds unisonFile beforeBranch0LibOnly + -- let beforeWithoutLib = + -- Branch.withoutLib beforeBranch0 + let afterWithoutLib = Branch.withoutLib afterBranch0 + -- Debug.debugM Debug.Temp "Old doc:" (R.lookupRan (Name.unsafeParseText "oauth2.handler.doc") (Branch.deepTerms beforeBranch0)) + Debug.debugM Debug.Temp "New doc:" (R.lookupRan (Name.unsafeParseText "oauth2.handler.doc") (Branch.deepTerms afterBranch0)) + Debug.debugM Debug.Temp "New doc Without Lib:" (R.lookupRan (Name.unsafeParseText "oauth2.handler.doc") (Branch.deepTerms afterWithoutLib)) + -- Debug.debugM Debug.Temp "After Branch terms:" (Branch.deepTerms $ Branch.withoutLib afterBranch0) + -- Debug.debugM Debug.Temp "After Branch types:" (Branch.deepTypes $ Branch.withoutLib afterBranch0) + afterPPED <- Cli.currentPrettyPrintEnvDecl + (_ppe, diff) <- diffHelper beforeBranch0 afterBranch0 + -- Debug.debugM Debug.Temp "DIFF" diff + let pped = afterPPED `PPED.addFallback` beforePPED + let ppe = PPE.suffixifiedPPE pped + currentPath <- Cli.getCurrentPath + Cli.respondNumbered $ Output.ShowDiffNamespace (Right currentPath) (Right currentPath) ppe diff + when (not silent) do + (bindings, e) <- evalUnisonFile Permissive ppe unisonFile [] + let e' = Map.map go e + go (ann, kind, _hash, _uneval, eval, isHit) = (ann, kind, eval, isHit) + when (not (null e')) do + Cli.respond $ Output.Evaluated text ppe bindings e' + #latestTypecheckedFile .= Just (Right unisonFile) + pure unisonFile + where + withFile :: + Names -> + Text -> + Text -> + Cli (TypecheckedUnisonFile Symbol Ann) + withFile names sourceName text = do + currentPath <- Cli.getCurrentPath + State.modify' \loopState -> + loopState + & #latestFile .~ Just (Text.unpack sourceName, False) + & #latestTypecheckedFile .~ Nothing + Cli.Env {codebase, generateUniqueName} <- ask + uniqueName <- liftIO generateUniqueName + let parsingEnv = + Parser.ParsingEnv + { uniqueNames = uniqueName, + uniqueTypeGuid = Cli.loadUniqueTypeGuid currentPath, + names + } + unisonFile <- + Cli.runTransaction (Parsers.parseFile (Text.unpack sourceName) (Text.unpack text) parsingEnv) + & onLeftM \err -> Cli.returnEarly (Output.ParseErrors text [err]) + -- set that the file at least parsed (but didn't typecheck) + State.modify' (& #latestTypecheckedFile .~ Just (Left unisonFile)) + typecheckingEnv <- + Cli.runTransaction do + computeTypecheckingEnvironment (FileParsers.ShouldUseTndr'Yes parsingEnv) codebase [] unisonFile + let Result.Result notes maybeTypecheckedUnisonFile = FileParsers.synthesizeFile typecheckingEnv unisonFile + maybeTypecheckedUnisonFile & onNothing do + let namesWithFileDefinitions = UF.addNamesFromUnisonFile unisonFile names + pped <- Cli.prettyPrintEnvDeclFromNames namesWithFileDefinitions + let suffixifiedPPE = PPED.suffixifiedPPE pped + let tes = [err | Result.TypeError err <- toList notes] + cbs = + [ bug + | Result.CompilerBug (Result.TypecheckerBug bug) <- + toList notes + ] + when (not (null tes)) do + currentPath <- Cli.getCurrentPath + Cli.respond (Output.TypeErrors currentPath text suffixifiedPPE tes) + when (not (null cbs)) do + Cli.respond (Output.CompilerBugs text suffixifiedPPE cbs) + Cli.returnEarlyWithoutOutput + data EvalMode = Sandboxed | Permissive | Native -- | Evaluate all watched expressions in a UnisonFile and return diff --git a/unison-cli/unison-cli.cabal b/unison-cli/unison-cli.cabal index 79f8ada36d..fbea509629 100644 --- a/unison-cli/unison-cli.cabal +++ b/unison-cli/unison-cli.cabal @@ -55,6 +55,7 @@ library Unison.Codebase.Editor.HandleInput.Branch Unison.Codebase.Editor.HandleInput.Branches Unison.Codebase.Editor.HandleInput.BranchRename + Unison.Codebase.Editor.HandleInput.Commit Unison.Codebase.Editor.HandleInput.DebugDefinition Unison.Codebase.Editor.HandleInput.DebugFoldRanges Unison.Codebase.Editor.HandleInput.DeleteBranch From 85a18a07c55a44b23e7d5dc9c90d49084ba43c32 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Fri, 31 May 2024 10:09:07 -0700 Subject: [PATCH 07/11] Clean up commit command --- .../src/Unison/Codebase/Editor/HandleInput.hs | 19 +-- .../Codebase/Editor/HandleInput/Load.hs | 145 ++++++------------ 2 files changed, 50 insertions(+), 114 deletions(-) diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs index a13cc9e012..e2dbc8dd3a 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs @@ -738,8 +738,6 @@ loop loadMode e = do previewResponse sourceName sr uf CommitI mayScratchFile -> do uf <- handleLoad True LoadForCommit mayScratchFile - description <- inputDescription input - Cli.Env {codebase} <- ask currentPath <- Cli.getCurrentPath libNames <- Cli.getCurrentBranch0 @@ -748,19 +746,14 @@ loop loadMode e = do let sr = Slurp.slurpFile uf mempty Slurp.AddOp libNames let adds = SlurpResult.adds sr beforeBranch0 <- Cli.getCurrentBranch0 - beforePPED <- Cli.currentPrettyPrintEnvDecl - Cli.stepAtNoSync (Path.unabsolute currentPath, doSlurpAdds adds uf . Branch.onlyLib) - Cli.runTransaction . Codebase.addDefsToCodebase codebase . SlurpResult.filterUnisonFile sr $ uf - -- pped <- Cli.prettyPrintEnvDeclFromNames $ UF.addNamesFromTypeCheckedUnisonFile uf libNames - -- let suffixifiedPPE = PPED.suffixifiedPPE pped - -- Cli.respond $ SlurpOutput input suffixifiedPPE sr - Cli.syncRoot description + Cli.Env {codebase} <- ask + Cli.runTransaction . Codebase.addDefsToCodebase codebase $ uf + description <- inputDescription input + Cli.stepAt description (Path.unabsolute currentPath, doSlurpAdds adds uf . Branch.onlyLib) afterBranch0 <- getCurrentBranch0 - afterPPED <- Cli.currentPrettyPrintEnvDecl - (_ppe, diff) <- diffHelper beforeBranch0 afterBranch0 - let pped = afterPPED `PPED.addFallback` beforePPED + (ppe, diff) <- diffHelper beforeBranch0 afterBranch0 currentPath <- Cli.getCurrentPath - Cli.respondNumbered $ ShowDiffNamespace (Right currentPath) (Right currentPath) (PPED.suffixifiedPPE pped) diff + Cli.respondNumbered $ ShowDiffNamespace (Right currentPath) (Right currentPath) ppe diff UpdateI optionalPatch requestedNames -> handleUpdate input optionalPatch requestedNames Update2I -> handleUpdate2 PreviewUpdateI requestedNames -> do diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs index bc26f1984b..5ab4ea8210 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs @@ -31,7 +31,6 @@ import Unison.Codebase.Editor.Output qualified as Output import Unison.Codebase.Editor.Slurp qualified as Slurp import Unison.Codebase.Editor.SlurpResult qualified as SlurpResult import Unison.Codebase.Runtime qualified as Runtime -import Unison.Debug qualified as Debug import Unison.FileParsers qualified as FileParsers import Unison.Names (Names) import Unison.Parser.Ann (Ann) @@ -44,13 +43,11 @@ import Unison.PrettyPrintEnvDecl qualified as PPED import Unison.Reference qualified as Reference import Unison.Result qualified as Result import Unison.Symbol (Symbol) -import Unison.Syntax.Name qualified as Name import Unison.Syntax.Parser qualified as Parser import Unison.Term (Term) import Unison.Term qualified as Term import Unison.UnisonFile (TypecheckedUnisonFile) import Unison.UnisonFile.Names qualified as UF -import Unison.Util.Relation qualified as R import Unison.WatchKind qualified as WK data LoadMode @@ -91,51 +88,6 @@ loadUnisonFile sourceName text = do Cli.respond $ Output.Evaluated text ppe bindings e' #latestTypecheckedFile .= Just (Right unisonFile) pure unisonFile - where - withFile :: - Names -> - Text -> - Text -> - Cli (TypecheckedUnisonFile Symbol Ann) - withFile names sourceName text = do - currentPath <- Cli.getCurrentPath - State.modify' \loopState -> - loopState - & #latestFile .~ Just (Text.unpack sourceName, False) - & #latestTypecheckedFile .~ Nothing - Cli.Env {codebase, generateUniqueName} <- ask - uniqueName <- liftIO generateUniqueName - let parsingEnv = - Parser.ParsingEnv - { uniqueNames = uniqueName, - uniqueTypeGuid = Cli.loadUniqueTypeGuid currentPath, - names - } - unisonFile <- - Cli.runTransaction (Parsers.parseFile (Text.unpack sourceName) (Text.unpack text) parsingEnv) - & onLeftM \err -> Cli.returnEarly (Output.ParseErrors text [err]) - -- set that the file at least parsed (but didn't typecheck) - State.modify' (& #latestTypecheckedFile .~ Just (Left unisonFile)) - typecheckingEnv <- - Cli.runTransaction do - computeTypecheckingEnvironment (FileParsers.ShouldUseTndr'Yes parsingEnv) codebase [] unisonFile - let Result.Result notes maybeTypecheckedUnisonFile = FileParsers.synthesizeFile typecheckingEnv unisonFile - maybeTypecheckedUnisonFile & onNothing do - let namesWithFileDefinitions = UF.addNamesFromUnisonFile unisonFile names - pped <- Cli.prettyPrintEnvDeclFromNames namesWithFileDefinitions - let suffixifiedPPE = PPED.suffixifiedPPE pped - let tes = [err | Result.TypeError err <- toList notes] - cbs = - [ bug - | Result.CompilerBug (Result.TypecheckerBug bug) <- - toList notes - ] - when (not (null tes)) do - currentPath <- Cli.getCurrentPath - Cli.respond (Output.TypeErrors currentPath text suffixifiedPPE tes) - when (not (null cbs)) do - Cli.respond (Output.CompilerBugs text suffixifiedPPE cbs) - Cli.returnEarlyWithoutOutput loadUnisonFileForCommit :: Bool -> Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) loadUnisonFileForCommit silent sourceName text = do @@ -148,17 +100,8 @@ loadUnisonFileForCommit silent sourceName text = do let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp libNames let adds = SlurpResult.adds sr let afterBranch0 = Update.doSlurpAdds adds unisonFile beforeBranch0LibOnly - -- let beforeWithoutLib = - -- Branch.withoutLib beforeBranch0 - let afterWithoutLib = Branch.withoutLib afterBranch0 - -- Debug.debugM Debug.Temp "Old doc:" (R.lookupRan (Name.unsafeParseText "oauth2.handler.doc") (Branch.deepTerms beforeBranch0)) - Debug.debugM Debug.Temp "New doc:" (R.lookupRan (Name.unsafeParseText "oauth2.handler.doc") (Branch.deepTerms afterBranch0)) - Debug.debugM Debug.Temp "New doc Without Lib:" (R.lookupRan (Name.unsafeParseText "oauth2.handler.doc") (Branch.deepTerms afterWithoutLib)) - -- Debug.debugM Debug.Temp "After Branch terms:" (Branch.deepTerms $ Branch.withoutLib afterBranch0) - -- Debug.debugM Debug.Temp "After Branch types:" (Branch.deepTypes $ Branch.withoutLib afterBranch0) afterPPED <- Cli.currentPrettyPrintEnvDecl (_ppe, diff) <- diffHelper beforeBranch0 afterBranch0 - -- Debug.debugM Debug.Temp "DIFF" diff let pped = afterPPED `PPED.addFallback` beforePPED let ppe = PPE.suffixifiedPPE pped currentPath <- Cli.getCurrentPath @@ -171,51 +114,51 @@ loadUnisonFileForCommit silent sourceName text = do Cli.respond $ Output.Evaluated text ppe bindings e' #latestTypecheckedFile .= Just (Right unisonFile) pure unisonFile - where - withFile :: - Names -> - Text -> - Text -> - Cli (TypecheckedUnisonFile Symbol Ann) - withFile names sourceName text = do + +withFile :: + Names -> + Text -> + Text -> + Cli (TypecheckedUnisonFile Symbol Ann) +withFile names sourceName text = do + currentPath <- Cli.getCurrentPath + State.modify' \loopState -> + loopState + & #latestFile .~ Just (Text.unpack sourceName, False) + & #latestTypecheckedFile .~ Nothing + Cli.Env {codebase, generateUniqueName} <- ask + uniqueName <- liftIO generateUniqueName + let parsingEnv = + Parser.ParsingEnv + { uniqueNames = uniqueName, + uniqueTypeGuid = Cli.loadUniqueTypeGuid currentPath, + names + } + unisonFile <- + Cli.runTransaction (Parsers.parseFile (Text.unpack sourceName) (Text.unpack text) parsingEnv) + & onLeftM \err -> Cli.returnEarly (Output.ParseErrors text [err]) + -- set that the file at least parsed (but didn't typecheck) + State.modify' (& #latestTypecheckedFile .~ Just (Left unisonFile)) + typecheckingEnv <- + Cli.runTransaction do + computeTypecheckingEnvironment (FileParsers.ShouldUseTndr'Yes parsingEnv) codebase [] unisonFile + let Result.Result notes maybeTypecheckedUnisonFile = FileParsers.synthesizeFile typecheckingEnv unisonFile + maybeTypecheckedUnisonFile & onNothing do + let namesWithFileDefinitions = UF.addNamesFromUnisonFile unisonFile names + pped <- Cli.prettyPrintEnvDeclFromNames namesWithFileDefinitions + let suffixifiedPPE = PPED.suffixifiedPPE pped + let tes = [err | Result.TypeError err <- toList notes] + cbs = + [ bug + | Result.CompilerBug (Result.TypecheckerBug bug) <- + toList notes + ] + when (not (null tes)) do currentPath <- Cli.getCurrentPath - State.modify' \loopState -> - loopState - & #latestFile .~ Just (Text.unpack sourceName, False) - & #latestTypecheckedFile .~ Nothing - Cli.Env {codebase, generateUniqueName} <- ask - uniqueName <- liftIO generateUniqueName - let parsingEnv = - Parser.ParsingEnv - { uniqueNames = uniqueName, - uniqueTypeGuid = Cli.loadUniqueTypeGuid currentPath, - names - } - unisonFile <- - Cli.runTransaction (Parsers.parseFile (Text.unpack sourceName) (Text.unpack text) parsingEnv) - & onLeftM \err -> Cli.returnEarly (Output.ParseErrors text [err]) - -- set that the file at least parsed (but didn't typecheck) - State.modify' (& #latestTypecheckedFile .~ Just (Left unisonFile)) - typecheckingEnv <- - Cli.runTransaction do - computeTypecheckingEnvironment (FileParsers.ShouldUseTndr'Yes parsingEnv) codebase [] unisonFile - let Result.Result notes maybeTypecheckedUnisonFile = FileParsers.synthesizeFile typecheckingEnv unisonFile - maybeTypecheckedUnisonFile & onNothing do - let namesWithFileDefinitions = UF.addNamesFromUnisonFile unisonFile names - pped <- Cli.prettyPrintEnvDeclFromNames namesWithFileDefinitions - let suffixifiedPPE = PPED.suffixifiedPPE pped - let tes = [err | Result.TypeError err <- toList notes] - cbs = - [ bug - | Result.CompilerBug (Result.TypecheckerBug bug) <- - toList notes - ] - when (not (null tes)) do - currentPath <- Cli.getCurrentPath - Cli.respond (Output.TypeErrors currentPath text suffixifiedPPE tes) - when (not (null cbs)) do - Cli.respond (Output.CompilerBugs text suffixifiedPPE cbs) - Cli.returnEarlyWithoutOutput + Cli.respond (Output.TypeErrors currentPath text suffixifiedPPE tes) + when (not (null cbs)) do + Cli.respond (Output.CompilerBugs text suffixifiedPPE cbs) + Cli.returnEarlyWithoutOutput data EvalMode = Sandboxed | Permissive | Native From f76d5e0dc0182f584d489821040fdab8ec46be11 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Fri, 31 May 2024 10:22:22 -0700 Subject: [PATCH 08/11] Add type lookup for typechecked files --- parser-typechecker/src/Unison/UnisonFile.hs | 30 +++++++++++++ .../Codebase/Editor/HandleInput/Load.hs | 4 +- .../Editor/HandleInput/NamespaceDiffUtils.hs | 44 +++++++++++++++++++ unison-src/transcripts/commit-command.md | 7 +-- 4 files changed, 80 insertions(+), 5 deletions(-) diff --git a/parser-typechecker/src/Unison/UnisonFile.hs b/parser-typechecker/src/Unison/UnisonFile.hs index 9613ce1642..521dd02468 100644 --- a/parser-typechecker/src/Unison/UnisonFile.hs +++ b/parser-typechecker/src/Unison/UnisonFile.hs @@ -36,6 +36,8 @@ module Unison.UnisonFile typecheckedUnisonFile, Unison.UnisonFile.rewrite, prepareRewrite, + typeLookupForTypecheckedFile, + typeOfReferentFromTypecheckedUnisonFile, ) where @@ -56,6 +58,7 @@ import Unison.LabeledDependency qualified as LD import Unison.Prelude import Unison.Reference (Reference) import Unison.Reference qualified as Reference +import Unison.Referent (Referent) import Unison.Referent qualified as Referent import Unison.Term (Term) import Unison.Term qualified as Term @@ -355,6 +358,33 @@ declsToTypeLookup uf = where wrangle = Map.fromList . Map.elems +-- | Provides a lookup for all types and terms within the unison file. +typeLookupForTypecheckedFile :: Var v => TypecheckedUnisonFile v a -> TL.TypeLookup v a +typeLookupForTypecheckedFile tf = + TL.TypeLookup + termTypeLookup + (wrangle $ dataDeclarationsId' tf) + (wrangle $ effectDeclarationsId' tf) + where + termTypeLookup = + hashTermsId tf + & Map.elems + & fmap + (\(_ann, termRefId, _wk, _trm, typ) -> (Reference.DerivedId termRefId, typ)) + & Map.fromList + wrangle = Map.fromList . fmap (first Reference.DerivedId) . Map.elems + +-- | Gets the type of a reference from either the parsed file or the codebase. +typeOfReferentFromTypecheckedUnisonFile :: Var v => TypecheckedUnisonFile v a -> Referent -> Maybe (Type v a) +typeOfReferentFromTypecheckedUnisonFile tf = \case + Referent.Ref reference -> + Map.lookup reference typeOfTerms + Referent.Con (ConstructorReference typeReference cid) _type -> do + decl <- Map.lookup typeReference dataDecls <|> (DD.toDataDecl <$> Map.lookup typeReference effectDecls) + DD.typeOfConstructor decl cid + where + TL.TypeLookup {typeOfTerms, dataDecls, effectDecls} = typeLookupForTypecheckedFile tf + -- Returns true if the file has any definitions or watches nonEmpty :: TypecheckedUnisonFile v a -> Bool nonEmpty uf = diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs index 5ab4ea8210..c98305b621 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs @@ -24,7 +24,7 @@ import Unison.Cli.UniqueTypeGuidLookup qualified as Cli import Unison.Codebase qualified as Codebase import Unison.Codebase.Branch qualified as Branch import Unison.Codebase.Branch.Names qualified as Branch -import Unison.Codebase.Editor.HandleInput.NamespaceDiffUtils (diffHelper) +import Unison.Codebase.Editor.HandleInput.NamespaceDiffUtils (diffFromTypecheckedUnisonFile) import Unison.Codebase.Editor.HandleInput.RuntimeUtils qualified as RuntimeUtils import Unison.Codebase.Editor.HandleInput.Update qualified as Update import Unison.Codebase.Editor.Output qualified as Output @@ -101,7 +101,7 @@ loadUnisonFileForCommit silent sourceName text = do let adds = SlurpResult.adds sr let afterBranch0 = Update.doSlurpAdds adds unisonFile beforeBranch0LibOnly afterPPED <- Cli.currentPrettyPrintEnvDecl - (_ppe, diff) <- diffHelper beforeBranch0 afterBranch0 + (_ppe, diff) <- diffFromTypecheckedUnisonFile unisonFile beforeBranch0 afterBranch0 let pped = afterPPED `PPED.addFallback` beforePPED let ppe = PPE.suffixifiedPPE pped currentPath <- Cli.getCurrentPath diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs index 0416672e3e..32d8703162 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs @@ -1,6 +1,7 @@ -- | Helpers/utils that have to do with namespace diffs. module Unison.Codebase.Editor.HandleInput.NamespaceDiffUtils ( diffHelper, + diffFromTypecheckedUnisonFile, ) where @@ -24,8 +25,13 @@ import Unison.PrettyPrintEnv qualified as PPE import Unison.PrettyPrintEnvDecl qualified as PPED import Unison.Reference (Reference) import Unison.Reference qualified as Reference +import Unison.Referent qualified as Referent import Unison.Sqlite qualified as Sqlite import Unison.Symbol (Symbol) +import Unison.Type (Type) +import Unison.Typechecker.TypeLookup qualified as TL +import Unison.UnisonFile (TypecheckedUnisonFile) +import Unison.UnisonFile qualified as UF diffHelper :: Branch0 IO -> @@ -48,6 +54,44 @@ diffHelper before after = (Branch.toNames after) diff +-- | Like diffHelper, but allows providing definitions from a file which may not have been added to the codebase +-- yet. +diffFromTypecheckedUnisonFile :: + TypecheckedUnisonFile Symbol Ann -> + Branch0 IO -> + Branch0 IO -> + Cli (PPE.PrettyPrintEnv, OBranchDiff.BranchDiffOutput Symbol Ann) +diffFromTypecheckedUnisonFile tf before after = do + Cli.time "diffFromTypecheckedUnisonFile" do + Cli.Env {codebase} <- ask + hqLength <- Cli.runTransaction Codebase.hashLength + diff <- liftIO (BranchDiff.diff0 before after) + names <- Cli.currentNames + pped <- Cli.prettyPrintEnvDeclFromNames names + let suffixifiedPPE = PPED.suffixifiedPPE pped + fmap (suffixifiedPPE,) do + OBranchDiff.toOutput + (getTypeOfReferent codebase) + (getDeclOrBuiltin codebase) + hqLength + (Branch.toNames before) + (Branch.toNames after) + diff + where + TL.TypeLookup {dataDecls, effectDecls} = UF.typeLookupForTypecheckedFile tf + referentTypeFromFile :: Referent.Referent -> (Maybe (Type Symbol Ann)) + referentTypeFromFile ref = UF.typeOfReferentFromTypecheckedUnisonFile tf ref + getDeclOrBuiltin :: Codebase m Symbol Ann -> Reference -> Cli (Maybe (DD.DeclOrBuiltin Symbol Ann)) + getDeclOrBuiltin codebase ref = runMaybeT do + hoistMaybe (Map.lookup ref dataDecls <&> DD.Decl . Right) + <|> hoistMaybe ((Map.lookup ref effectDecls) <&> DD.Decl . Left) + <|> (MaybeT (Cli.runTransaction $ declOrBuiltin codebase ref)) + getTypeOfReferent codebase ref = + runMaybeT $ + do + (hoistMaybe $ referentTypeFromFile ref) + <|> (MaybeT . Cli.runTransaction $ Codebase.getTypeOfReferent codebase ref) + declOrBuiltin :: Codebase m Symbol Ann -> Reference -> Sqlite.Transaction (Maybe (DD.DeclOrBuiltin Symbol Ann)) declOrBuiltin codebase r = case r of Reference.Builtin {} -> diff --git a/unison-src/transcripts/commit-command.md b/unison-src/transcripts/commit-command.md index c162f115ff..14f9f7995c 100644 --- a/unison-src/transcripts/commit-command.md +++ b/unison-src/transcripts/commit-command.md @@ -5,7 +5,7 @@ Add some definitions to the codebase for us to later update. ```unison -type MyRecord = +type MyRecord = { nat : Nat , text : Text , bool : Boolean @@ -29,8 +29,8 @@ Should be able to easily change and remove record fields and definitions in a si ```unison -- Rename and re-type the `nat` field to `getNat` --- Remove the `bool` field -type MyRecord = +-- Remove the `bool` field +type MyRecord = { getNat : () -> Nat , text : Text } @@ -47,6 +47,7 @@ addToRecordField rec = !(getNat rec) + 10 ``` ```ucm +.> experimental.commit.preview .> experimental.commit .> find .> view MyRecord From bd7802b8381f93fee57924fb12197ec1e56a1898 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Fri, 31 May 2024 10:22:22 -0700 Subject: [PATCH 09/11] Add experimental.commit.preview --- .../src/Unison/Codebase/Editor/HandleInput.hs | 13 +++++-------- unison-cli/src/Unison/Codebase/Editor/Input.hs | 1 + .../src/Unison/CommandLine/InputPatterns.hs | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs index e2dbc8dd3a..40bd23ee8b 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs @@ -37,7 +37,6 @@ import Unison.Builtin qualified as Builtin import Unison.Builtin.Terms qualified as Builtin import Unison.Cli.Monad (Cli) import Unison.Cli.Monad qualified as Cli -import Unison.Cli.MonadUtils (getCurrentBranch0) import Unison.Cli.MonadUtils qualified as Cli import Unison.Cli.NamesUtils qualified as Cli import Unison.Cli.PrettyPrintUtils qualified as Cli @@ -737,7 +736,7 @@ loop loadMode e = do let sr = Slurp.slurpFile uf vars Slurp.AddOp currentNames previewResponse sourceName sr uf CommitI mayScratchFile -> do - uf <- handleLoad True LoadForCommit mayScratchFile + uf <- handleLoad False LoadForCommit mayScratchFile currentPath <- Cli.getCurrentPath libNames <- Cli.getCurrentBranch0 @@ -745,15 +744,12 @@ loop loadMode e = do <&> Branch.toNames let sr = Slurp.slurpFile uf mempty Slurp.AddOp libNames let adds = SlurpResult.adds sr - beforeBranch0 <- Cli.getCurrentBranch0 Cli.Env {codebase} <- ask Cli.runTransaction . Codebase.addDefsToCodebase codebase $ uf description <- inputDescription input Cli.stepAt description (Path.unabsolute currentPath, doSlurpAdds adds uf . Branch.onlyLib) - afterBranch0 <- getCurrentBranch0 - (ppe, diff) <- diffHelper beforeBranch0 afterBranch0 - currentPath <- Cli.getCurrentPath - Cli.respondNumbered $ ShowDiffNamespace (Right currentPath) (Right currentPath) ppe diff + CommitPreviewI mayScratchFile -> do + void $ handleLoad False LoadForCommit mayScratchFile UpdateI optionalPatch requestedNames -> handleUpdate input optionalPatch requestedNames Update2I -> handleUpdate2 PreviewUpdateI requestedNames -> do @@ -1073,7 +1069,8 @@ inputDescription input = DeleteTarget'ProjectBranch _ -> wat DeleteTarget'Project _ -> wat AddI _selection -> pure "add" - CommitI mayScratchFile -> pure ("commit" <> maybe "" Text.pack mayScratchFile) + CommitI mayScratchFile -> pure ("experimental.commit" <> maybe "" Text.pack mayScratchFile) + CommitPreviewI mayScratchFile -> pure ("experimental.commit.preview" <> maybe "" Text.pack mayScratchFile) UpdateI p0 _selection -> do p <- case p0 of diff --git a/unison-cli/src/Unison/Codebase/Editor/Input.hs b/unison-cli/src/Unison/Codebase/Editor/Input.hs index a68e88f4f7..fac8381cdb 100644 --- a/unison-cli/src/Unison/Codebase/Editor/Input.hs +++ b/unison-cli/src/Unison/Codebase/Editor/Input.hs @@ -148,6 +148,7 @@ data Input | AddI (Set Name) | PreviewAddI (Set Name) | CommitI (Maybe FilePath) + | CommitPreviewI (Maybe FilePath) | UpdateI OptionalPatch (Set Name) | Update2I | PreviewUpdateI (Set Name) diff --git a/unison-cli/src/Unison/CommandLine/InputPatterns.hs b/unison-cli/src/Unison/CommandLine/InputPatterns.hs index e034dabf4e..7238d13466 100644 --- a/unison-cli/src/Unison/CommandLine/InputPatterns.hs +++ b/unison-cli/src/Unison/CommandLine/InputPatterns.hs @@ -19,6 +19,7 @@ module Unison.CommandLine.InputPatterns clear, clone, commit, + commitPreview, compileScheme, createAuthor, debugClearWatchCache, @@ -191,8 +192,8 @@ import Unison.Name (Name) import Unison.Name qualified as Name import Unison.NameSegment (NameSegment) import Unison.NameSegment qualified as NameSegment -import Unison.Prelude hiding (view) import Unison.Parser.Ann (Ann) +import Unison.Prelude hiding (view) import Unison.Project ( ProjectAndBranch (..), ProjectAndBranchNames (..), @@ -817,6 +818,20 @@ commit = [file] -> Input.LoadI . Just <$> unsupportedStructuredArgument "a file name" file _ -> Left (I.help load) +commitPreview :: InputPattern +commitPreview = + InputPattern + "experimental.commit.preview" + [] + I.Visible + [("scratch file", Optional, filePathArg)] + ( "`experimental.commit.preview` shows the diff which would be applied if you were to run " <> patternName commit + ) + \case + [] -> pure $ Input.CommitI Nothing + [file] -> Input.LoadI . Just <$> unsupportedStructuredArgument "a file name" file + _ -> Left (I.help load) + update :: InputPattern update = InputPattern From 0adc6f3e2c354e7c813509406be7f1943dcaabd3 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Fri, 31 May 2024 14:28:02 -0700 Subject: [PATCH 10/11] Fix up commit.preview and accidentally ignoring top-level terms --- .../src/Unison/Codebase/Branch.hs | 5 +- .../src/Unison/Codebase/Editor/HandleInput.hs | 2 +- .../Codebase/Editor/HandleInput/Load.hs | 12 +- .../Editor/HandleInput/NamespaceDiffUtils.hs | 7 +- .../src/Unison/Codebase/Editor/Output.hs | 3 +- .../src/Unison/CommandLine/InputPatterns.hs | 7 +- unison-src/transcripts/commit-command.md | 6 +- .../transcripts/commit-command.output.md | 286 ++++++++++-------- 8 files changed, 188 insertions(+), 140 deletions(-) diff --git a/parser-typechecker/src/Unison/Codebase/Branch.hs b/parser-typechecker/src/Unison/Codebase/Branch.hs index 78fb630e37..b62bb6351e 100644 --- a/parser-typechecker/src/Unison/Codebase/Branch.hs +++ b/parser-typechecker/src/Unison/Codebase/Branch.hs @@ -187,9 +187,8 @@ withoutTransitiveLibs b0 = onlyLib :: Branch0 m -> Branch0 m onlyLib b = - b - & children %~ \c -> - (Map.singleton NameSegment.libSegment (fromMaybe empty $ Map.lookup NameSegment.libSegment c)) + let newChildren = (Map.singleton NameSegment.libSegment (fromMaybe empty $ Map.lookup NameSegment.libSegment (b ^. children))) + in branch0 mempty mempty newChildren mempty -- | @deleteLibdep name branch@ deletes the libdep named @name@ from @branch@, if it exists. deleteLibdep :: NameSegment -> Branch0 m -> Branch0 m diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs index 40bd23ee8b..11b3061afb 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput.hs @@ -710,7 +710,7 @@ loop loadMode e = do FindI isVerbose fscope ws -> handleFindI isVerbose fscope ws input StructuredFindI _fscope ws -> handleStructuredFindI ws StructuredFindReplaceI ws -> handleStructuredFindReplaceI ws - LoadI maybePath -> void $ handleLoad False loadMode maybePath + LoadI maybePath -> void $ handleLoad True loadMode maybePath ClearI -> Cli.respond ClearScreen AddI requestedNames -> do description <- inputDescription input diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs index c98305b621..c8e1e80e5a 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/Load.hs @@ -58,7 +58,7 @@ data LoadMode deriving (Show, Eq, Ord) handleLoad :: Bool -> LoadMode -> Maybe FilePath -> Cli (TypecheckedUnisonFile Symbol Ann) -handleLoad silent loadMode maybePath = do +handleLoad showWatchExprs loadMode maybePath = do latestFile <- Cli.getLatestFile path <- (maybePath <|> fst <$> latestFile) & onNothing (Cli.returnEarly Output.NoUnisonFile) Cli.Env {loadSource} <- ask @@ -69,7 +69,7 @@ handleLoad silent loadMode maybePath = do Cli.LoadSuccess contents -> pure contents case loadMode of Normal -> loadUnisonFile (Text.pack path) contents - LoadForCommit -> loadUnisonFileForCommit silent (Text.pack path) contents + LoadForCommit -> loadUnisonFileForCommit showWatchExprs (Text.pack path) contents loadUnisonFile :: Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) loadUnisonFile sourceName text = do @@ -90,8 +90,8 @@ loadUnisonFile sourceName text = do pure unisonFile loadUnisonFileForCommit :: Bool -> Text -> Text -> Cli (TypecheckedUnisonFile Symbol Ann) -loadUnisonFileForCommit silent sourceName text = do - when (not silent) . Cli.respond $ Output.LoadingFile sourceName +loadUnisonFileForCommit showWatchExprs sourceName text = do + Cli.respond $ Output.LoadingFile sourceName beforeBranch0 <- Cli.getCurrentBranch0 let beforeBranch0LibOnly = Branch.onlyLib beforeBranch0 beforePPED <- Cli.currentPrettyPrintEnvDecl @@ -100,13 +100,13 @@ loadUnisonFileForCommit silent sourceName text = do let sr = Slurp.slurpFile unisonFile mempty Slurp.CheckOp libNames let adds = SlurpResult.adds sr let afterBranch0 = Update.doSlurpAdds adds unisonFile beforeBranch0LibOnly - afterPPED <- Cli.currentPrettyPrintEnvDecl + afterPPED <- Cli.prettyPrintEnvDeclFromNames (Branch.toNames afterBranch0) (_ppe, diff) <- diffFromTypecheckedUnisonFile unisonFile beforeBranch0 afterBranch0 let pped = afterPPED `PPED.addFallback` beforePPED let ppe = PPE.suffixifiedPPE pped currentPath <- Cli.getCurrentPath Cli.respondNumbered $ Output.ShowDiffNamespace (Right currentPath) (Right currentPath) ppe diff - when (not silent) do + when showWatchExprs do (bindings, e) <- evalUnisonFile Permissive ppe unisonFile [] let e' = Map.map go e go (ann, kind, _hash, _uneval, eval, isHit) = (ann, kind, eval, isHit) diff --git a/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs b/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs index 32d8703162..5d0a7f506b 100644 --- a/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs +++ b/unison-cli/src/Unison/Codebase/Editor/HandleInput/NamespaceDiffUtils.hs @@ -32,6 +32,7 @@ import Unison.Type (Type) import Unison.Typechecker.TypeLookup qualified as TL import Unison.UnisonFile (TypecheckedUnisonFile) import Unison.UnisonFile qualified as UF +import Unison.UnisonFile.Names qualified as Names diffHelper :: Branch0 IO -> @@ -69,13 +70,15 @@ diffFromTypecheckedUnisonFile tf before after = do names <- Cli.currentNames pped <- Cli.prettyPrintEnvDeclFromNames names let suffixifiedPPE = PPED.suffixifiedPPE pped + let beforeNames = Branch.toNames before + let afterNames = Names.addNamesFromTypeCheckedUnisonFile tf (Branch.toNames after) fmap (suffixifiedPPE,) do OBranchDiff.toOutput (getTypeOfReferent codebase) (getDeclOrBuiltin codebase) hqLength - (Branch.toNames before) - (Branch.toNames after) + beforeNames + afterNames diff where TL.TypeLookup {dataDecls, effectDecls} = UF.typeLookupForTypecheckedFile tf diff --git a/unison-cli/src/Unison/Codebase/Editor/Output.hs b/unison-cli/src/Unison/Codebase/Editor/Output.hs index 24f3ae0448..06830bc435 100644 --- a/unison-cli/src/Unison/Codebase/Editor/Output.hs +++ b/unison-cli/src/Unison/Codebase/Editor/Output.hs @@ -31,7 +31,6 @@ import Unison.Cli.MergeTypes (MergeSourceAndTarget, MergeSourceOrTarget) import Unison.Cli.Share.Projects.Types qualified as Share import Unison.Codebase.Editor.Input import Unison.Codebase.Editor.Output.BranchDiff (BranchDiffOutput) -import Unison.Codebase.Editor.Output.BranchDiff qualified as BD import Unison.Codebase.Editor.Output.PushPull (PushPull) import Unison.Codebase.Editor.RemoteRepo import Unison.Codebase.Editor.SlurpResult (SlurpResult (..)) @@ -661,6 +660,6 @@ isNumberedFailure = \case ShowDiffAfterModifyBranch {} -> False ShowDiffAfterPull {} -> False ShowDiffAfterUndo {} -> False - ShowDiffNamespace _ _ _ bd -> BD.isEmpty bd + ShowDiffNamespace _ _ _ _ -> False ListNamespaceDependencies {} -> False TodoOutput _ todo -> TO.todoScore todo > 0 || not (TO.noConflicts todo) diff --git a/unison-cli/src/Unison/CommandLine/InputPatterns.hs b/unison-cli/src/Unison/CommandLine/InputPatterns.hs index 7238d13466..42c2db9f5f 100644 --- a/unison-cli/src/Unison/CommandLine/InputPatterns.hs +++ b/unison-cli/src/Unison/CommandLine/InputPatterns.hs @@ -815,7 +815,7 @@ commit = ) \case [] -> pure $ Input.CommitI Nothing - [file] -> Input.LoadI . Just <$> unsupportedStructuredArgument "a file name" file + [file] -> Input.CommitI . Just <$> unsupportedStructuredArgument "a file name" file _ -> Left (I.help load) commitPreview :: InputPattern @@ -828,8 +828,8 @@ commitPreview = ( "`experimental.commit.preview` shows the diff which would be applied if you were to run " <> patternName commit ) \case - [] -> pure $ Input.CommitI Nothing - [file] -> Input.LoadI . Just <$> unsupportedStructuredArgument "a file name" file + [] -> pure $ Input.CommitPreviewI Nothing + [file] -> Input.CommitPreviewI . Just <$> unsupportedStructuredArgument "a file name" file _ -> Left (I.help load) update :: InputPattern @@ -3190,6 +3190,7 @@ validInputs = clone, compileScheme, commit, + commitPreview, createAuthor, debugClearWatchCache, debugDoctor, diff --git a/unison-src/transcripts/commit-command.md b/unison-src/transcripts/commit-command.md index 14f9f7995c..02008ed04b 100644 --- a/unison-src/transcripts/commit-command.md +++ b/unison-src/transcripts/commit-command.md @@ -1,10 +1,10 @@ ```ucm:hide -.> builtins.merge +.> builtins.merge lib ``` Add some definitions to the codebase for us to later update. -```unison +```unison:hide type MyRecord = { nat : Nat , text : Text @@ -21,7 +21,7 @@ addToRecordField rec = nat rec + 10 > addToRecordField (MyRecord 9 "hi" true) ``` -```ucm +```ucm:hide .> add ``` diff --git a/unison-src/transcripts/commit-command.output.md b/unison-src/transcripts/commit-command.output.md index 50808bbff7..d02ce1de3c 100644 --- a/unison-src/transcripts/commit-command.output.md +++ b/unison-src/transcripts/commit-command.output.md @@ -1,7 +1,7 @@ Add some definitions to the codebase for us to later update. ```unison -type MyRecord = +type MyRecord = { nat : Nat , text : Text , bool : Boolean @@ -17,78 +17,12 @@ addToRecordField rec = nat rec + 10 > addToRecordField (MyRecord 9 "hi" true) ``` -```ucm - - Loading changes detected in scratch.u. - - I found and typechecked these definitions in scratch.u. If you - do an `add` or `update`, here's how your codebase would - change: - - ⍟ These new definitions are ok to `add`: - - type MyRecord - MyRecord.bool : MyRecord -> Boolean - MyRecord.bool.modify : (Boolean ->{g} Boolean) - -> MyRecord - ->{g} MyRecord - MyRecord.bool.set : Boolean -> MyRecord -> MyRecord - MyRecord.nat : MyRecord -> Nat - MyRecord.nat.modify : (Nat ->{g} Nat) - -> MyRecord - ->{g} MyRecord - MyRecord.nat.set : Nat -> MyRecord -> MyRecord - MyRecord.text : MyRecord -> Text - MyRecord.text.modify : (Text ->{g} Text) - -> MyRecord - ->{g} MyRecord - MyRecord.text.set : Text -> MyRecord -> MyRecord - addToRecordField : MyRecord -> Nat - lib.dep.dependency : Nat - termOne : Nat - termTwo : Nat - - Now evaluating any watch expressions (lines starting with - `>`)... Ctrl+C cancels. - - 14 | > addToRecordField (MyRecord 9 "hi" true) - ⧩ - 19 - -``` -```ucm -.> add - - ⍟ I've added these definitions: - - type MyRecord - MyRecord.bool : MyRecord -> Boolean - MyRecord.bool.modify : (Boolean ->{g} Boolean) - -> MyRecord - ->{g} MyRecord - MyRecord.bool.set : Boolean -> MyRecord -> MyRecord - MyRecord.nat : MyRecord -> Nat - MyRecord.nat.modify : (Nat ->{g} Nat) - -> MyRecord - ->{g} MyRecord - MyRecord.nat.set : Nat -> MyRecord -> MyRecord - MyRecord.text : MyRecord -> Text - MyRecord.text.modify : (Text ->{g} Text) - -> MyRecord - ->{g} MyRecord - MyRecord.text.set : Text -> MyRecord -> MyRecord - addToRecordField : MyRecord -> Nat - lib.dep.dependency : Nat - termOne : Nat - termTwo : Nat - -``` Should be able to easily change and remove record fields and definitions in a single commit. ```unison -- Rename and re-type the `nat` field to `getNat` --- Remove the `bool` field -type MyRecord = +-- Remove the `bool` field +type MyRecord = { getNat : () -> Nat , text : Text } @@ -141,67 +75,179 @@ addToRecordField rec = !(getNat rec) + 10 ``` ```ucm +.> experimental.commit.preview + + Loading changes detected in scratch.u. + + Updates: + + 1. type MyRecord + ↓ + 2. type MyRecord + + 3. addToRecordField : MyRecord -> Nat + ↓ + 4. addToRecordField : MyRecord -> Nat + + 5. MyRecord.MyRecord : Nat -> Text -> Boolean -> MyRecord + ↓ + 6. MyRecord.MyRecord : 'Nat -> Text -> MyRecord + + 7. MyRecord.text : MyRecord -> Text + ↓ + 8. MyRecord.text : MyRecord -> Text + + 9. MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + ↓ + 10. MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + + 11. MyRecord.text.set : Text -> MyRecord -> MyRecord + ↓ + 12. MyRecord.text.set : Text -> MyRecord -> MyRecord + + 13. termOne : Nat + ↓ + 14. termOne : Nat + + Added definitions: + + 15. MyRecord.getNat : MyRecord -> 'Nat + 16. MyRecord.getNat.modify : ('Nat ->{g} 'Nat) + -> MyRecord + ->{g} MyRecord + 17. MyRecord.getNat.set : 'Nat -> MyRecord -> MyRecord + + Removed definitions: + + 18. MyRecord.bool : MyRecord -> Boolean + 19. MyRecord.bool.modify : (Boolean ->{g} Boolean) + -> MyRecord + ->{g} MyRecord + 20. MyRecord.nat.modify : (Nat ->{g} Nat) + -> MyRecord + ->{g} MyRecord + 21. MyRecord.nat : MyRecord -> Nat + 22. MyRecord.bool.set : Boolean -> MyRecord -> MyRecord + 23. MyRecord.nat.set : Nat -> MyRecord -> MyRecord + 24. termTwo : Nat + .> experimental.commit - x These definitions would fail on `add` or `update`: + Loading changes detected in scratch.u. + + Updates: + + 1. type MyRecord + ↓ + 2. type MyRecord + + 3. addToRecordField : MyRecord -> Nat + ↓ + 4. addToRecordField : MyRecord -> Nat + + 5. MyRecord.MyRecord : Nat -> Text -> Boolean -> MyRecord + ↓ + 6. MyRecord.MyRecord : 'Nat -> Text -> MyRecord + + 7. MyRecord.text : MyRecord -> Text + ↓ + 8. MyRecord.text : MyRecord -> Text + + 9. MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + ↓ + 10. MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + + 11. MyRecord.text.set : Text -> MyRecord -> MyRecord + ↓ + 12. MyRecord.text.set : Text -> MyRecord -> MyRecord + + 13. termOne : Nat + ↓ + 14. termOne : Nat + + Added definitions: + + 15. MyRecord.getNat : MyRecord -> 'Nat + 16. MyRecord.getNat.modify : ('Nat ->{g} 'Nat) + -> MyRecord + ->{g} MyRecord + 17. MyRecord.getNat.set : 'Nat -> MyRecord -> MyRecord - Reason - needs update type MyRecord - needs update addToRecordField : MyRecord -> ##Nat - needs update termOne : ##Nat - blocked MyRecord.getNat : MyRecord -> '##Nat - blocked MyRecord.getNat.modify : ('##Nat - ->{g} '##Nat) - -> MyRecord - ->{g} MyRecord - blocked MyRecord.getNat.set : '##Nat - -> MyRecord - -> MyRecord - blocked MyRecord.text : MyRecord -> ##Text - blocked MyRecord.text.modify : (##Text - ->{g} ##Text) - -> MyRecord - ->{g} MyRecord - blocked MyRecord.text.set : ##Text - -> MyRecord - -> MyRecord + Removed definitions: - Tip: Use `help filestatus` to learn more. + 18. MyRecord.bool : MyRecord -> Boolean + 19. MyRecord.bool.modify : (Boolean ->{g} Boolean) + -> MyRecord + ->{g} MyRecord + 20. MyRecord.nat.modify : (Nat ->{g} Nat) + -> MyRecord + ->{g} MyRecord + 21. MyRecord.nat : MyRecord -> Nat + 22. MyRecord.bool.set : Boolean -> MyRecord -> MyRecord + 23. MyRecord.nat.set : Nat -> MyRecord -> MyRecord + 24. termTwo : Nat -``` +.> find -```ucm -.> experimental.commit.> find.> view MyRecord.> ls MyRecord.> view addToRecordField.> view termOne -``` + 1. addToRecordField : MyRecord -> Nat + 2. type MyRecord + 3. MyRecord.getNat : MyRecord -> 'Nat + 4. MyRecord.getNat.modify : ('Nat ->{g} 'Nat) + -> MyRecord + ->{g} MyRecord + 5. MyRecord.getNat.set : 'Nat -> MyRecord -> MyRecord + 6. MyRecord.MyRecord : 'Nat -> Text -> MyRecord + 7. MyRecord.text : MyRecord -> Text + 8. MyRecord.text.modify : (Text ->{g} Text) + -> MyRecord + ->{g} MyRecord + 9. MyRecord.text.set : Text -> MyRecord -> MyRecord + 10. termOne : Nat + +.> view MyRecord -🛑 + type MyRecord = { getNat : 'Nat, text : Text } -The transcript failed due to an error in the stanza above. The error is: +.> ls MyRecord + 1. MyRecord ('Nat -> Text -> MyRecord) + 2. getNat (MyRecord -> 'Nat) + 3. getNat/ (2 terms) + 4. text (MyRecord -> Text) + 5. text/ (2 terms) - x These definitions would fail on `add` or `update`: - - Reason - needs update type MyRecord - needs update addToRecordField : MyRecord -> ##Nat - needs update termOne : ##Nat - blocked MyRecord.getNat : MyRecord -> '##Nat - blocked MyRecord.getNat.modify : ('##Nat - ->{g} '##Nat) - -> MyRecord - ->{g} MyRecord - blocked MyRecord.getNat.set : '##Nat - -> MyRecord - -> MyRecord - blocked MyRecord.text : MyRecord -> ##Text - blocked MyRecord.text.modify : (##Text - ->{g} ##Text) - -> MyRecord - ->{g} MyRecord - blocked MyRecord.text.set : ##Text - -> MyRecord - -> MyRecord +.> view addToRecordField + + addToRecordField : MyRecord -> Nat + addToRecordField rec = + use Nat + + getNat rec () + 10 + +.> view termOne + + termOne : Nat + termOne = + use Nat + + dependency + 20 + +``` +This term should be deleted. + +```ucm +.> view termTwo + + ⚠️ - Tip: Use `help filestatus` to learn more. + The following names were not found in the codebase. Check your spelling. + termTwo +``` From f914250e8d58877d11f8216169d5a9f9349ef204 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Fri, 31 May 2024 15:07:20 -0700 Subject: [PATCH 11/11] Adjust transcripts to non-erroring diff.namespace --- unison-src/transcripts-round-trip/main.md | 2 +- unison-src/transcripts/diff-namespace.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unison-src/transcripts-round-trip/main.md b/unison-src/transcripts-round-trip/main.md index 7287a7ddba..bfa66f363e 100644 --- a/unison-src/transcripts-round-trip/main.md +++ b/unison-src/transcripts-round-trip/main.md @@ -40,7 +40,7 @@ So we can see the pretty-printed output: This diff should be empty if the two namespaces are equivalent. If it's nonempty, the diff will show us the hashes that differ. -```ucm:error +```ucm .> diff.namespace a1 a2 ``` diff --git a/unison-src/transcripts/diff-namespace.md b/unison-src/transcripts/diff-namespace.md index 5e938a79a5..1ebea24745 100644 --- a/unison-src/transcripts/diff-namespace.md +++ b/unison-src/transcripts/diff-namespace.md @@ -56,7 +56,7 @@ Here's what we've done so far: .> diff.namespace nothing ns1 ``` -```ucm:error +```ucm .> diff.namespace ns1 ns2 ```