1
1
package main
2
2
3
3
import (
4
+ "encoding/csv"
4
5
"encoding/json"
5
6
"fmt"
6
7
"os"
@@ -11,7 +12,6 @@ import (
11
12
"github.com/spf13/cobra"
12
13
13
14
"cosmossdk.io/tools/cosmovisor"
14
- upgradetypes "cosmossdk.io/x/upgrade/types"
15
15
)
16
16
17
17
func NewBatchAddUpgradeCmd () * cobra.Command {
@@ -21,8 +21,8 @@ func NewBatchAddUpgradeCmd() *cobra.Command {
21
21
Long : `This command allows you to specify multiple upgrades at once at specific heights, copying or creating a batch upgrade file that's actively watched during 'cosmovisor run'.
22
22
You can provide upgrades in two ways:
23
23
24
- 1. Using --upgrade-file: Specify a path to a batch upgrade file ie. a JSON array of upgrade-info objects.
25
- The file is validated before it's copied over to the upgrade directory.
24
+ 1. Using --upgrade-file: Specify a path to a headerless CSV batch upgrade file in the format:
25
+ upgrade-name,path-to-exec, upgrade-height
26
26
27
27
2. Using --upgrade-list: Provide a comma-separated list of upgrades.
28
28
Each upgrade is defined by three colon-separated values:
@@ -55,35 +55,31 @@ func addBatchUpgrade(cmd *cobra.Command, args []string) error {
55
55
}
56
56
upgradeFile , err := cmd .Flags ().GetString ("upgrade-file" )
57
57
if err == nil && upgradeFile != "" {
58
- info , err := os .Stat (upgradeFile )
59
- if err != nil {
60
- return fmt .Errorf ("error getting reading upgrade file %s: %w" , upgradeFile , err )
61
- }
62
- if info .IsDir () {
63
- return fmt .Errorf ("upgrade file %s is a directory" , upgradeFile )
64
- }
65
58
return processUpgradeFile (cfg , upgradeFile )
66
59
}
67
60
upgradeList , err := cmd .Flags ().GetStringSlice ("upgrade-list" )
68
61
if err != nil || len (upgradeList ) == 0 {
69
62
return fmt .Errorf ("either --upgrade-file or --upgrade-list must be provided" )
70
63
}
71
- return processUpgradeList (cfg , upgradeList )
64
+ var splitUpgrades [][]string
65
+ for _ , upgrade := range upgradeList {
66
+ splitUpgrades = append (splitUpgrades , strings .Split (upgrade , ":" ))
67
+ }
68
+ return processUpgradeList (cfg , splitUpgrades )
72
69
}
73
70
74
71
// processUpgradeList takes in a list of upgrades and creates a batch upgrade file
75
- func processUpgradeList (cfg * cosmovisor.Config , upgradeList []string ) error {
72
+ func processUpgradeList (cfg * cosmovisor.Config , upgradeList [][] string ) error {
76
73
upgradeInfoPaths := []string {}
77
- for i , as := range upgradeList {
78
- a := strings .Split (as , ":" )
79
- if len (a ) != 3 {
80
- return fmt .Errorf ("argument at position %d (%s) is invalid" , i , as )
74
+ for i , upgrade := range upgradeList {
75
+ if len (upgrade ) != 3 {
76
+ return fmt .Errorf ("argument at position %d (%s) is invalid" , i , upgrade )
81
77
}
82
- upgradeName := filepath .Base (a [0 ])
83
- upgradePath := a [1 ]
84
- upgradeHeight , err := strconv .ParseInt (a [2 ], 10 , 64 )
78
+ upgradeName := filepath .Base (upgrade [0 ])
79
+ upgradePath := upgrade [1 ]
80
+ upgradeHeight , err := strconv .ParseInt (upgrade [2 ], 10 , 64 )
85
81
if err != nil {
86
- return fmt .Errorf ("upgrade height at position %d (%s) is invalid" , i , a [2 ])
82
+ return fmt .Errorf ("upgrade height at position %d (%s) is invalid" , i , upgrade [2 ])
87
83
}
88
84
upgradeInfoPath := cfg .UpgradeInfoFilePath () + "." + upgradeName
89
85
upgradeInfoPaths = append (upgradeInfoPaths , upgradeInfoPath )
@@ -124,15 +120,23 @@ func processUpgradeList(cfg *cosmovisor.Config, upgradeList []string) error {
124
120
return nil
125
121
}
126
122
127
- // processUpgradeFile takes in a batch upgrade file, validates it and copies it to the upgrade directory
123
+ // processUpgradeFile takes in a CSV batch upgrade file, parses it and calls processUpgradeList
128
124
func processUpgradeFile (cfg * cosmovisor.Config , upgradeFile string ) error {
129
- b , err := os .ReadFile (upgradeFile )
125
+ file , err := os .Open (upgradeFile )
130
126
if err != nil {
131
- return fmt .Errorf ("error reading upgrade file %s: %w" , upgradeFile , err )
127
+ return fmt .Errorf ("error opening upgrade CSV file %s: %w" , upgradeFile , err )
132
128
}
133
- var batch []upgradetypes.Plan
134
- if err := json .Unmarshal (b , & batch ); err != nil {
135
- return fmt .Errorf ("error unmarshalling upgrade file %s: %w" , upgradeFile , err )
129
+ defer file .Close ()
130
+
131
+ r := csv .NewReader (file )
132
+ r .FieldsPerRecord = 3
133
+ r .TrimLeadingSpace = true
134
+ records , err := r .ReadAll ()
135
+ if err != nil {
136
+ return fmt .Errorf ("error parsing upgrade CSV file %s: %w" , upgradeFile , err )
137
+ }
138
+ if err := processUpgradeList (cfg , records ); err != nil {
139
+ return err
136
140
}
137
- return copyFile ( upgradeFile , cfg . UpgradeInfoBatchFilePath ())
141
+ return nil
138
142
}
0 commit comments