@@ -16,9 +16,12 @@ limitations under the License.
1616package cmd
1717
1818import (
19+ "bytes"
20+ "context"
21+ "encoding/json"
1922 "fmt"
2023 "os"
21- "path"
24+ "path/filepath "
2225
2326 "github.com/marstr/baronial/internal/index"
2427 "github.com/marstr/envelopes"
@@ -28,6 +31,11 @@ import (
2831 "github.com/spf13/cobra"
2932)
3033
34+ type RevertParameters struct {
35+ Comment string `json:"comment,omitempty"`
36+ Reverts []envelopes.ID `json:"reverts"`
37+ }
38+
3139// revertCmd represents the revert command
3240var revertCmd = & cobra.Command {
3341 Use : "revert {ref-spec}" ,
@@ -40,6 +48,7 @@ It is not advised to revert a revert. Even if this tool handles it well, it
4048complicates all future tools and many may not do a good job. If you
4149accidentally reverted a transaction, just commit a new transaction that is
4250identical to the original.` ,
51+ Args : cobra .ExactArgs (1 ),
4352 Run : func (cmd * cobra.Command , args []string ) {
4453 ctx , cancel := RootContext (cmd )
4554 defer cancel ()
@@ -49,8 +58,9 @@ identical to the original.`,
4958 logrus .Fatal (err )
5059 }
5160
61+ repoLoc := filepath .Join (root , index .RepoName )
5262 var repo persist.RepositoryReaderWriter
53- repo , err = filesystem .OpenRepositoryWithCache (ctx , path . Join ( root , index . RepoName ) , 10000 )
63+ repo , err = filesystem .OpenRepositoryWithCache (ctx , repoLoc , 10000 )
5464 if err != nil {
5565 logrus .Fatal (err )
5666 }
@@ -91,10 +101,90 @@ identical to the original.`,
91101 logrus .Fatal (err )
92102 }
93103
104+ var inProg bool
105+ inProg , err = RevertIsInProgress (ctx , repoLoc )
106+ if err != nil {
107+ logrus .Warn ("couldn't see if previous revert was in progress because: " , err )
108+ }
109+
110+ var revertParams RevertParameters
111+
112+ if inProg {
113+ err = RevertUnstowProgress (ctx , repoLoc , & revertParams )
114+ if err != nil {
115+ logrus .Fatal ("couldn't read the currently in-progress revert because: " , err )
116+ }
117+ }
118+
119+ revertParams .Reverts = append (revertParams .Reverts , id )
120+ revertParams .Comment = getRevertComment (revertParams .Reverts )
121+
122+ err = RevertStowProgress (ctx , repoLoc , revertParams )
123+ if err != nil {
124+ fmt .Fprintln (os .Stderr , "Unable to stow revert information. Please reset to the last known good state." )
125+ logrus .Fatal (err )
126+ }
127+
94128 fmt .Printf ("Undid the effects of transaction %s. Please check current balances for accuracy, make any necessary edits, then commit." , id )
95129 },
96130}
97131
132+ func RevertIsInProgress (_ context.Context , repoLoc string ) (bool , error ) {
133+ _ , err := os .Stat (getRevertParamsLoc (repoLoc ))
134+ if err == nil {
135+ return true , nil
136+ } else if os .IsNotExist (err ) {
137+ return false , nil
138+ } else {
139+ return false , err
140+ }
141+ }
142+
143+ func RevertStowProgress (_ context.Context , repoLoc string , parameters RevertParameters ) error {
144+ const filePermissions = 0660 // owner and group can read and write. The file is not executable. Other users cannot read it.
145+ toWrite , err := json .Marshal (parameters )
146+ if err != nil {
147+ return err
148+ }
149+
150+ return os .WriteFile (getRevertParamsLoc (repoLoc ), toWrite , filePermissions )
151+ }
152+
153+ func RevertUnstowProgress (_ context.Context , repoLoc string , destination * RevertParameters ) error {
154+ contents , err := os .ReadFile (getRevertParamsLoc (repoLoc ))
155+ if err != nil {
156+ return err
157+ }
158+
159+ return json .Unmarshal (contents , destination )
160+ }
161+
162+ func RevertResetProgress (_ context.Context , repoLoc string ) error {
163+ return os .Remove (getRevertParamsLoc (repoLoc ))
164+ }
165+
166+ func getRevertParamsLoc (repoLoc string ) string {
167+ return filepath .Join (repoLoc , "revert.json" )
168+ }
169+
170+ func getRevertComment (reverts []envelopes.ID ) string {
171+ var buf bytes.Buffer
172+
173+ fmt .Fprint (& buf , "Reverts " )
174+
175+ seenAny := false
176+ for _ , id := range reverts {
177+ seenAny = true
178+ fmt .Fprintf (& buf , "%s, " , id )
179+ }
180+
181+ if seenAny {
182+ buf .Truncate (buf .Len () - 2 )
183+ }
184+
185+ return buf .String ()
186+ }
187+
98188func init () {
99189 rootCmd .AddCommand (revertCmd )
100190
0 commit comments