diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf39e5b..68726bf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,17 +1,50 @@ name: Release on: + workflow_dispatch: + pull_request: push: - tags: - - 'v*' - -permissions: - contents: write + branches: + - main + release: + types: + - published jobs: + goreleaser-check: + name: Check GoReleaser + if: github.event_name != 'release' + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 + submodules: recursive + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 + with: + go-version: '1.25' + cache: false + + - name: Check GoReleaser + uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 + with: + distribution: goreleaser + version: latest + args: release --snapshot --clean --skip=publish + goreleaser: name: Release with GoReleaser + if: github.event_name == 'release' && github.event.action == 'published' runs-on: ubuntu-latest + environment: release + permissions: + contents: write steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.golangci.yml b/.golangci.yml index 48bcbd3..e79fc0c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -53,6 +53,9 @@ linters: - gocognit + # Replaced by gomodguard_v2. + - gomodguard + # We don't want to forbid TODO, FIXME, etc. - godox @@ -309,92 +312,90 @@ linters: toolchain-forbidden: true go-version-pattern: \d\.\d+(\.0)? - # IMPORTANT: gomodguard blocks _modules_, not arbitrary packages. Be + # IMPORTANT: gomodguard_v2 blocks _modules_, not arbitrary packages. Be # sure to use the module path from the go.mod file for these. # See https://github.com/ryancurrah/gomodguard/issues/12 - gomodguard: + gomodguard_v2: blocked: - modules: - - github.com/avct/uasurfer: - recommendations: - - github.com/xavivars/uasurfer - reason: The original avct module appears abandoned. - - github.com/BurntSushi/toml: - recommendations: - - github.com/pelletier/go-toml/v2 - reason: This library panics frequently on invalid input. - - github.com/pelletier/go-toml: - recommendations: - - github.com/pelletier/go-toml/v2 - reason: This is an outdated version. - - github.com/gofrs/uuid: - recommendations: - - github.com/google/uuid - - github.com/gofrs/uuid/v5: - recommendations: - - github.com/google/uuid - - github.com/satori/go.uuid: - recommendations: - - github.com/google/uuid - - github.com/google/uuid: - recommendations: - - github.com/google/uuid - - github.com/lib/pq: - recommendations: - - github.com/jackc/pgx - reason: This library is no longer actively maintained. - - github.com/neilotoole/errgroup: - recommendations: - - golang.org/x/sync/errgroup - reason: This library can lead to subtle deadlocks in certain use cases. - - github.com/pariz/gountries: - reason: This library's data is not actively maintained. Use GeoInfo data. - github.com/pkg/errors: - recommendations: - - errors - reason: pkg/errors is no longer maintained. - - github.com/RackSec/srslog: - recommendations: - - log/syslog - reason: This library's data is not actively maintained. - - github.com/ua-parser/uap-go: - recommendations: - - github.com/xavivars/uasurfer - reason: The performance of this library is absolutely abysmal. - - github.com/ugorji/go: - recommendations: - - encoding/json - - github.com/mailru/easyjson - reason: This library is poorly maintained. We should default to using encoding/json and use easyjson where performance really matters. - - github.com/zeebo/assert: - recommendations: - - github.com/stretchr/testify/assert - reason: Use github.com/stretchr/testify/assert - - gopkg.in/yaml.v2: - recommendations: - - github.com/goccy/go-yaml - reason: Not actively maintained. - - gopkg.in/yaml.v3: - recommendations: - - github.com/goccy/go-yaml - reason: Not actively maintained. - - gotest.tools/v3: - recommendations: - - github.com/stretchr/testify/assert - reason: Use github.com/stretchr/testify/assert - - inet.af/netaddr: - recommendations: - - net/netip - - go4.org/netipx - reason: inet.af/netaddr has been deprecated. - versions: - - github.com/jackc/pgconn: - reason: Use github.com/jackc/pgx/v5 - - github.com/jackc/pgtype: - reason: Use github.com/jackc/pgx/v5 - - github.com/jackc/pgx: - version: < 5.0.0 - reason: Use github.com/jackc/pgx/v5 + - module: github.com/avct/uasurfer + recommendations: + - github.com/xavivars/uasurfer + reason: The original avct module appears abandoned. + - module: github.com/BurntSushi/toml + recommendations: + - github.com/pelletier/go-toml/v2 + reason: This library panics frequently on invalid input. + - module: github.com/pelletier/go-toml + recommendations: + - github.com/pelletier/go-toml/v2 + reason: This is an outdated version. + - module: github.com/gofrs/uuid + recommendations: + - github.com/google/uuid + - module: github.com/gofrs/uuid/v5 + recommendations: + - github.com/google/uuid + - module: github.com/satori/go.uuid + recommendations: + - github.com/google/uuid + - module: github.com/google/uuid + recommendations: + - github.com/google/uuid + - module: github.com/lib/pq + recommendations: + - github.com/jackc/pgx + reason: This library is no longer actively maintained. + - module: github.com/neilotoole/errgroup + recommendations: + - golang.org/x/sync/errgroup + reason: This library can lead to subtle deadlocks in certain use cases. + - module: github.com/pariz/gountries + reason: This library's data is not actively maintained. Use GeoInfo data. + - module: github.com/pkg/errors + recommendations: + - errors + reason: pkg/errors is no longer maintained. + - module: github.com/RackSec/srslog + recommendations: + - log/syslog + reason: This library's data is not actively maintained. + - module: github.com/ua-parser/uap-go + recommendations: + - github.com/xavivars/uasurfer + reason: The performance of this library is absolutely abysmal. + - module: github.com/ugorji/go + recommendations: + - encoding/json + - github.com/mailru/easyjson + reason: This library is poorly maintained. We should default to using encoding/json and use easyjson where performance really matters. + - module: github.com/zeebo/assert + recommendations: + - github.com/stretchr/testify/assert + reason: Use github.com/stretchr/testify/assert + - module: gopkg.in/yaml.v2 + recommendations: + - github.com/goccy/go-yaml + reason: Not actively maintained. + - module: gopkg.in/yaml.v3 + recommendations: + - github.com/goccy/go-yaml + reason: Not actively maintained. + - module: gotest.tools/v3 + recommendations: + - github.com/stretchr/testify/assert + reason: Use github.com/stretchr/testify/assert + - module: inet.af/netaddr + recommendations: + - net/netip + - go4.org/netipx + reason: inet.af/netaddr has been deprecated. + - module: github.com/jackc/pgconn + reason: Use github.com/jackc/pgx/v5 + - module: github.com/jackc/pgtype + reason: Use github.com/jackc/pgx/v5 + - module: github.com/jackc/pgx + version: < 5.0.0 + reason: Use github.com/jackc/pgx/v5 gosec: excludes: diff --git a/internal/config/config.go b/internal/config/config.go index 4ed1a03..9b38c5c 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -13,12 +13,50 @@ import ( ) const ( - formatCSV = "csv" - formatParquet = "parquet" - formatMMDB = "mmdb" + // OutputFormatCSV writes CSV output. + OutputFormatCSV = "csv" + // OutputFormatParquet writes Parquet output. + OutputFormatParquet = "parquet" + // OutputFormatMMDB writes MMDB output. + OutputFormatMMDB = "mmdb" + + // NetworkColumnTypeCIDR writes network prefixes in CIDR notation. + NetworkColumnTypeCIDR = "cidr" + // NetworkColumnTypeStartIP writes the first IP address in a network. + NetworkColumnTypeStartIP = "start_ip" + // NetworkColumnTypeEndIP writes the last IP address in a network. + NetworkColumnTypeEndIP = "end_ip" + // NetworkColumnTypeStartInt writes the first IP address as an integer. + NetworkColumnTypeStartInt = "start_int" + // NetworkColumnTypeEndInt writes the last IP address as an integer. + NetworkColumnTypeEndInt = "end_int" + // NetworkColumnTypeBucket writes bucket values for accelerated lookups. + NetworkColumnTypeBucket = "network_bucket" + + // ColumnTypeString coerces data columns to strings. + ColumnTypeString = "string" + // ColumnTypeInt64 coerces data columns to int64. + ColumnTypeInt64 = "int64" + // ColumnTypeFloat64 coerces data columns to float64. + ColumnTypeFloat64 = "float64" + // ColumnTypeBool coerces data columns to bool. + ColumnTypeBool = "bool" + // ColumnTypeBinary coerces data columns to binary. + ColumnTypeBinary = "binary" + + // ParquetCompressionNone uses no compression. + ParquetCompressionNone = "none" + // ParquetCompressionSnappy uses snappy compression. + ParquetCompressionSnappy = "snappy" + // ParquetCompressionGzip uses gzip compression. + ParquetCompressionGzip = "gzip" + // ParquetCompressionLz4 uses lz4 compression. + ParquetCompressionLz4 = "lz4" + // ParquetCompressionZstd uses Zstd compression. + ParquetCompressionZstd = "zstd" // IPv6BucketTypeString stores IPv6 bucket values as hex strings. - IPv6BucketTypeString = "string" + IPv6BucketTypeString = ColumnTypeString // IPv6BucketTypeInt stores IPv6 bucket values as int64 (first 60 bits). IPv6BucketTypeInt = "int" ) @@ -189,7 +227,7 @@ func applyDefaults(config *Config) { // Parquet defaults if config.Output.Parquet.Compression == "" { - config.Output.Parquet.Compression = "snappy" + config.Output.Parquet.Compression = ParquetCompressionSnappy } if config.Output.Parquet.RowGroupSize == 0 { config.Output.Parquet.RowGroupSize = 500000 @@ -205,7 +243,7 @@ func applyDefaults(config *Config) { } // MMDB defaults - if config.Output.Format == formatMMDB { + if config.Output.Format == OutputFormatMMDB { if config.Output.MMDB.RecordSize == nil { config.Output.MMDB.RecordSize = intPtr(28) } @@ -225,19 +263,19 @@ func applyDefaults(config *Config) { // Network column defaults - apply format-specific defaults if no columns specified if len(config.Network.Columns) == 0 { switch config.Output.Format { - case formatParquet: + case OutputFormatParquet: // Parquet default: integer columns for query performance config.Network.Columns = []NetworkColumn{ - {Name: "start_int", Type: "start_int"}, - {Name: "end_int", Type: "end_int"}, + {Name: NetworkColumnTypeStartInt, Type: NetworkColumnTypeStartInt}, + {Name: NetworkColumnTypeEndInt, Type: NetworkColumnTypeEndInt}, } - case formatMMDB: + case OutputFormatMMDB: // MMDB default: no network columns (data written by prefix) config.Network.Columns = []NetworkColumn{} default: // CSV default: human-readable CIDR config.Network.Columns = []NetworkColumn{ - {Name: "network", Type: "cidr"}, + {Name: "network", Type: NetworkColumnTypeCIDR}, } } } @@ -259,8 +297,8 @@ func validate(config *Config) error { if config.Output.Format == "" { return errors.New("output.format is required") } - if config.Output.Format != formatCSV && config.Output.Format != formatParquet && - config.Output.Format != formatMMDB { + if config.Output.Format != OutputFormatCSV && config.Output.Format != OutputFormatParquet && + config.Output.Format != OutputFormatMMDB { return fmt.Errorf( "output.format must be 'csv', 'parquet', or 'mmdb', got '%s'", config.Output.Format, @@ -278,9 +316,11 @@ func validate(config *Config) error { } // Validate Parquet compression - if config.Output.Format == formatParquet { + if config.Output.Format == OutputFormatParquet { validCompressions := map[string]bool{ - "none": true, "snappy": true, "gzip": true, "lz4": true, "zstd": true, + ParquetCompressionNone: true, ParquetCompressionSnappy: true, + ParquetCompressionGzip: true, ParquetCompressionLz4: true, + ParquetCompressionZstd: true, } if !validCompressions[config.Output.Parquet.Compression] { return fmt.Errorf( @@ -291,7 +331,7 @@ func validate(config *Config) error { } // Validate MMDB configuration - if config.Output.Format == formatMMDB { + if config.Output.Format == OutputFormatMMDB { if config.Output.MMDB.DatabaseType == "" { return errors.New("output.mmdb.database_type is required for MMDB output") } @@ -310,7 +350,7 @@ func validate(config *Config) error { } // Validate type hints only allowed for Parquet - if config.Output.Format == formatCSV || config.Output.Format == formatMMDB { + if config.Output.Format == OutputFormatCSV || config.Output.Format == OutputFormatMMDB { for _, col := range config.Columns { if col.Type != "" { return fmt.Errorf( @@ -343,8 +383,9 @@ func validate(config *Config) error { // Validate network columns validNetworkTypes := map[string]bool{ - "cidr": true, "start_ip": true, "end_ip": true, "start_int": true, "end_int": true, - "network_bucket": true, + NetworkColumnTypeCIDR: true, NetworkColumnTypeStartIP: true, + NetworkColumnTypeEndIP: true, NetworkColumnTypeStartInt: true, + NetworkColumnTypeEndInt: true, NetworkColumnTypeBucket: true, } networkColNames := map[mmdbtype.String]bool{} hasBucketColumn := false @@ -362,7 +403,7 @@ func validate(config *Config) error { col.Name, ) } - if col.Type == "network_bucket" { + if col.Type == NetworkColumnTypeBucket { hasBucketColumn = true } if networkColNames[col.Name] { @@ -372,7 +413,7 @@ func validate(config *Config) error { } if hasBucketColumn { - if config.Output.Format == formatMMDB { + if config.Output.Format == OutputFormatMMDB { return errors.New( "network_bucket column type is only supported for CSV and Parquet output", ) @@ -393,7 +434,8 @@ func validate(config *Config) error { // Validate data columns validDataTypes := map[string]bool{ - "": true, "string": true, "int64": true, "float64": true, "bool": true, "binary": true, + "": true, ColumnTypeString: true, ColumnTypeInt64: true, + ColumnTypeFloat64: true, ColumnTypeBool: true, ColumnTypeBinary: true, } dataColNames := map[mmdbtype.String]bool{} for _, col := range config.Columns { @@ -446,7 +488,7 @@ func validateBucketConfig(config *Config) error { var ipv4BucketSize, ipv6BucketSize int var ipv6BucketType string - if config.Output.Format == formatCSV { + if config.Output.Format == OutputFormatCSV { ipv4BucketSize = config.Output.CSV.IPv4BucketSize ipv6BucketSize = config.Output.CSV.IPv6BucketSize ipv6BucketType = config.Output.CSV.IPv6BucketType diff --git a/internal/writer/csv.go b/internal/writer/csv.go index 9cd6dde..347be62 100644 --- a/internal/writer/csv.go +++ b/internal/writer/csv.go @@ -49,7 +49,10 @@ func NewCSVWriter(w io.Writer, cfg *config.Config) *CSVWriter { rangeCapable := true for _, col := range cfg.Network.Columns { switch col.Type { - case NetworkColumnStartIP, NetworkColumnEndIP, NetworkColumnStartInt, NetworkColumnEndInt: + case config.NetworkColumnTypeStartIP, + config.NetworkColumnTypeEndIP, + config.NetworkColumnTypeStartInt, + config.NetworkColumnTypeEndInt: // supported default: rangeCapable = false @@ -293,7 +296,7 @@ func (w *CSVWriter) ensureHeader() error { } // generateNetworkColumnValue generates the value for a network column. -// bucket is only used for NetworkColumnBucket; for other column types it is ignored. +// bucket is only used for config.NetworkColumnTypeBucket; for other column types it is ignored. func (w *CSVWriter) generateNetworkColumnValue( prefix netip.Prefix, bucket netip.Prefix, @@ -302,30 +305,30 @@ func (w *CSVWriter) generateNetworkColumnValue( addr := prefix.Addr() switch colType { - case NetworkColumnCIDR: + case config.NetworkColumnTypeCIDR: return prefix.String(), nil - case NetworkColumnStartIP: + case config.NetworkColumnTypeStartIP: return addr.String(), nil - case NetworkColumnEndIP: + case config.NetworkColumnTypeEndIP: endIP := netipx.PrefixLastIP(prefix) return endIP.String(), nil - case NetworkColumnStartInt: + case config.NetworkColumnTypeStartInt: if addr.Is4() { return strconv.FormatUint(uint64(network.IPv4ToUint32(addr)), 10), nil } return w.formatIPv6AsInt(addr), nil - case NetworkColumnEndInt: + case config.NetworkColumnTypeEndInt: endIP := netipx.PrefixLastIP(prefix) if endIP.Is4() { return strconv.FormatUint(uint64(network.IPv4ToUint32(endIP)), 10), nil } return w.formatIPv6AsInt(endIP), nil - case NetworkColumnBucket: + case config.NetworkColumnTypeBucket: if !bucket.IsValid() { return "", errors.New("invalid bucket but network_bucket column requested") } @@ -354,16 +357,16 @@ func (w *CSVWriter) generateRangeNetworkValue( colType string, ) (string, error) { switch colType { - case NetworkColumnStartIP: + case config.NetworkColumnTypeStartIP: return start.String(), nil - case NetworkColumnEndIP: + case config.NetworkColumnTypeEndIP: return end.String(), nil - case NetworkColumnStartInt: + case config.NetworkColumnTypeStartInt: if start.Is4() { return strconv.FormatUint(uint64(network.IPv4ToUint32(start)), 10), nil } return w.formatIPv6AsInt(start), nil - case NetworkColumnEndInt: + case config.NetworkColumnTypeEndInt: if end.Is4() { return strconv.FormatUint(uint64(network.IPv4ToUint32(end)), 10), nil } diff --git a/internal/writer/parquet.go b/internal/writer/parquet.go index 8e71142..e6a1c0e 100644 --- a/internal/writer/parquet.go +++ b/internal/writer/parquet.go @@ -17,16 +17,12 @@ import ( ) const ( - ipVersionAny = 0 - ipVersion4 = 4 - ipVersion6 = 6 - // IPVersionAny represents a Parquet writer that accepts both IPv4 and IPv6 rows. - IPVersionAny = ipVersionAny + IPVersionAny = 0 // IPVersion4 constrains a Parquet writer to IPv4 rows. - IPVersion4 = ipVersion4 + IPVersion4 = 4 // IPVersion6 constrains a Parquet writer to IPv6 rows. - IPVersion6 = ipVersion6 + IPVersion6 = 6 ) // ParquetWriter writes merged MMDB data to Parquet format. @@ -42,7 +38,7 @@ type ParquetWriter struct { // NewParquetWriter creates a new Parquet writer. func NewParquetWriter(w io.Writer, cfg *config.Config) (*ParquetWriter, error) { - return NewParquetWriterWithIPVersion(w, cfg, ipVersionAny) + return NewParquetWriterWithIPVersion(w, cfg, IPVersionAny) } // NewParquetWriterWithIPVersion creates a Parquet writer scoped to a specific IP version. @@ -197,7 +193,7 @@ func (w *ParquetWriter) Flush() error { } // generateNetworkColumnValue generates the value for a network column. -// bucket is only used for NetworkColumnBucket; for other column types it is ignored. +// bucket is only used for config.NetworkColumnTypeBucket; for other column types it is ignored. func (w *ParquetWriter) generateNetworkColumnValue( prefix netip.Prefix, bucket netip.Prefix, @@ -206,56 +202,56 @@ func (w *ParquetWriter) generateNetworkColumnValue( addr := prefix.Addr() switch colType { - case NetworkColumnCIDR: + case config.NetworkColumnTypeCIDR: return prefix.String(), nil - case NetworkColumnStartIP: + case config.NetworkColumnTypeStartIP: return addr.String(), nil - case NetworkColumnEndIP: + case config.NetworkColumnTypeEndIP: endIP := netipx.PrefixLastIP(prefix) return endIP.String(), nil - case NetworkColumnStartInt: + case config.NetworkColumnTypeStartInt: if addr.Is4() { - if w.ipVersion == ipVersion6 { + if w.ipVersion == IPVersion6 { return nil, errors.New("encountered IPv4 address in IPv6-specific writer") } return int64(network.IPv4ToUint32(addr)), nil } - if w.ipVersion == ipVersion4 { + if w.ipVersion == IPVersion4 { return nil, errors.New( "start_int column type only supports IPv4 in IPv4-only Parquet files; configure output.ipv4_file and output.ipv6_file to emit IPv6 integer columns", ) } - if w.ipVersion == ipVersion6 { + if w.ipVersion == IPVersion6 { return ipv6IntBytes(addr), nil } return nil, errors.New( "start_int column type only supports IPv4 unless you configure output.ipv4_file and output.ipv6_file", ) - case NetworkColumnEndInt: + case config.NetworkColumnTypeEndInt: endIP := netipx.PrefixLastIP(prefix) if endIP.Is4() { - if w.ipVersion == ipVersion6 { + if w.ipVersion == IPVersion6 { return nil, errors.New("encountered IPv4 address in IPv6-specific writer") } return int64(network.IPv4ToUint32(endIP)), nil } - if w.ipVersion == ipVersion4 { + if w.ipVersion == IPVersion4 { return nil, errors.New( "end_int column type only supports IPv4 in IPv4-only Parquet files; configure output.ipv4_file and output.ipv6_file to emit IPv6 integer columns", ) } - if w.ipVersion == ipVersion6 { + if w.ipVersion == IPVersion6 { return ipv6IntBytes(endIP), nil } return nil, errors.New( "end_int column type only supports IPv4 unless you configure output.ipv4_file and output.ipv6_file", ) - case NetworkColumnBucket: + case config.NetworkColumnTypeBucket: if !bucket.IsValid() { return nil, errors.New("invalid bucket but network_bucket column requested") } @@ -316,19 +312,21 @@ func buildNetworkNode( cfg *config.Config, ) (parquet.Node, error) { switch col.Type { - case NetworkColumnCIDR, NetworkColumnStartIP, NetworkColumnEndIP: + case config.NetworkColumnTypeCIDR, + config.NetworkColumnTypeStartIP, + config.NetworkColumnTypeEndIP: // String columns return parquet.Optional(parquet.String()), nil - case NetworkColumnStartInt, NetworkColumnEndInt: - if ipVersion == ipVersion6 { + case config.NetworkColumnTypeStartInt, config.NetworkColumnTypeEndInt: + if ipVersion == IPVersion6 { return parquet.Optional(parquet.Leaf(parquet.FixedLenByteArrayType(16))), nil } return parquet.Optional(parquet.Int(64)), nil - case NetworkColumnBucket: + case config.NetworkColumnTypeBucket: // IPv6 bucket: string (hex) by default, int64 when explicitly configured - if ipVersion == ipVersion6 && + if ipVersion == IPVersion6 && cfg.Output.Parquet.IPv6BucketType != config.IPv6BucketTypeInt { return parquet.Optional(parquet.String()), nil } @@ -349,21 +347,21 @@ func ipv6IntBytes(addr netip.Addr) []byte { // buildDataNode builds a Parquet node for a data column. func buildDataNode(col config.Column) (parquet.Node, error) { // Default to string if no type specified - if col.Type == "" || col.Type == "string" { + if col.Type == "" || col.Type == config.ColumnTypeString { return parquet.Optional(parquet.String()), nil } switch col.Type { - case "int64": + case config.ColumnTypeInt64: return parquet.Optional(parquet.Int(64)), nil - case "float64": + case config.ColumnTypeFloat64: return parquet.Optional(parquet.Leaf(parquet.DoubleType)), nil - case "bool": + case config.ColumnTypeBool: return parquet.Optional(parquet.Leaf(parquet.BooleanType)), nil - case "binary": + case config.ColumnTypeBinary: return parquet.Optional(parquet.Leaf(parquet.ByteArrayType)), nil default: @@ -378,12 +376,12 @@ func convertToParquetType(value any, typeHint string) (any, error) { } // If no type hint, return as-is (will be string) - if typeHint == "" || typeHint == "string" { + if typeHint == "" || typeHint == config.ColumnTypeString { return convertToString(value) } switch typeHint { - case "int64": + case config.ColumnTypeInt64: switch v := value.(type) { case mmdbtype.Int32: return int64(v), nil @@ -406,7 +404,7 @@ func convertToParquetType(value any, typeHint string) (any, error) { return nil, fmt.Errorf("cannot convert %T to int64", value) } - case "float64": + case config.ColumnTypeFloat64: switch v := value.(type) { case mmdbtype.Float32: return float64(v), nil @@ -428,13 +426,13 @@ func convertToParquetType(value any, typeHint string) (any, error) { return nil, fmt.Errorf("cannot convert %T to float64", value) } - case "bool": + case config.ColumnTypeBool: if v, ok := value.(mmdbtype.Bool); ok { return bool(v), nil } return nil, fmt.Errorf("cannot convert %T to bool", value) - case "binary": + case config.ColumnTypeBinary: if v, ok := value.(mmdbtype.Bytes); ok { return []byte(v), nil } @@ -448,15 +446,15 @@ func convertToParquetType(value any, typeHint string) (any, error) { // getCompressionCodec returns the compression codec for the given name. func getCompressionCodec(name string) (compress.Codec, error) { switch name { - case "none": + case config.ParquetCompressionNone: return &parquet.Uncompressed, nil - case "snappy": + case config.ParquetCompressionSnappy: return &parquet.Snappy, nil - case "gzip": + case config.ParquetCompressionGzip: return &parquet.Gzip, nil - case "lz4": + case config.ParquetCompressionLz4: return &parquet.Lz4Raw, nil - case "zstd": + case config.ParquetCompressionZstd: return &parquet.Zstd, nil default: return nil, fmt.Errorf("unknown compression codec: %s", name) @@ -468,7 +466,7 @@ func getCompressionCodec(name string) (compress.Codec, error) { // this sort order in the Parquet metadata to help query engines optimize lookups. func determineSortingColumns(cfg *config.Config) parquet.WriterOption { for _, col := range cfg.Network.Columns { - if col.Type == NetworkColumnStartInt { + if col.Type == config.NetworkColumnTypeStartInt { return parquet.SortingWriterConfig( parquet.SortingColumns(parquet.Ascending(string(col.Name))), ) diff --git a/internal/writer/writer.go b/internal/writer/writer.go index 4383886..f62cb4d 100644 --- a/internal/writer/writer.go +++ b/internal/writer/writer.go @@ -3,20 +3,10 @@ package writer import "github.com/maxmind/mmdbconvert/internal/config" -// Network column type constants. -const ( - NetworkColumnCIDR = "cidr" - NetworkColumnStartIP = "start_ip" - NetworkColumnEndIP = "end_ip" - NetworkColumnStartInt = "start_int" - NetworkColumnEndInt = "end_int" - NetworkColumnBucket = "network_bucket" -) - // hasNetworkBucketColumn returns true if a network_bucket column is configured. func hasNetworkBucketColumn(cfg *config.Config) bool { for _, col := range cfg.Network.Columns { - if col.Type == NetworkColumnBucket { + if col.Type == config.NetworkColumnTypeBucket { return true } } diff --git a/lychee.toml b/lychee.toml index 4cbc854..4da452d 100644 --- a/lychee.toml +++ b/lychee.toml @@ -5,7 +5,7 @@ # lychee './**/*.md' './**/*.go' # Include URL fragments in checks -include_fragments = true +include_fragments = "full" # Don't allow any redirects, so links that have moved are surfaced and can be # updated to their canonical destination. diff --git a/mise.lock b/mise.lock index 4006d8f..5761e7a 100644 --- a/mise.lock +++ b/mise.lock @@ -1,180 +1,193 @@ -# @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html +# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html [[tools."github:golangci/golangci-lint"]] -version = "2.11.3" +version = "2.12.2" backend = "github:golangci/golangci-lint" [tools."github:golangci/golangci-lint"."platforms.linux-arm64"] -checksum = "sha256:ee3d95f301359e7d578e6d99c8ad5aeadbabc5a13009a30b2b0df11c8058afe9" -url = "https://github.com/golangci/golangci-lint/releases/download/v2.11.3/golangci-lint-2.11.3-linux-arm64.tar.gz" -url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/370749014" +checksum = "sha256:44cd40a8c76c86755375adfeea52cfd3533cb43d7bd647771e0ae065e166df3a" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-arm64.tar.gz" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470996" provenance = "github-attestations" [tools."github:golangci/golangci-lint"."platforms.linux-arm64-musl"] -checksum = "sha256:ee3d95f301359e7d578e6d99c8ad5aeadbabc5a13009a30b2b0df11c8058afe9" -url = "https://github.com/golangci/golangci-lint/releases/download/v2.11.3/golangci-lint-2.11.3-linux-arm64.tar.gz" -url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/370749014" +checksum = "sha256:44cd40a8c76c86755375adfeea52cfd3533cb43d7bd647771e0ae065e166df3a" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-arm64.tar.gz" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470996" provenance = "github-attestations" [tools."github:golangci/golangci-lint"."platforms.linux-x64"] -checksum = "sha256:87bb8cddbcc825d5778b64e8a91b46c0526b247f4e2f2904dea74ec7450475d1" -url = "https://github.com/golangci/golangci-lint/releases/download/v2.11.3/golangci-lint-2.11.3-linux-amd64.tar.gz" -url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/370748984" +checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471054" provenance = "github-attestations" [tools."github:golangci/golangci-lint"."platforms.linux-x64-musl"] -checksum = "sha256:87bb8cddbcc825d5778b64e8a91b46c0526b247f4e2f2904dea74ec7450475d1" -url = "https://github.com/golangci/golangci-lint/releases/download/v2.11.3/golangci-lint-2.11.3-linux-amd64.tar.gz" -url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/370748984" +checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471054" provenance = "github-attestations" [tools."github:golangci/golangci-lint"."platforms.macos-arm64"] -checksum = "sha256:30ee39979c516b9d1adca289a3f93429d130c4c0fda5e57d637850894221f6cc" -url = "https://github.com/golangci/golangci-lint/releases/download/v2.11.3/golangci-lint-2.11.3-darwin-arm64.tar.gz" -url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/370749042" +checksum = "sha256:a9c54498731b3128f79e090be6110f3e5fffccc617b08142ed244d4126c73f29" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-darwin-arm64.tar.gz" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470950" provenance = "github-attestations" [tools."github:golangci/golangci-lint"."platforms.macos-x64"] -checksum = "sha256:f93bda1f2cc981fd1326464020494be62f387bbf262706e1b3b644e5afacc440" -url = "https://github.com/golangci/golangci-lint/releases/download/v2.11.3/golangci-lint-2.11.3-darwin-amd64.tar.gz" -url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/370749038" +checksum = "sha256:f6f06d94b6241521c53d15450c5209b028270bf966f842afb11c030c79f5bc16" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-darwin-amd64.tar.gz" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470980" +provenance = "github-attestations" [tools."github:golangci/golangci-lint"."platforms.windows-x64"] -checksum = "sha256:cd42e890176bc5cfeb36225a77e66b9410ddd3a59a03551e23f6b210d29e1f67" -url = "https://github.com/golangci/golangci-lint/releases/download/v2.11.3/golangci-lint-2.11.3-windows-amd64.zip" -url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/370749053" +checksum = "sha256:bd42e3ebc8cb4ececb86941983baaf1dc221bbb04d838e94ce63b49cc91e02bb" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-windows-amd64.zip" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471017" +provenance = "github-attestations" [[tools."github:houseabsolute/precious"]] -version = "0.10.2" +version = "0.11.0" backend = "github:houseabsolute/precious" [tools."github:houseabsolute/precious"."platforms.linux-arm64"] -checksum = "sha256:8fbaead9f9626170549c3121e67d1bc81193b3bb086e29576f548aefa839fcc4" -url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Linux-musl-arm64.tar.gz" -url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345520042" +checksum = "sha256:44d98091a988671786a99d8025b169c76bb08718ffa8f793a80ae1aa97ca5472" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-Linux-musl-arm64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639525" [tools."github:houseabsolute/precious"."platforms.linux-arm64-musl"] -checksum = "sha256:8fbaead9f9626170549c3121e67d1bc81193b3bb086e29576f548aefa839fcc4" -url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Linux-musl-arm64.tar.gz" -url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345520042" +checksum = "sha256:44d98091a988671786a99d8025b169c76bb08718ffa8f793a80ae1aa97ca5472" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-Linux-musl-arm64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639525" [tools."github:houseabsolute/precious"."platforms.linux-x64"] -checksum = "sha256:3d717d906db338f63017766b07982dc9055773e1b3bec6d3f432d1f0ad9676bb" -url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Linux-musl-x86_64.tar.gz" -url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345519861" +checksum = "sha256:6a267a3e309ebd39ef36352e283b2ad70066ccb61e4b04785afbd85df3fa76b4" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-Linux-musl-x86_64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639494" [tools."github:houseabsolute/precious"."platforms.linux-x64-musl"] -checksum = "sha256:3d717d906db338f63017766b07982dc9055773e1b3bec6d3f432d1f0ad9676bb" -url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Linux-musl-x86_64.tar.gz" -url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345519861" +checksum = "sha256:6a267a3e309ebd39ef36352e283b2ad70066ccb61e4b04785afbd85df3fa76b4" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-Linux-musl-x86_64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639494" [tools."github:houseabsolute/precious"."platforms.macos-arm64"] -checksum = "sha256:04157c64459bb6ab029295b21b112077040ad2575b34508d84b19a839551cddb" -url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-macOS-arm64.tar.gz" -url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345519985" +checksum = "sha256:e6cbdba5261c15e3eb9208af928facff50c883bb11c0dd0c10766379285c75b9" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-macOS-arm64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639276" [tools."github:houseabsolute/precious"."platforms.macos-x64"] -checksum = "sha256:9932defd246d0771530357463bdb55582557fd7381853cb4dc2074e36ad0cc84" -url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-macOS-x86_64.tar.gz" -url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345519772" +checksum = "sha256:5500304c379686acd0cb852ad9f32e20baaab939f7fbc1f75f1ec0583f4bd676" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-macOS-x86_64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639281" [tools."github:houseabsolute/precious"."platforms.windows-x64"] -checksum = "sha256:9d683d1730e302c646ccb90a23d313e7a548c8b23b5abf7d24e19ff6befe763d" -url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Windows-msvc-x86_64.zip" -url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345520544" +checksum = "sha256:bc5dfb482675ef79798fa578dc5f8edea1cd9f2b5d7bdc5bb02b4a9590f54467" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-Windows-msvc-x86_64.zip" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434640219" [[tools.go]] -version = "1.26.1" +version = "1.26.4" backend = "core:go" [tools.go."platforms.linux-arm64"] -checksum = "sha256:a290581cfe4fe28ddd737dde3095f3dbeb7f2e4065cab4eae44dfc53b760c2f7" -url = "https://dl.google.com/go/go1.26.1.linux-arm64.tar.gz" +checksum = "sha256:ef758ae7c6cf9267c9c0ef080b8965f453d89ab2d25d9eb22de4405925238768" +url = "https://dl.google.com/go/go1.26.4.linux-arm64.tar.gz" [tools.go."platforms.linux-arm64-musl"] -checksum = "sha256:a290581cfe4fe28ddd737dde3095f3dbeb7f2e4065cab4eae44dfc53b760c2f7" -url = "https://dl.google.com/go/go1.26.1.linux-arm64.tar.gz" +checksum = "sha256:ef758ae7c6cf9267c9c0ef080b8965f453d89ab2d25d9eb22de4405925238768" +url = "https://dl.google.com/go/go1.26.4.linux-arm64.tar.gz" [tools.go."platforms.linux-x64"] -checksum = "sha256:031f088e5d955bab8657ede27ad4e3bc5b7c1ba281f05f245bcc304f327c987a" -url = "https://dl.google.com/go/go1.26.1.linux-amd64.tar.gz" +checksum = "sha256:1153d3d50e0ac764b447adfe05c2bcf08e889d42a02e0fe0259bd47f6733ad7f" +url = "https://dl.google.com/go/go1.26.4.linux-amd64.tar.gz" [tools.go."platforms.linux-x64-musl"] -checksum = "sha256:031f088e5d955bab8657ede27ad4e3bc5b7c1ba281f05f245bcc304f327c987a" -url = "https://dl.google.com/go/go1.26.1.linux-amd64.tar.gz" +checksum = "sha256:1153d3d50e0ac764b447adfe05c2bcf08e889d42a02e0fe0259bd47f6733ad7f" +url = "https://dl.google.com/go/go1.26.4.linux-amd64.tar.gz" [tools.go."platforms.macos-arm64"] -checksum = "sha256:353df43a7811ce284c8938b5f3c7df40b7bfb6f56cb165b150bc40b5e2dd541f" -url = "https://dl.google.com/go/go1.26.1.darwin-arm64.tar.gz" +checksum = "sha256:b62ad2b6d7d2464f12a5bcad7ff47f19d08325773b5efd21610e445a05a9bf53" +url = "https://dl.google.com/go/go1.26.4.darwin-arm64.tar.gz" [tools.go."platforms.macos-x64"] -checksum = "sha256:65773dab2f8cc4cd23d93ba6d0a805de150ca0b78378879292be0b903b8cdd08" -url = "https://dl.google.com/go/go1.26.1.darwin-amd64.tar.gz" +checksum = "sha256:05dc9b5f9997744520aaebb3d5deaa7c755371aebbfb7f97c2511a9f3367538d" +url = "https://dl.google.com/go/go1.26.4.darwin-amd64.tar.gz" [tools.go."platforms.windows-x64"] -checksum = "sha256:9b68112c913f45b7aebbf13c036721264bbba7e03a642f8f7490c561eebd1ecc" -url = "https://dl.google.com/go/go1.26.1.windows-amd64.zip" +checksum = "sha256:3ca8fb4630b07c419cbdd51f754e31363cfcfb83b3a5354d9e895c90be2cc345" +url = "https://dl.google.com/go/go1.26.4.windows-amd64.zip" [[tools.lychee]] -version = "0.23.0" +version = "0.24.2" backend = "aqua:lycheeverse/lychee" [tools.lychee."platforms.linux-arm64"] -checksum = "sha256:97eb93b02a7d78a752fc33e5b0983439ccaadbf3db952b68a0a4401acd92e6e0" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-aarch64-unknown-linux-gnu.tar.gz" +checksum = "sha256:5d0b0e3aeab240f41920c633a6eaf97599be6eedda034b36e858ede7dba5e535" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409958602" [tools.lychee."platforms.linux-arm64-musl"] -checksum = "sha256:97eb93b02a7d78a752fc33e5b0983439ccaadbf3db952b68a0a4401acd92e6e0" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-aarch64-unknown-linux-gnu.tar.gz" +checksum = "sha256:5d0b0e3aeab240f41920c633a6eaf97599be6eedda034b36e858ede7dba5e535" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409958602" [tools.lychee."platforms.linux-x64"] -checksum = "sha256:5538440d2c69a45a0a09983271e5dee0c2fe7137d8035d25b2632e10a66a090a" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-unknown-linux-musl.tar.gz" +checksum = "sha256:73657a111819a30c47c08352896796f23d64e4eb2b3ed39b6d32149241566fc5" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409959271" [tools.lychee."platforms.linux-x64-musl"] -checksum = "sha256:5538440d2c69a45a0a09983271e5dee0c2fe7137d8035d25b2632e10a66a090a" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-unknown-linux-musl.tar.gz" +checksum = "sha256:73657a111819a30c47c08352896796f23d64e4eb2b3ed39b6d32149241566fc5" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-unknown-linux-musl.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409959271" [tools.lychee."platforms.macos-arm64"] -checksum = "sha256:4c8034900e11083b68ac6f6582c377ff1f704e268991999e09d717973e493e7f" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-arm64-macos.dmg" +checksum = "sha256:c9d3740ea2d891854d37116c9fba840f37b6e7c89d330e7db84ac333631c4977" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-apple-darwin.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409957951" + +[tools.lychee."platforms.macos-x64"] +checksum = "sha256:887503a9cff667d322b8d0892b40bf49976eb9507af8483220a3706cdad55978" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-apple-darwin.tar.gz" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409957687" [tools.lychee."platforms.windows-x64"] -checksum = "sha256:0fda7ff0a60c0250939fc25361c2d4e6e7853c31c996733fdd5a1dd760bcb824" -url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-windows.exe" +checksum = "sha256:32975d1493ee1a975d6bb41e4fb56fe419cb442ded628bb772ba2e614acfacad" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-pc-windows-msvc.zip" +url_api = "https://api.github.com/repos/lycheeverse/lychee/releases/assets/409959491" [[tools.node]] -version = "25.8.0" +version = "26.4.0" backend = "core:node" [tools.node."platforms.linux-arm64"] -checksum = "sha256:54c128f5286a4392a1fd1c765729b074a6873abff8a4f9bb3d63d571c2855e41" -url = "https://nodejs.org/dist/v25.8.0/node-v25.8.0-linux-arm64.tar.gz" +checksum = "sha256:773d9ec67266838270ddc105c2548ae8aaff28bc8fe6f34c55d1094043c4165e" +url = "https://nodejs.org/dist/v26.4.0/node-v26.4.0-linux-arm64.tar.gz" [tools.node."platforms.linux-arm64-musl"] -checksum = "sha256:54c128f5286a4392a1fd1c765729b074a6873abff8a4f9bb3d63d571c2855e41" -url = "https://nodejs.org/dist/v25.8.0/node-v25.8.0-linux-arm64.tar.gz" +checksum = "sha256:d2ad8c6e9fa955edf0337078c1d1acda345d36a84986b218cce3cfd1d2d26920" +url = "https://unofficial-builds.nodejs.org/download/release/v26.4.0/node-v26.4.0-linux-arm64-musl.tar.gz" [tools.node."platforms.linux-x64"] -checksum = "sha256:2ae6f70d74a459c0a96456e486dc60f3e7e65d7752ad302771834e58b27500af" -url = "https://nodejs.org/dist/v25.8.0/node-v25.8.0-linux-x64.tar.gz" +checksum = "sha256:f221dab30d0e9d544332f06fbee2c62186c97d864d5cac8482dba34f1e38b8dc" +url = "https://nodejs.org/dist/v26.4.0/node-v26.4.0-linux-x64.tar.gz" [tools.node."platforms.linux-x64-musl"] -checksum = "sha256:2ae6f70d74a459c0a96456e486dc60f3e7e65d7752ad302771834e58b27500af" -url = "https://nodejs.org/dist/v25.8.0/node-v25.8.0-linux-x64.tar.gz" +checksum = "sha256:554e960f6570bd3d1987f5170d8f2a373a21818581a8d307b697e7839988314a" +url = "https://unofficial-builds.nodejs.org/download/release/v26.4.0/node-v26.4.0-linux-x64-musl.tar.gz" [tools.node."platforms.macos-arm64"] -checksum = "sha256:75ff6fd07e0a85fb4d2529f6189c996014b1d3d83180c31e65feb2b3eaeec5d9" -url = "https://nodejs.org/dist/v25.8.0/node-v25.8.0-darwin-arm64.tar.gz" +checksum = "sha256:4f4fbcacf6b1ff1a95deedba7bd7b2d79efecaa53a8ecb0530546dc9063fefbc" +url = "https://nodejs.org/dist/v26.4.0/node-v26.4.0-darwin-arm64.tar.gz" [tools.node."platforms.macos-x64"] -checksum = "sha256:03fb559600c3ede0228d8b588ac6ad8b7b2cd0bac9422b56e7e2ef7f5c11b67c" -url = "https://nodejs.org/dist/v25.8.0/node-v25.8.0-darwin-x64.tar.gz" +checksum = "sha256:eb3bdd8dec3ff2558ee10e284da7d2a3865af0cbda21f06d397b0265837c641e" +url = "https://nodejs.org/dist/v26.4.0/node-v26.4.0-darwin-x64.tar.gz" [tools.node."platforms.windows-x64"] -checksum = "sha256:5744746371a417179a701044739b5fa2b3164e943aa57f86059fb312f8032e86" -url = "https://nodejs.org/dist/v25.8.0/node-v25.8.0-win-x64.zip" +checksum = "sha256:5f87d038c6ec442aa46b9126f8ca170acbd2f3b9b9152ca798cf54596a31e214" +url = "https://nodejs.org/dist/v26.4.0/node-v26.4.0-win-x64.zip" [[tools."npm:prettier"]] -version = "3.8.1" +version = "3.9.4" backend = "npm:prettier" diff --git a/mmdbconvert.go b/mmdbconvert.go index aa76654..69adc69 100644 --- a/mmdbconvert.go +++ b/mmdbconvert.go @@ -96,7 +96,7 @@ func prepareRowWriter( } switch cfg.Output.Format { - case "csv": + case config.OutputFormatCSV: if cfg.Output.IPv4File != "" && cfg.Output.IPv6File != "" { ipv4Path, ipv6Path := splitConfiguredPaths( cfg.Output.File, @@ -131,7 +131,7 @@ func prepareRowWriter( closers = append(closers, outputFile) return writer.NewCSVWriter(outputFile, cfg), closers, nil - case "parquet": + case config.OutputFormatParquet: if cfg.Output.IPv4File != "" && cfg.Output.IPv6File != "" { ipv4Path, ipv6Path := splitConfiguredPaths( cfg.Output.File, @@ -188,7 +188,7 @@ func prepareRowWriter( } return parquetWriter, closers, nil - case "mmdb": + case config.OutputFormatMMDB: ipVersion, err := detectIPVersionFromDatabases(cfg, readers) if err != nil { closeAll() @@ -232,7 +232,6 @@ func detectIPVersionFromDatabases(cfg *config.Config, readers *mmdb.Readers) (in } metadata := reader.Metadata() - //nolint:gosec // IPVersion is always 4 or 6, no overflow risk ipVersion := int(metadata.IPVersion) if ipVersion != 4 && ipVersion != 6 { @@ -268,7 +267,7 @@ func splitConfiguredPaths(base, ipv4Override, ipv6Override string) (ipv4, ipv6 s } func validateParquetNetworkColumns(cfg *config.Config, readers *mmdb.Readers) error { - if cfg.Output.Format != "parquet" { + if cfg.Output.Format != config.OutputFormatParquet { return nil } @@ -298,7 +297,7 @@ func validateParquetNetworkColumns(cfg *config.Config, readers *mmdb.Readers) er func hasIntegerNetworkColumns(cols []config.NetworkColumn) bool { for _, col := range cols { switch col.Type { - case writer.NetworkColumnStartInt, writer.NetworkColumnEndInt: + case config.NetworkColumnTypeStartInt, config.NetworkColumnTypeEndInt: return true } }