Skip to content

Commit bceefc4

Browse files
committed
commit
1 parent b4ec39d commit bceefc4

File tree

15 files changed

+105
-270
lines changed

15 files changed

+105
-270
lines changed

cmd/ibctl/internal/command/config/configedit/configedit.go

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,33 @@ import (
1717
"github.com/bufdev/ibctl/cmd/ibctl/internal/ibctlcmd"
1818
"github.com/bufdev/ibctl/internal/ibctl/ibctlconfig"
1919
"github.com/bufdev/ibctl/internal/ibctl/ibctlpath"
20-
"github.com/spf13/pflag"
2120
)
2221

2322
// NewCommand returns a new config edit command that opens the configuration file in an editor.
2423
func NewCommand(name string, builder appext.SubCommandBuilder) *appcmd.Command {
25-
flags := newFlags()
2624
return &appcmd.Command{
2725
Use: name,
2826
Short: "Edit the configuration file in $EDITOR",
2927
Args: appcmd.NoArgs,
3028
Run: builder.NewRunFunc(
3129
func(ctx context.Context, container appext.Container) error {
32-
return run(ctx, container, flags)
30+
return run(ctx, container)
3331
},
3432
),
35-
BindFlags: flags.Bind,
3633
}
3734
}
3835

39-
type flags struct {
40-
// Dir is the ibctl directory containing ibctl.yaml.
41-
Dir string
42-
}
43-
44-
func newFlags() *flags {
45-
return &flags{}
46-
}
47-
48-
// Bind registers the flag definitions with the given flag set.
49-
func (f *flags) Bind(flagSet *pflag.FlagSet) {
50-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
51-
}
52-
53-
func run(ctx context.Context, container appext.Container, flags *flags) error {
36+
func run(ctx context.Context, container appext.Container) error {
37+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
38+
dirPath, err := ibctlcmd.DirPath(container)
39+
if err != nil {
40+
return err
41+
}
5442
// Resolve the config file path from the base directory.
55-
configFilePath := ibctlpath.ConfigFilePath(flags.Dir)
43+
configFilePath := ibctlpath.ConfigFilePath(dirPath)
5644
// Create the configuration file with the default template if it does not exist.
5745
if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
58-
if err := ibctlconfig.InitConfig(flags.Dir); err != nil {
46+
if err := ibctlconfig.InitConfig(dirPath); err != nil {
5947
return err
6048
}
6149
}
@@ -73,6 +61,6 @@ func run(ctx context.Context, container appext.Container, flags *flags) error {
7361
return fmt.Errorf("running editor: %w", err)
7462
}
7563
// Print the path of the edited file.
76-
_, err := fmt.Fprintf(container.Stdout(), "%s\n", configFilePath)
64+
_, err = fmt.Fprintf(container.Stdout(), "%s\n", configFilePath)
7765
return err
7866
}

cmd/ibctl/internal/command/config/configinit/configinit.go

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,45 +13,33 @@ import (
1313
"buf.build/go/app/appext"
1414
"github.com/bufdev/ibctl/cmd/ibctl/internal/ibctlcmd"
1515
"github.com/bufdev/ibctl/internal/ibctl/ibctlconfig"
16-
"github.com/spf13/pflag"
1716
)
1817

1918
// NewCommand returns a new config init command that creates a default configuration file.
2019
func NewCommand(name string, builder appext.SubCommandBuilder) *appcmd.Command {
21-
flags := newFlags()
2220
return &appcmd.Command{
2321
Use: name,
2422
Short: "Create a new configuration file",
2523
Args: appcmd.NoArgs,
2624
Run: builder.NewRunFunc(
2725
func(ctx context.Context, container appext.Container) error {
28-
return run(ctx, container, flags)
26+
return run(ctx, container)
2927
},
3028
),
31-
BindFlags: flags.Bind,
3229
}
3330
}
3431

35-
type flags struct {
36-
// Dir is the ibctl directory containing ibctl.yaml.
37-
Dir string
38-
}
39-
40-
func newFlags() *flags {
41-
return &flags{}
42-
}
43-
44-
// Bind registers the flag definitions with the given flag set.
45-
func (f *flags) Bind(flagSet *pflag.FlagSet) {
46-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
47-
}
48-
49-
func run(_ context.Context, container appext.Container, flags *flags) error {
32+
func run(_ context.Context, container appext.Container) error {
33+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
34+
dirPath, err := ibctlcmd.DirPath(container)
35+
if err != nil {
36+
return err
37+
}
5038
// Create the configuration file in the specified directory.
51-
if err := ibctlconfig.InitConfig(flags.Dir); err != nil {
39+
if err := ibctlconfig.InitConfig(dirPath); err != nil {
5240
return err
5341
}
5442
// Print the directory path so the user knows where to find it.
55-
_, err := fmt.Fprintf(container.Stdout(), "%s\n", flags.Dir)
43+
_, err = fmt.Fprintf(container.Stdout(), "%s\n", dirPath)
5644
return err
5745
}

cmd/ibctl/internal/command/config/configvalidate/configvalidate.go

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,27 @@ import (
1212
"buf.build/go/app/appext"
1313
"github.com/bufdev/ibctl/cmd/ibctl/internal/ibctlcmd"
1414
"github.com/bufdev/ibctl/internal/ibctl/ibctlconfig"
15-
"github.com/spf13/pflag"
1615
)
1716

1817
// NewCommand returns a new config validate command that validates the configuration file.
1918
func NewCommand(name string, builder appext.SubCommandBuilder) *appcmd.Command {
20-
flags := newFlags()
2119
return &appcmd.Command{
2220
Use: name,
2321
Short: "Validate the configuration file",
2422
Args: appcmd.NoArgs,
2523
Run: builder.NewRunFunc(
2624
func(ctx context.Context, container appext.Container) error {
27-
return run(ctx, container, flags)
25+
return run(ctx, container)
2826
},
2927
),
30-
BindFlags: flags.Bind,
3128
}
3229
}
3330

34-
type flags struct {
35-
// Dir is the ibctl directory containing ibctl.yaml.
36-
Dir string
37-
}
38-
39-
func newFlags() *flags {
40-
return &flags{}
41-
}
42-
43-
// Bind registers the flag definitions with the given flag set.
44-
func (f *flags) Bind(flagSet *pflag.FlagSet) {
45-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
46-
}
47-
48-
func run(_ context.Context, _ appext.Container, flags *flags) error {
49-
return ibctlconfig.ValidateConfig(flags.Dir)
31+
func run(_ context.Context, container appext.Container) error {
32+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
33+
dirPath, err := ibctlcmd.DirPath(container)
34+
if err != nil {
35+
return err
36+
}
37+
return ibctlconfig.ValidateConfig(dirPath)
5038
}

cmd/ibctl/internal/command/data/datazip/datazip.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ func NewCommand(name string, builder appext.SubCommandBuilder) *appcmd.Command {
4040
}
4141

4242
type flags struct {
43-
// Dir is the base directory containing ibctl.yaml and data subdirectories.
44-
Dir string
4543
// Output is the path to the output zip file.
4644
Output string
4745
}
@@ -52,7 +50,6 @@ func newFlags() *flags {
5250

5351
// Bind registers the flag definitions with the given flag set.
5452
func (f *flags) Bind(flagSet *pflag.FlagSet) {
55-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
5653
flagSet.StringVarP(&f.Output, outputFlagName, "o", "", "Output zip file path (required)")
5754
}
5855

@@ -64,8 +61,13 @@ func run(_ context.Context, container appext.Container, flags *flags) error {
6461
if !strings.HasSuffix(flags.Output, ".zip") {
6562
return appcmd.NewInvalidArgumentError("output file must have a .zip extension")
6663
}
64+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
65+
dirPath, err := ibctlcmd.DirPath(container)
66+
if err != nil {
67+
return err
68+
}
6769
// Resolve the base directory to an absolute path.
68-
absDirPath, err := filepath.Abs(flags.Dir)
70+
absDirPath, err := filepath.Abs(dirPath)
6971
if err != nil {
7072
return fmt.Errorf("resolving directory path: %w", err)
7173
}

cmd/ibctl/internal/command/download/download.go

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ import (
1111
"buf.build/go/app/appcmd"
1212
"buf.build/go/app/appext"
1313
"github.com/bufdev/ibctl/cmd/ibctl/internal/ibctlcmd"
14-
"github.com/spf13/pflag"
1514
)
1615

1716
// NewCommand returns a new download command that pre-caches IBKR data.
1817
func NewCommand(name string, builder appext.SubCommandBuilder) *appcmd.Command {
19-
flags := newFlags()
2018
return &appcmd.Command{
2119
Use: name,
2220
Short: "Pre-cache IBKR data via Flex Query API",
@@ -47,30 +45,20 @@ Requires the IBKR_FLEX_WEB_SERVICE_TOKEN environment variable.`,
4745
Args: appcmd.NoArgs,
4846
Run: builder.NewRunFunc(
4947
func(ctx context.Context, container appext.Container) error {
50-
return run(ctx, container, flags)
48+
return run(ctx, container)
5149
},
5250
),
53-
BindFlags: flags.Bind,
5451
}
5552
}
5653

57-
type flags struct {
58-
// Dir is the ibctl directory containing ibctl.yaml.
59-
Dir string
60-
}
61-
62-
func newFlags() *flags {
63-
return &flags{}
64-
}
65-
66-
// Bind registers the flag definitions with the given flag set.
67-
func (f *flags) Bind(flagSet *pflag.FlagSet) {
68-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
69-
}
70-
71-
func run(ctx context.Context, container appext.Container, flags *flags) error {
54+
func run(ctx context.Context, container appext.Container) error {
55+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
56+
dirPath, err := ibctlcmd.DirPath(container)
57+
if err != nil {
58+
return err
59+
}
7260
// Construct the downloader using shared command wiring.
73-
downloader, err := ibctlcmd.NewDownloader(container, flags.Dir)
61+
downloader, err := ibctlcmd.NewDownloader(container, dirPath)
7462
if err != nil {
7563
return err
7664
}

cmd/ibctl/internal/command/holding/category/categorylist/categorylist.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ category. The --geo flag is case-insensitive.`,
5959
}
6060

6161
type flags struct {
62-
// Dir is the base directory containing ibctl.yaml and data subdirectories.
63-
Dir string
6462
// Format is the output format (table, csv, json).
6563
Format string
6664
// Download fetches fresh data before displaying.
@@ -77,7 +75,6 @@ func newFlags() *flags {
7775

7876
// Bind registers the flag definitions with the given flag set.
7977
func (f *flags) Bind(flagSet *pflag.FlagSet) {
80-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
8178
flagSet.StringVar(&f.Format, formatFlagName, "table", "Output format (table, csv, json)")
8279
flagSet.BoolVar(&f.Download, downloadFlagName, false, "Download fresh data before displaying")
8380
flagSet.StringVar(&f.Geo, geoFlagName, "", "Filter by geo (e.g., US, INTL)")
@@ -93,14 +90,19 @@ func run(ctx context.Context, container appext.Container, flags *flags) error {
9390
baseCurrency := strings.ToUpper(flags.BaseCurrency)
9491
// Select the formatting function based on the base currency.
9592
formatBase := formatBaseFunc(baseCurrency)
93+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
94+
dirPath, err := ibctlcmd.DirPath(container)
95+
if err != nil {
96+
return err
97+
}
9698
// Read and validate the configuration file from the base directory.
97-
config, err := ibctlconfig.ReadConfig(flags.Dir)
99+
config, err := ibctlconfig.ReadConfig(dirPath)
98100
if err != nil {
99101
return err
100102
}
101103
// Download fresh data if --download is set.
102104
if flags.Download {
103-
downloader, err := ibctlcmd.NewDownloader(container, flags.Dir)
105+
downloader, err := ibctlcmd.NewDownloader(container, dirPath)
104106
if err != nil {
105107
return err
106108
}

cmd/ibctl/internal/command/holding/geo/geolist/geolist.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ The --category flag is case-insensitive.`,
6060
}
6161

6262
type flags struct {
63-
// Dir is the base directory containing ibctl.yaml and data subdirectories.
64-
Dir string
6563
// Format is the output format (table, csv, json).
6664
Format string
6765
// Download fetches fresh data before displaying.
@@ -78,7 +76,6 @@ func newFlags() *flags {
7876

7977
// Bind registers the flag definitions with the given flag set.
8078
func (f *flags) Bind(flagSet *pflag.FlagSet) {
81-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
8279
flagSet.StringVar(&f.Format, formatFlagName, "table", "Output format (table, csv, json)")
8380
flagSet.BoolVar(&f.Download, downloadFlagName, false, "Download fresh data before displaying")
8481
flagSet.StringVar(&f.Category, categoryFlagName, "", "Filter by category (e.g., EQUITY, FIXED_INCOME)")
@@ -94,14 +91,19 @@ func run(ctx context.Context, container appext.Container, flags *flags) error {
9491
baseCurrency := strings.ToUpper(flags.BaseCurrency)
9592
// Select the formatting function based on the base currency.
9693
formatBase := formatBaseFunc(baseCurrency)
94+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
95+
dirPath, err := ibctlcmd.DirPath(container)
96+
if err != nil {
97+
return err
98+
}
9799
// Read and validate the configuration file from the base directory.
98-
config, err := ibctlconfig.ReadConfig(flags.Dir)
100+
config, err := ibctlconfig.ReadConfig(dirPath)
99101
if err != nil {
100102
return err
101103
}
102104
// Download fresh data if --download is set.
103105
if flags.Download {
104-
downloader, err := ibctlcmd.NewDownloader(container, flags.Dir)
106+
downloader, err := ibctlcmd.NewDownloader(container, dirPath)
105107
if err != nil {
106108
return err
107109
}

cmd/ibctl/internal/command/holding/holdinglist/holdinglist.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ mismatches and cost basis discrepancies above 0.1% are logged as warnings.`,
9090
}
9191

9292
type flags struct {
93-
// Dir is the base directory containing ibctl.yaml and data subdirectories.
94-
Dir string
9593
// Format is the output format (table, csv, json).
9694
Format string
9795
// Download fetches fresh data before displaying.
@@ -106,7 +104,6 @@ func newFlags() *flags {
106104

107105
// Bind registers the flag definitions with the given flag set.
108106
func (f *flags) Bind(flagSet *pflag.FlagSet) {
109-
flagSet.StringVar(&f.Dir, ibctlcmd.DirFlagName, ".", "The ibctl directory containing ibctl.yaml")
110107
flagSet.StringVar(&f.Format, formatFlagName, "table", "Output format (table, csv, json)")
111108
flagSet.BoolVar(&f.Download, downloadFlagName, false, "Download fresh data before displaying")
112109
flagSet.StringVar(&f.BaseCurrency, baseCurrencyFlagName, "USD", "Base currency for value conversion (e.g., USD, CAD)")
@@ -122,14 +119,19 @@ func run(ctx context.Context, container appext.Container, flags *flags) error {
122119
// Select the formatting functions based on the base currency.
123120
formatBase := formatBaseFunc(baseCurrency)
124121
formatBaseMicros := formatBaseMicrosFunc(baseCurrency)
122+
// Resolve the ibctl directory from the IBKR_DIR environment variable.
123+
dirPath, err := ibctlcmd.DirPath(container)
124+
if err != nil {
125+
return err
126+
}
125127
// Read and validate the configuration file from the base directory.
126-
config, err := ibctlconfig.ReadConfig(flags.Dir)
128+
config, err := ibctlconfig.ReadConfig(dirPath)
127129
if err != nil {
128130
return err
129131
}
130132
// Download fresh data if --download is set.
131133
if flags.Download {
132-
downloader, err := ibctlcmd.NewDownloader(container, flags.Dir)
134+
downloader, err := ibctlcmd.NewDownloader(container, dirPath)
133135
if err != nil {
134136
return err
135137
}

0 commit comments

Comments
 (0)