Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Add option to specify generated method name #4

Merged
merged 3 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# [arcgen](https://github.com/kunitsucom/arcgen)

[![license](https://img.shields.io/github/license/kunitsucom/arcgen)](LICENSE)
[![pkg](https://pkg.go.dev/badge/github.com/kunitsucom/arcgen)](https://pkg.go.dev/github.com/kunitsucom/arcgen)
[![goreportcard](https://goreportcard.com/badge/github.com/kunitsucom/arcgen)](https://goreportcard.com/report/github.com/kunitsucom/arcgen)
[![workflow](https://github.com/kunitsucom/arcgen/workflows/go-lint/badge.svg)](https://github.com/kunitsucom/arcgen/tree/main)
[![workflow](https://github.com/kunitsucom/arcgen/workflows/go-test/badge.svg)](https://github.com/kunitsucom/arcgen/tree/main)
[![workflow](https://github.com/kunitsucom/arcgen/workflows/go-vuln/badge.svg)](https://github.com/kunitsucom/arcgen/tree/main)
[![codecov](https://codecov.io/gh/kunitsucom/arcgen/graph/badge.svg?token=Y19kZ7UtVZ)](https://codecov.io/gh/kunitsucom/arcgen)
[![sourcegraph](https://sourcegraph.com/github.com/kunitsucom/arcgen/-/badge.svg)](https://sourcegraph.com/github.com/kunitsucom/arcgen)

## Overview

`arcgen` is a tool that generates methods that return information such as DB table names and column names from Go struct tags.

## Example

```console
$ # == 1. Prepare your annotated model source code ================================
$ cat <<"EOF" > /tmp/sample.go
package sample

// User is a user model struct.
//
// db: table: Users
type User struct {
ID int64 `db:"Id" spanddl:"STRING(36) NOT NULL"`
Name string `db:"Name" spanddl:"STRING(255) NOT NULL"`
Age int64 `db:"Age" spanddl:"INT64 NOT NULL"`
}

// Group is a group model struct.
//
type Group struct {
ID int64 `db:"Id" spanddl:"STRING(36) NOT NULL"`
Name string `db:"Name" spanddl:"STRING(255) NOT NULL"`
Description string `db:"Description" spanddl:"STRING(2048) NOT NULL"`
}
EOF

$ # == 2. generate file ================================
$ arcgen --src /tmp/sample.go
INFO: 2023/11/12 03:56:59 arcgen.go:33: source: /tmp/sample.go

$ # == 3. Check generated file ================================
$ cat /tmp/sample.db.gen.go
// Code generated by arcgen. DO NOT EDIT.
//
// source: tmp/sample.go

package sample

func (s *User) TableName() string {
return "Users"
}

func (s *User) ColumnNames() []string {
return []string{"Id", "Name", "Age"}
}

func (s *User) ColumnName_ID() string {
return "Id"
}

func (s *User) ColumnName_Name() string {
return "Name"
}

func (s *User) ColumnName_Age() string {
return "Age"
}

func (s *Group) ColumnNames() []string {
return []string{"Id", "Name", "Description"}
}

func (s *Group) ColumnName_ID() string {
return "Id"
}

func (s *Group) ColumnName_Name() string {
return "Name"
}

func (s *Group) ColumnName_Description() string {
return "Description"
}
```

## Installation

### pre-built binary

```bash
VERSION=v0.0.3

# download
curl -fLROSs https://github.com/kunitsucom/arcgen/releases/download/${VERSION}/arcgen_${VERSION}_darwin_arm64.zip

# unzip
unzip -j arcgen_${VERSION}_darwin_arm64.zip '*/arcgen'
```

### go install

```bash
go install github.com/kunitsucom/arcgen/cmd/arcgen@latest
```

## Usage

```console
$ arcgen --help
Usage:
arcgen [options]

Description:
Generate methods that return information such as DB table names and column names from Go struct tags.

options:
--version (default: false)
show version information and exit
--trace (env: ARCGEN_TRACE, default: false)
trace mode enabled
--debug (env: ARCGEN_DEBUG, default: false)
debug mode
--lang (env: ARCGEN_LANGUAGE, default: go)
programming language to generate DDL
--src (env: ARCGEN_SOURCE, default: /dev/stdin)
source file or directory
--column-tag-go (env: ARCGEN_COLUMN_TAG_GO, default: db)
column annotation key for Go struct tag
--method-name-table (env: ARCGEN_METHOD_NAME_TABLE, default: TableName)
method name for table
--method-name-columns (env: ARCGEN_METHOD_NAME_COLUMNS, default: ColumnNames)
method name for columns
--method-prefix-column (env: ARCGEN_METHOD_PREFIX_COLUMN, default: ColumnName_)
method prefix for column name
--help (default: false)
show usage
```

## TODO

- lang
- [x] Support `go`
14 changes: 7 additions & 7 deletions internal/arcgen/lang/go/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func fprint(osFile io.Writer, buf buffer, arcSrcSet *ARCSourceSet) error {
}
}

appendAST(astFile, structName, tableName, config.MethodNameTable(), config.MethodPrefixColumn(), fieldNames, columnNames)
appendAST(astFile, structName, tableName, config.MethodNameTable(), config.MethodNameColumns(), config.MethodPrefixColumn(), fieldNames, columnNames)
}

if err := printer.Fprint(buf, token.NewFileSet(), astFile); err != nil {
Expand Down Expand Up @@ -129,7 +129,7 @@ func extractTableNameFromCommentGroup(commentGroup *ast.CommentGroup) string {
}

//nolint:funlen
func appendAST(file *ast.File, structName string, tableName string, prefixGlobal string, prefixColumn string, fieldNames, columnNames []string) {
func appendAST(file *ast.File, structName string, tableName string, methodNameTable string, methodNameColumns string, methodPrefixColumn string, fieldNames, columnNames []string) {
if tableName != "" {
file.Decls = append(file.Decls, &ast.FuncDecl{
Recv: &ast.FieldList{
Expand All @@ -149,7 +149,7 @@ func appendAST(file *ast.File, structName string, tableName string, prefixGlobal
},
},
Name: &ast.Ident{
Name: prefixGlobal + "TableName",
Name: methodNameTable,
},
Type: &ast.FuncType{
Params: &ast.FieldList{},
Expand Down Expand Up @@ -177,13 +177,13 @@ func appendAST(file *ast.File, structName string, tableName string, prefixGlobal
})
}

file.Decls = append(file.Decls, generateASTColumnMethods(structName, prefixGlobal, prefixColumn, fieldNames, columnNames)...)
file.Decls = append(file.Decls, generateASTColumnMethods(structName, methodNameColumns, methodPrefixColumn, fieldNames, columnNames)...)

return //nolint:gosimple
}

//nolint:funlen
func generateASTColumnMethods(structName string, prefixGlobal string, prefixColumn string, fieldNames, columnNames []string) []ast.Decl {
func generateASTColumnMethods(structName string, methodNameColumns string, prefixColumn string, fieldNames, columnNames []string) []ast.Decl {
decls := make([]ast.Decl, 0)

// all column names method
Expand Down Expand Up @@ -212,7 +212,7 @@ func generateASTColumnMethods(structName string, prefixGlobal string, prefixColu
},
},
Name: &ast.Ident{
Name: prefixGlobal + "ColumnNames",
Name: methodNameColumns,
},
Type: &ast.FuncType{
Params: &ast.FieldList{},
Expand Down Expand Up @@ -264,7 +264,7 @@ func generateASTColumnMethods(structName string, prefixGlobal string, prefixColu
},
},
Name: &ast.Ident{
Name: prefixGlobal + prefixColumn + fieldNames[i],
Name: prefixColumn + fieldNames[i],
},
Type: &ast.FuncType{
Params: &ast.FieldList{},
Expand Down
20 changes: 15 additions & 5 deletions internal/arcgen/lang/go/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ func TestGenerate(t *testing.T) {
ctx := contexts.WithArgs(context.Background(), []string{
"ddlgen",
"--column-tag-go=dbtest",
"--method-name-table=Get",
"--method-name-table=GetTableName",
"--method-name-columns=GetColumnNames",
"--method-prefix-column=GetColumnName_",
// "--src=tests/common.source",
"--src=tests",
})
Expand Down Expand Up @@ -58,7 +60,9 @@ func TestGenerate(t *testing.T) {
ctx := contexts.WithArgs(context.Background(), []string{
"ddlgen",
"--column-tag-go=dbtest",
"--method-name-table=Get",
"--method-name-table=GetTableName",
"--method-name-columns=GetColumnNames",
"--method-prefix-column=GetColumnName_",
"--src=tests/no.errsource",
})

Expand All @@ -76,7 +80,9 @@ func TestGenerate(t *testing.T) {
ctx := contexts.WithArgs(context.Background(), []string{
"ddlgen",
"--column-tag-go=dbtest",
"--method-name-table=Get",
"--method-name-table=GetTableName",
"--method-name-columns=GetColumnNames",
"--method-prefix-column=GetColumnName_",
"--src=tests",
})

Expand All @@ -94,7 +100,9 @@ func TestGenerate(t *testing.T) {
ctx := contexts.WithArgs(context.Background(), []string{
"ddlgen",
"--column-tag-go=dbtest",
"--method-name-table=Get",
"--method-name-table=GetTableName",
"--method-name-columns=GetColumnNames",
"--method-prefix-column=GetColumnName_",
"--src=tests/no-such-file-or-directory",
})

Expand All @@ -112,7 +120,9 @@ func TestGenerate(t *testing.T) {
ctx := contexts.WithArgs(context.Background(), []string{
"ddlgen",
"--column-tag-go=dbtest",
"--method-name-table=Get",
"--method-name-table=GetTableName",
"--method-name-columns=GetColumnNames",
"--method-prefix-column=GetColumnName_",
"--src=tests/directory.dir",
})

Expand Down
60 changes: 25 additions & 35 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"sync"
"time"

errorz "github.com/kunitsucom/util.go/errors"
cliz "github.com/kunitsucom/util.go/exp/cli"
Expand All @@ -17,16 +16,16 @@ import (
//
//nolint:tagliatelle
type config struct {
Version bool `json:"version"`
Trace bool `json:"trace"`
Debug bool `json:"debug"`
Timestamp string `json:"timestamp"`
Language string `json:"language"`
Source string `json:"source"`
Version bool `json:"version"`
Trace bool `json:"trace"`
Debug bool `json:"debug"`
Language string `json:"language"`
Source string `json:"source"`
// Golang
ColumnTagGo string `json:"column_tag_go"`
MethodPrefixColumn string `json:"column_method_prefix"`
MethodNameTable string `json:"method_table_name"`
MethodNameTable string `json:"method_name_table"`
MethodNameColumns string `json:"method_name_columns"`
MethodPrefixColumn string `json:"method_prefix_column"`
}

//nolint:gochecknoglobals
Expand Down Expand Up @@ -74,18 +73,12 @@ const (
_OptionDebug = "debug"
_EnvKeyDebug = "ARCGEN_DEBUG"

_OptionTimestamp = "timestamp"
_EnvKeyTimestamp = "ARCGEN_TIMESTAMP"

_OptionLanguage = "lang"
_EnvKeyLanguage = "ARCGEN_LANGUAGE"

_OptionSource = "src"
_EnvKeySource = "ARCGEN_SOURCE"

_OptionDestination = "dst"
_EnvKeyDestination = "ARCGEN_DESTINATION"

// Golang

_OptionColumnTagGo = "column-tag-go"
Expand All @@ -94,6 +87,9 @@ const (
_OptionMethodNameTable = "method-name-table"
_EnvKeyMethodNameTable = "ARCGEN_METHOD_NAME_TABLE"

_OptionMethodNameColumns = "method-name-columns"
_EnvKeyMethodNameColumns = "ARCGEN_METHOD_NAME_COLUMNS"

_OptionMethodPrefixColumn = "method-prefix-column"
_EnvKeyMethodPrefixColumn = "ARCGEN_METHOD_PREFIX_COLUMN"
)
Expand All @@ -103,8 +99,8 @@ const (
//nolint:funlen
func load(ctx context.Context) (cfg *config, err error) { //nolint:unparam
cmd := &cliz.Command{
Name: "ARCgen",
Description: "Generate DDL from annotated source code.",
Name: "arcgen",
Description: "Generate methods that return information such as DB table names and column names from Go struct tags.",
Options: []cliz.Option{
&cliz.BoolOption{
Name: _OptionVersion,
Expand All @@ -123,12 +119,6 @@ func load(ctx context.Context) (cfg *config, err error) { //nolint:unparam
Description: "debug mode",
Default: cliz.Default(false),
},
&cliz.StringOption{
Name: _OptionTimestamp,
Environment: _EnvKeyTimestamp,
Description: "code generation timestamp",
Default: cliz.Default(time.Now().Format(time.RFC3339)),
},
&cliz.StringOption{
Name: _OptionLanguage,
Environment: _EnvKeyLanguage,
Expand All @@ -141,12 +131,6 @@ func load(ctx context.Context) (cfg *config, err error) { //nolint:unparam
Description: "source file or directory",
Default: cliz.Default("/dev/stdin"),
},
&cliz.StringOption{
Name: _OptionDestination,
Environment: _EnvKeyDestination,
Description: "destination file or directory",
Default: cliz.Default("/dev/stdout"),
},
// Golang
&cliz.StringOption{
Name: _OptionColumnTagGo,
Expand All @@ -160,6 +144,12 @@ func load(ctx context.Context) (cfg *config, err error) { //nolint:unparam
Description: "method name for table",
Default: cliz.Default("TableName"),
},
&cliz.StringOption{
Name: _OptionMethodNameColumns,
Environment: _EnvKeyMethodNameColumns,
Description: "method name for columns",
Default: cliz.Default("ColumnNames"),
},
&cliz.StringOption{
Name: _OptionMethodPrefixColumn,
Environment: _EnvKeyMethodPrefixColumn,
Expand All @@ -174,15 +164,15 @@ func load(ctx context.Context) (cfg *config, err error) { //nolint:unparam
}

c := &config{
Version: loadVersion(ctx, cmd),
Trace: loadTrace(ctx, cmd),
Debug: loadDebug(ctx, cmd),
Timestamp: loadTimestamp(ctx, cmd),
Language: loadLanguage(ctx, cmd),
Source: loadSource(ctx, cmd),
Version: loadVersion(ctx, cmd),
Trace: loadTrace(ctx, cmd),
Debug: loadDebug(ctx, cmd),
Language: loadLanguage(ctx, cmd),
Source: loadSource(ctx, cmd),
// Golang
ColumnTagGo: loadColumnTagGo(ctx, cmd),
MethodNameTable: loadMethodNameTable(ctx, cmd),
MethodNameColumns: loadMethodNameColumns(ctx, cmd),
MethodPrefixColumn: loadMethodPrefixColumn(ctx, cmd),
}

Expand Down
Loading
Loading