Skip to content

Commit

Permalink
feat: Initial implementation for structs and type aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
armsnyder committed Jul 1, 2024
1 parent 244c181 commit d360391
Show file tree
Hide file tree
Showing 25 changed files with 800 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/.release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
17 changes: 17 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/dependabot-2.0.json
version: 2
updates:
- directory: /
package-ecosystem: gomod
schedule:
interval: monthly
commit-message:
prefix: chore
include: scope
- directory: /
package-ecosystem: github-actions
schedule:
interval: monthly
commit-message:
prefix: chore
include: scope
10 changes: 10 additions & 0 deletions .github/release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"packages": {
".": {
"release-type": "go",
"bump-minor-pre-major": true,
"include-v-in-tag": true
}
}
}
42 changes: 42 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow

on:
push:
branches:
- main
pull_request: {}
workflow_dispatch: {}

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ["1.20", "1.21", "1.22"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- run: go test -cover ./...

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: golangci/golangci-lint-action@v6
with:
version: v1.59.1

release-please:
runs-on: ubuntu-latest
needs: [test, lint]
if: github.ref == 'refs/heads/main'
steps:
- uses: googleapis/release-please-action@v4
id: release-please
with:
token: ${{ secrets.PAT }}
config-file: .github/release-please-config.json
manifest-file: .github/.release-please-manifest.json
120 changes: 120 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# See https://golangci-lint.run/usage/configuration/

linters:
disable-all: true
enable:
# See https://golangci-lint.run/usage/linters/
- asasalint # Check for pass []any as any in variadic func(...any).
- bodyclose # Checks whether HTTP response body is closed successfully.
- contextcheck # Check whether the function uses a non-inherited context.
- durationcheck # Check for two durations multiplied together.
- errcheck # Checks whether Rows.Err of rows is checked successfully.
- errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omitted.
- errorlint # Errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
- forbidigo # Forbids identifiers.
- gci # Gci controls Go package import order and makes it always deterministic.
- gocritic # Provides diagnostics that check for bugs, performance and style issues. Extensible without recompilation through dynamic rules. Dynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion.
- godot # Check if comments end in a period.
- gosec # Inspects source code for security problems.
- gosimple # Linter for Go source code that specializes in simplifying code.
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string.
- inamedparam # Reports interfaces with unnamed method parameters.
- ineffassign # Detects when assignments to existing variables are not used.
- mirror # Reports wrong mirror patterns of bytes/strings usage.
- misspell # Finds commonly misspelled English words.
- musttag # Enforce field tags in (un)marshaled structs.
- nilerr # Finds the code that returns nil even if it checks that the error is not nil.
- nilnil # Checks that there is no simultaneous return of nil error and an invalid value.
- noctx # Finds sending http request without context.Context.
- nolintlint # Reports ill-formed or insufficient nolint directives.
- nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL.
- perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative.
- protogetter # Reports direct reads from proto message fields when getters should be used.
- reassign # Checks that package variables are not reassigned.
- revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.
- staticcheck # It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint.
- tenv # # Tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17.
- unconvert # Remove unnecessary type conversions.
- unused # Checks Go code for unused constants, variables, functions and types.

linters-settings:
# See https://golangci-lint.run/usage/linters/#linters-configuration
forbidigo:
forbid:
- 'fmt\.Print.*' # Should be using a logger
gci:
sections:
- standard
- default
- prefix(github.com/armsnyder)
gocritic:
enabled-tags:
- performance
- opinionated
- experimental
disabled-checks:
- whyNoLint # False positives, use nolintlint instead
govet:
enable-all: true
disable:
- fieldalignment # Too struct
nolintlint:
require-specific: true
revive:
enable-all-rules: true
rules:
# See https://revive.run/r
- name: add-constant # too strict
disabled: true
- name: argument-limit # too strict
disabled: true
- name: cognitive-complexity
arguments:
- 30
- name: cyclomatic
arguments:
- 30
- name: file-header # too strict
disabled: true
- name: function-length
arguments:
- 50 # statements
- 0 # lines (0 to disable)
- name: function-result-limit # too strict
disabled: true
- name: import-shadowing # too strict, results in uglier code
disabled: true
- name: line-length-limit # too strict
disabled: true
- name: max-public-structs # too strict
disabled: true
- name: modifies-parameter # too strict
disabled: true
- name: modifies-value-receiver # too strict
disabled: true
- name: nested-structs # too strict
disabled: true
- name: package-comments # too strict
disabled: true
- name: unhandled-error
disabled: true # not as good as errcheck

issues:
exclude-rules:
- path: _test\.go$
linters:
- gosec # too strict
- noctx # too strict
- path: _test\.go$
text: (cognitive-complexity|function-length|dot-imports|import-alias-naming) # too strict
linters:
- revive
# Shadowing err is common.
- text: 'shadow: declaration of "err"'
linters:
- govet
- text: "^exported:.+stutters" # too strict and gets in the way of combining types like handlers
linters:
- revive
- path: _test\.go$
text: "unused-parameter" # too strict
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Adam Snyder

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Typescript To Golang

This library can be used to convert TypeScript type definitions into Golang
type definitions.
5 changes: 5 additions & 0 deletions cmd/ts2go/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

func main() {
panic("not implemented")
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/armsnyder/ts2go

go 1.22.4

require github.com/armsnyder/typescript-ast-go v0.1.0 // indirect
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/armsnyder/typescript-ast-go v0.0.0-20240701013106-3fe20f2ce05c h1:3NaOBoBqWCjmQGOA1G2WpOQx830K3q/oNDW5NjyCpso=
github.com/armsnyder/typescript-ast-go v0.0.0-20240701013106-3fe20f2ce05c/go.mod h1:g+d4M+jObtdnAC7tysKlYcVpaAw26uVWD+Nxip5dqrg=
github.com/armsnyder/typescript-ast-go v0.1.0 h1:u0VVgRbkviKteBMjL7cQhYeNkfwZFq/HV0EsCZGBxkY=
github.com/armsnyder/typescript-ast-go v0.1.0/go.mod h1:Ekm32kIHighHhBImp32z2XoaQnkZqh/TDiJNlBXTaq0=
3 changes: 3 additions & 0 deletions internal/templates/const_group.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const (
Foo = "bar"
)
3 changes: 3 additions & 0 deletions internal/templates/header.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Code generated by ts2go. DO NOT EDIT.
package {{ .PackageName }}

15 changes: 15 additions & 0 deletions internal/templates/output.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- if not .SkipHeader -}}
{{- template "header.tmpl" . -}}
{{- end -}}

{{- range .ConstGroups -}}
{{- template "const_group.tmpl" . -}}
{{- end -}}

{{- range .TypeAliases -}}
{{- template "type_alias.tmpl" . -}}
{{- end -}}

{{- range .Structs -}}
{{- template "struct.tmpl" . -}}
{{- end -}}
14 changes: 14 additions & 0 deletions internal/templates/struct.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{ range .Doc -}}
// {{ . }}
{{ end -}}
type {{ .Name }} struct {
{{ range .Embeds -}}
{{ . }}
{{ end -}}
{{ range .Fields -}}
{{ range .Doc -}}
// {{ . }}
{{ end -}}
{{ .Name }} {{ if .IsPointer }}*{{ end }}{{ .Type }} `json:"{{ .JSONName }}{{ if .OmitEmpty }},omitempty{{ end }}"`
{{- end }}
}
4 changes: 4 additions & 0 deletions internal/templates/type_alias.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{ range .Doc -}}
// {{ . }}
{{ end -}}
type {{ .Name }} {{ .Type }}
8 changes: 8 additions & 0 deletions internal/testdata/basic_interface/expected.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions internal/testdata/basic_interface/source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// An RPC message.
interface Message {
// The message text.
text: string;
}
5 changes: 5 additions & 0 deletions internal/testdata/basic_type_alias/expected.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions internal/testdata/basic_type_alias/source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// A document uri.
type DocumentUri = string;
34 changes: 34 additions & 0 deletions mixin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ts2go

// Mixin is used to modify or add custom data to the [TemplateData] before it
// is rendered.
type Mixin func(*TemplateData)

// SkipOptionalPointer specifies that optional fields should not be
// represented as pointers in the generated Go code.
func SkipOptionalPointer() Mixin {
return func(data *TemplateData) {
for _, s := range data.Structs {
for _, f := range s.Fields {
f.IsPointer = false
}
}
}
}

// SkipHeader specifies that the generated Go code should not include the
// header comment and package declaration. This is useful if you want to run
// [Generate] more than once and concatenate the results.
func SkipHeader() Mixin {
return func(data *TemplateData) {
data.SkipHeader = true
}
}

// SetPackageName specifies the package name that should be used in the
// generated Golang code. If not specified, [DefaultPackageName] is used.
func SetPackageName(name string) Mixin {
return func(data *TemplateData) {
data.PackageName = name
}
}
36 changes: 36 additions & 0 deletions option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ts2go

import (
"io/fs"
"os"
)

// Option customizes the behavior of [Generate].
type Option func(*generator)

// WithMixin specifies one or more [Mixin]s to customize the data that is
// passed to the templates.
func WithMixin(mixins ...Mixin) Option {
return func(g *generator) {
g.mixins = append(g.mixins, mixins...)
}
}

// WithTemplateOverrideDir specifies a directory which can contain template
// overrides.
//
// You may override as many or as few templates as you like. This is useful in
// conjunction with mixins. You can add custom data to the parsed types, and
// then reference that custom data inside your template override. See the
// templates directory for the list of templates that can be overridden.
func WithTemplateOverrideDir(dir string) Option {
return WithTemplateOverrideFS(os.DirFS(dir))
}

// WithTemplateOverrideFS is the same as [WithTemplateOverrideDir], but takes a
// file system interface instead of a directory.
func WithTemplateOverrideFS(fsys fs.FS) Option {
return func(g *generator) {
g.templateOverrideFS = fsys
}
}
Loading

0 comments on commit d360391

Please sign in to comment.