2module TutorialD.Interpreter.TransactionGraphOperator where
3import TutorialD.Interpreter.Base
5import Text.Parsec.String
7import qualified Data.UUID as U
8import qualified Data.Text as T
10import ProjectM36.Transaction
11import ProjectM36.Transaction.Show
12import ProjectM36.Relation.Show.Term
14--operators which manipulate a transaction graph
15data TransactionGraphOperator where
16 JumpToHead :: HeadName -> TransactionGraphOperator
17 JumpToTransaction :: U.UUID -> TransactionGraphOperator
18 Branch :: HeadName -> TransactionGraphOperator
19 Commit :: TransactionGraphOperator
20 Rollback :: TransactionGraphOperator
21 ShowGraph :: TransactionGraphOperator
23jumpToHeadP :: Parser TransactionGraphOperator
25 reservedOp ":jumphead"
27 return $ JumpToHead (T.pack headid)
29jumpToTransactionP :: Parser TransactionGraphOperator
30jumpToTransactionP = do
33 return $ JumpToTransaction uuid
35branchTransactionP :: Parser TransactionGraphOperator
36branchTransactionP = do
38 branchName <- identifier
39 return $ Branch (T.pack branchName)
41commitTransactionP :: Parser TransactionGraphOperator
42commitTransactionP = do
46rollbackTransactionP :: Parser TransactionGraphOperator
47rollbackTransactionP = do
48 reservedOp ":rollback"
51showGraphP :: Parser TransactionGraphOperator
53 reservedOp ":showgraph"
56transactionGraphOpP :: Parser TransactionGraphOperator
57transactionGraphOpP = do
59 <|> jumpToTransactionP
60 <|> branchTransactionP
61 <|> commitTransactionP
62 <|> rollbackTransactionP
67 uuidStr <- many (alphaNum <|> char '-')
68 case U.fromString uuidStr of
69 Nothing -> fail "Invalid uuid string"
70 Just uuid -> return uuid
72-- returns the new "current" transaction, updated graph, and tutorial d result
73-- the current transaction is not part of the transaction graph until it is committed
74evalGraphOp :: U.UUID -> DisconnectedTransaction -> TransactionGraph -> TransactionGraphOperator -> Either RelationalError (DisconnectedTransaction, TransactionGraph, TutorialDOperatorResult)
76--affects only disconncted transaction
77evalGraphOp _ _ graph (JumpToTransaction jumpUUID) = case transactionForUUID jumpUUID graph of
79 Right parentTrans -> Right (newTrans, graph, QuietSuccessResult)
81 newTrans = DisconnectedTransaction jumpUUID (transactionContext parentTrans)
83-- switch from one head to another
84-- affects only disconnectedtransaction
85evalGraphOp _ _ graph (JumpToHead headName) =
86 case transactionForHead headName graph of
87 Just newHeadTransaction -> let disconnectedTrans = newDisconnectedTransaction (transactionUUID newHeadTransaction) (transactionContext newHeadTransaction) in
88 Right (disconnectedTrans, graph, QuietSuccessResult)
89 Nothing -> Left $ NoSuchHeadNameError headName
90-- add new head pointing to branchPoint
91-- repoint the disconnected transaction to the new branch commit (with a potentially different disconnected context)
92-- affects transactiongraph and the disconnectedtransaction is recreated based off the branch
94evalGraphOp newUUID discon@(DisconnectedTransaction parentUUID disconContext) graph (Branch newBranchName) = case transactionForUUID parentUUID graph of
95 Nothing -> (discon, graph, DisplayErrorResult "Failed to find parent transaction.")
96 Just parentTrans -> case addBranch newBranchName parentTrans graph of
97 Nothing -> (discon, graph, DisplayErrorResult "Failed to add branch.")
98 Just newGraph -> (newDiscon, newGraph, DisplayResult "Branched.")
100 newDiscon = DisconnectedTransaction (transactionUUID parentTrans) disconContext
103-- create a new commit and add it to the heads
104-- technically, the new head could be added to an existing commit, but by adding a new commit, the new head is unambiguously linked to a new commit (with a context indentical to its parent)
105evalGraphOp newUUID (DisconnectedTransaction parentUUID disconContext) graph (Branch newBranchName) = case transactionForUUID parentUUID graph of
107 Right parentTrans -> case addBranch newUUID newBranchName parentTrans graph of
109 Right (_, newGraph) -> Right (newDiscon, newGraph, QuietSuccessResult)
111 newDiscon = DisconnectedTransaction newUUID disconContext
113-- add the disconnected transaction to the graph
114-- affects graph and disconnectedtransaction- the new disconnectedtransaction's parent is the freshly committed transaction
115evalGraphOp newTransUUID discon@(DisconnectedTransaction parentUUID context) graph Commit = case transactionForUUID parentUUID graph of
117 Right parentTransaction -> case headNameForTransaction parentTransaction graph of
118 Nothing -> Left $ TransactionIsNotAHeadError parentUUID
119 Just headName -> case maybeUpdatedGraph of
121 Right (_, updatedGraph) -> Right (newDisconnectedTrans, updatedGraph, QuietSuccessResult)
123 newDisconnectedTrans = newDisconnectedTransaction newTransUUID context
124 maybeUpdatedGraph = addDisconnectedTransaction newTransUUID headName discon graph
126-- refresh the disconnected transaction, return the same graph
127evalGraphOp _ (DisconnectedTransaction parentUUID _) graph Rollback = case transactionForUUID parentUUID graph of
129 Right parentTransaction -> Right (newDiscon, graph, QuietSuccessResult)
131 newDiscon = newDisconnectedTransaction parentUUID (transactionContext parentTransaction)
133--display transaction graph as relation
134evalGraphOp _ discon graph ShowGraph = do
135 graphStr <- graphAsRelation discon graph
136 return (discon, graph, DisplayResult $ showRelation graphStr)
139-- for interpreter-specific operations
140interpretOps :: U.UUID -> DisconnectedTransaction -> TransactionGraph -> String -> (DisconnectedTransaction, TransactionGraph, TutorialDOperatorResult)
141interpretOps newUUID trans@(DisconnectedTransaction _ context) transGraph instring = case parse interpreterOps "" instring of
142 Left _ -> (trans, transGraph, NoActionResult)
143 Right ops -> case ops of
144 Left contextOp -> (trans, transGraph, (evalContextOp context contextOp))
145 Right graphOp -> case evalGraphOp newUUID trans transGraph graphOp of
146 Left err -> (trans, transGraph, DisplayErrorResult $ T.pack (show err))
147 Right (newDiscon, newGraph, result) -> (newDiscon, newGraph, result)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list