diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9cc652d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,37 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: Bug +--- + +## Describe the bug + +A clear and concise description of what the bug is. + +## To Reproduce + +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +## Expected behavior + +A clear and concise description of what you expected to happen. + +## Screenshots + +If applicable, add screenshots to help explain your problem. + +## Application + +Please complete the following information: + +- badaas version [X.X.X] or commit hash + +## Additional context + +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/user_story.md b/.github/ISSUE_TEMPLATE/user_story.md new file mode 100644 index 0000000..1112fab --- /dev/null +++ b/.github/ISSUE_TEMPLATE/user_story.md @@ -0,0 +1,39 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: User Story, To be verify +--- + +## Description + +**As a** `[roles impacted]`, + +**I want** `[clear context and goals]` + +**so that** `[result of this story]`. + +## Acceptance Criteria + + **Scenario** | `[the name for the behavior that will be described]` + ------------ | ------------------------------------------------- + **Given** | `[the beginning state of the scenario]` + **When** | `[specific action that the user makes]` + **Then** | `[the outcome of the action in “When”]` + **And** | `[used to continue any of three previous statements]` + +### Constraints + +`[Put all others constraints here, like list of acceptances values or other]` + +## Resources + +`[Put all your resources here, like mockups, diagrams or other here]` + +## Notes + +`[Some complementary notes if necessary]` + +## Links + +`[Only use by the team, to link this feature with epic, technical tasks or bugs]` diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..fbb06c0 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1 @@ +:information_source: Don't forget to modify the changelog.md before merging this branch. \ No newline at end of file diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..0905aed --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,78 @@ +name: CI +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] + +jobs: + branch-naming-rules: + name: Check branch name + runs-on: ubuntu-latest + steps: + - uses: deepakputhraya/action-branch-name@master + with: + regex: '^(feature|bugfix|improvement|library|prerelease|release|hotfix|poc)\/[a-z0-9_.-]+$' + allowed_prefixes: 'feature,bugfix,improvement,library,prerelease,release,hotfix,poc' + ignore: main,dev + min_length: 5 + max_length: 50 + + check-style: + name: Code style + needs: [branch-naming-rules] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-go@v3 + with: + go-version: '^1.18' + cache: true + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: v1.52.2 + skip-cache: true + skip-pkg-cache: true + skip-build-cache: true + + unit-tests: + name: Unit tests + needs: [branch-naming-rules] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-go@v3 + with: + go-version: '^1.18' + cache: true + - name: Run unit tests + run: go test ./... -coverprofile=coverage_unit.out -v + - uses: actions/upload-artifact@v3 + with: + name: coverage_unit + path: coverage_unit.out + + sonarcloud: + name: SonarCloud + needs: [unit-tests, check-style] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Download unit tests line coverage report + uses: actions/download-artifact@v3 + with: + name: coverage_unit + path: coverage_unit.out + - name: SonarCloud Scan + uses: sonarsource/sonarcloud-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b927af --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +vendor/ + +# Go workspace file +go.work + +# vscode conf +.vscode + +# binary output +badaas-cli + +# test results +cmd/gen/conditions/*_conditions.go \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..d470509 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,271 @@ +# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY +# +# The original version of this file is located in the https://github.com/istio/common-files repo. +# If you're looking at this file in a different repo and want to make a change, please go to the +# common-files repo, make the change there and check it in. Then come back to this repo and run +# "make update-common". + +output: + # Format: colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions + # + # Multiple can be specified by separating them by comma, output can be provided + # for each of them by separating format name and path by colon symbol. + # Output path can be either `stdout`, `stderr` or path to the file to write to. + # Example: "checkstyle:report.json,colored-line-number" + # + # Default: colored-line-number + format: github-actions + # Print lines of code with issue. + # Default: true + print-issued-lines: false + # Print linter name in the end of issue text. + # Default: true + print-linter-name: false + # Make issues output unique by line. + # Default: true + uniq-by-line: false + # Add a prefix to the output file references. + # Default is no prefix. + path-prefix: "" + # Sort results by: filepath, line and column. + sort-results: false + +run: + tests: false + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 20m + build-tags: + - integ + - integfuzz + # which dirs to skip: they won't be analyzed; + # can use regexp here: generated.*, regexp is applied on full path; + # default value is empty list, but next dirs are always skipped independently + # from this option's value: + #vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + skip-dirs: + - genfiles$ + - vendor$ + + # which files to skip: they will be analyzed, but issues from them + # won't be reported. Default value is empty list, but there is + # no need to include all autogenerated files, we confidently recognize + # autogenerated files. If it's not please let us know. + skip-files: + - ".*\\.pb\\.go" + - ".*\\.gen\\.go" + +linters: + disable-all: true + enable: + - deadcode + - exportloopref + - gocritic + - revive + - gosimple + - govet + - ineffassign + - lll + - misspell + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - varcheck + fast: false + +linters-settings: + govet: + # report about shadowed variables + check-shadowing: false + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: US + ignore-words: + - cancelled + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 160 + # tab width in spaces. Default to 1. + tab-width: 1 + revive: + ignore-generated-header: false + severity: "warning" + confidence: 0.0 + error-code: 2 + warning-code: 1 + rules: + - name: blank-imports + - name: context-keys-type + - name: time-naming + - name: var-declaration + - name: unexported-return + - name: errorf + - name: context-as-argument + - name: dot-imports + - name: error-return + - name: error-strings + - name: error-naming + - name: increment-decrement + - name: var-naming + - name: package-comments + - name: range + - name: receiver-naming + - name: indent-error-flow + - name: superfluous-else + - name: modifies-parameter + - name: unreachable-code + - name: struct-tag + - name: constant-logical-expr + - name: bool-literal-in-expr + - name: redefines-builtin-id + - name: imports-blacklist + - name: range-val-in-closure + - name: range-val-address + - name: waitgroup-by-value + - name: atomic + - name: call-to-gc + - name: duplicated-imports + - name: string-of-int + - name: defer + arguments: [["call-chain"]] + - name: unconditional-recursion + - name: identical-branches + # the following rules can be enabled in the future + # - name: empty-lines + # - name: confusing-results + # - name: empty-block + # - name: get-return + # - name: confusing-naming + # - name: unexported-naming + - name: early-return + # - name: unused-parameter + # - name: unnecessary-stmt + # - name: deep-exit + # - name: import-shadowing + # - name: modifies-value-receiver + # - name: unused-receiver + # - name: bare-return + # - name: flag-parameter + # - name: unhandled-error + # - name: if-return + unused: + # treat code as a program (not a library) and report unused exported identifiers; default is false. + # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find funcs usages. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + unparam: + # call graph construction algorithm (cha, rta). In general, use cha for libraries, + # and rta for programs with main packages. Default is cha. + algo: rta + + # Inspect exported functions, default is false. Set to true if no external program/library imports your code. + # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find external interfaces. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + gocritic: + enabled-checks: + - appendCombine + - argOrder + - assignOp + - badCond + - boolExprSimplify + - builtinShadow + - captLocal + - caseOrder + - codegenComment + - commentedOutCode + - commentedOutImport + - defaultCaseOrder + - deprecatedComment + - docStub + - dupArg + - dupBranchBody + - dupCase + - dupSubExpr + - elseif + - emptyFallthrough + - equalFold + - flagDeref + - flagName + - hexLiteral + - indexAlloc + - initClause + - methodExprCall + - nilValReturn + - octalLiteral + - offBy1 + - rangeExprCopy + - regexpMust + - sloppyLen + - stringXbytes + - switchTrue + - typeAssertChain + - typeSwitchVar + - typeUnparen + - underef + - unlambda + - unnecessaryBlock + - unslice + - valSwap + - weakCond + + # Unused + # - yodaStyleExpr + # - appendAssign + # - commentFormatting + # - emptyStringTest + # - exitAfterDefer + # - ifElseChain + # - hugeParam + # - importShadow + # - nestingReduce + # - paramTypeCombine + # - ptrToRefParam + # - rangeValCopy + # - singleCaseSwitch + # - sloppyReassign + # - unlabelStmt + # - unnamedResult + # - wrapperFunc + +issues: + # List of regexps of issue texts to exclude, empty list by default. + # But independently from this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. To list all + # excluded by default patterns execute `golangci-lint run --help` + exclude: + - composite literal uses unkeyed fields + + exclude-rules: + # Exclude some linters from running on test files. + - path: _test\.go$|^tests/|^samples/ + linters: + - errcheck + - maligned + + # TODO(https://github.com/dominikh/go-tools/issues/732) remove this once we update + - linters: + - staticcheck + text: "SA1019: package github.com/golang/protobuf" + + # Independently from option `exclude` we use default exclude patterns, + # it can be disabled by this option. To list all + # excluded by default patterns execute `golangci-lint run --help`. + # Default value for this option is true. + exclude-use-default: true + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..74e762f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,73 @@ +# Contribute to the development of badaas + +- [Local compilation](#local-compilation) +- [Tests](#tests) + - [Unit tests](#unit-tests) +- [Git](#git) + - [Branch naming policy](#branch-naming-policy) + - [Default branch](#default-branch) + - [How to release](#how-to-release) + +## Local compilation + +You can make modifications to the badaas-cli source code and compile it locally with: + +```bash +go build . +``` + +You can then run the badaas-cli executable directly or add a link in your $GOPATH to run it from a project: + +```bash +ln -sf badaas-cli $GOPATH/bin/badaas-cli +``` + +## Tests + +### Unit tests + +We use the standard test suite in combination with [github.com/stretchr/testify](https://github.com/stretchr/testify) to do our unit testing. + +To run them, please run: + +```sh +make test_unit +``` + +## Git + +### Branch naming policy + +`[BRANCH_TYPE]/[BRANCH_NAME]` + +- `BRANCH_TYPE` is a prefix to describe the purpose of the branch. + Accepted prefixes are: + - `feature`, used for feature development + - `bugfix`, used for bug fix + - `improvement`, used for refactor + - `library`, used for updating library + - `prerelease`, used for preparing the branch for the release + - `release`, used for releasing project + - `hotfix`, used for applying a hotfix on main + - `poc`, used for proof of concept +- `BRANCH_NAME` is managed by this regex: `[a-z0-9._-]` (`_` is used as space character). + +### Default branch + +The default branch is `main`. Direct commit on it is forbidden. The only way to update the application is through pull request. + +Release tag are only done on the `main` branch. + +### How to release + +We use [Semantic Versioning](https://semver.org/spec/v2.0.0.html) as guideline for the version management. + +Steps to release: + +- Create a new branch labeled `release/vX.Y.Z` from the latest `main`. +- Improve the version number in `changelog.md`. +- Verify the content of the `changelog.md`. +- Commit the modifications with the label `Release version X.Y.Z`. +- Create a pull request on github for this branch into `main`. +- Once the pull request validated and merged, tag the `main` branch with `vX.Y.Z`. +- After the tag is pushed, make the release on the tag in GitHub. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e65468f --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +lint: + golangci-lint run + +test_unit: + go test ./... -v + +.PHONY: test_unit \ No newline at end of file diff --git a/README.md b/README.md index 0b83cad..e933bcb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,84 @@ -# badaas-cli -Command line tools to generate the files required to run a badaas application +# badaas-cli + +`badaas-cli` is the command line tool that makes it possible to configure and run a badaas application. + +- [Install with go install](#install-with-go-install) +- [Build from sources](#build-from-sources) +- [Commands](#commands) + - [badaas-cli gen docker](#badaas-cli-gen-docker) + - [badaas-cli gen conditions](#badaas-cli-gen-conditions) +- [Contributing](#contributing) +- [License](#license) + +## Install with go install + +For simply installing it, use: + +```bash +go install github.com/ditrit/badaas-cli +``` + +Or you can build it from sources. + +## Build from sources + +Get the sources of the project, either by visiting the [releases](https://github.com/ditrit/badaas/releases) page and downloading an archive or clone the main branch (please be aware that is it not a stable version). + +To build the project: + +- [Install go](https://go.dev/dl/#go1.18.4) v1.18 +- Install project dependencies + + ```bash + go get + ``` + +- Run build command + + ```bash + go build . + ``` + +Well done, you have a binary `badaas-cli` at the root of the project. + +## Commands + +You can see the available commands by running: + +```bash +badaas-cli help +``` + +For more information about the functionality provided and how to use each command use: + +```bash +badaas-cli help [command] +``` + +### badaas-cli gen docker + +gen docker is the command you can use to generate the files and configurations necessary for your project to use badaas in a simple way. + +`gen docker` will generate the docker and configuration files needed to run the application in the `badaas/docker` and `badaas/config` folders respectively. + +All these files can be modified in case you need different values than those provided by default. For more information about the configuration head to [configuration docs](github.com/ditrit/badaas/configuration.md). + +A Makefile will be generated for the execution of a badaas server, with the command: + +```bash +make badaas_run +``` + +### badaas-cli gen conditions + +gen conditions is the command you can use to generate conditions to query your objects using badaas-orm. For each BaDaaS Model found in the input packages a file containing all possible Conditions on that object will be generated, allowing you to use badaas-orm. + +Its use is recommended through `go generate`. To see an example of how to do it click [here](https://github.com/ditrit/badaa-orm-example/blob/main/standalone/conditions/orm.go). + +## Contributing + +See [this section](./CONTRIBUTING.md). + +## License + +badaas-cli is Licensed under the [Mozilla Public License Version 2.0](./LICENSE). diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..53a520c --- /dev/null +++ b/changelog.md @@ -0,0 +1,15 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) + +## [Unreleased] + +### Added + +- Add generation of docker and configuration files +- Add gen conditions to generate the conditions for the badaas' compilable query system. + +[unreleased]: https://github.com/ditrit/badaas-cli/blob/main/changelog.md#unreleased \ No newline at end of file diff --git a/cmd/gen/conditions/condition.go b/cmd/gen/conditions/condition.go new file mode 100644 index 0000000..5c57391 --- /dev/null +++ b/cmd/gen/conditions/condition.go @@ -0,0 +1,283 @@ +package conditions + +import ( + "go/types" + + "github.com/dave/jennifer/jen" + "github.com/ditrit/badaas-cli/cmd/log" + "github.com/ettle/strcase" +) + +const ( + // badaas/orm/condition.go + badaasORMCondition = "Condition" + badaasORMWhereCondition = "WhereCondition" + badaasORMJoinCondition = "JoinCondition" +) + +type Condition struct { + codes []jen.Code + param *JenParam + destPkg string +} + +func NewCondition(destPkg string, objectType Type, field Field) *Condition { + condition := &Condition{ + param: NewJenParam(), + destPkg: destPkg, + } + condition.generate(objectType, field) + return condition +} + +// Generate the condition between the object and the field +func (condition *Condition) generate(objectType Type, field Field) { + switch fieldType := field.Type.Type.(type) { + case *types.Basic: + // the field is a basic type (string, int, etc) + // adapt param to that type and generate a WhereCondition + condition.param.ToBasicKind(fieldType) + condition.generateWhere( + objectType, + field, + ) + case *types.Named: + // the field is a named type (user defined structs) + condition.generateForNamedType( + objectType, + field, + ) + case *types.Pointer: + // the field is a pointer + condition.generate( + objectType, + field.ChangeType(fieldType.Elem()), + ) + case *types.Slice: + // the field is a slice + // adapt param to slice and + // generate code for the type of the elements of the slice + condition.param.ToSlice() + condition.generateForSlice( + objectType, + field.ChangeType(fieldType.Elem()), + ) + default: + log.Logger.Debugf("struct field type not handled: %T", fieldType) + } +} + +// Generate condition between the object and the field when the field is a slice +func (condition *Condition) generateForSlice(objectType Type, field Field) { + switch elemType := field.Type.Type.(type) { + case *types.Basic: + // slice of basic types ([]string, []int, etc.) + // the only one supported directly by gorm is []byte + // but the others can be used after configuration in some dbs + condition.generate( + objectType, + field, + ) + case *types.Named: + // slice of named types (user defined types) + _, err := field.Type.BadaasModelStruct() + if err == nil { + // slice of Badaas models -> hasMany relation + condition.generateInverseJoin( + objectType, + field, + ) + } + case *types.Pointer: + // slice of pointers, generate code for a slice of the pointed type + condition.generateForSlice( + objectType, + field.ChangeType(elemType.Elem()), + ) + default: + log.Logger.Debugf("struct field list elem type not handled: %T", elemType) + } +} + +// Generate condition between object and field when the field is a named type (user defined struct) +func (condition *Condition) generateForNamedType(objectType Type, field Field) { + _, err := field.Type.BadaasModelStruct() + + if err == nil { + // field is a Badaas Model + hasFK, _ := objectType.HasFK(field) + if hasFK { + // belongsTo relation + condition.generateJoinWithFK( + objectType, + field, + ) + } else { + // hasOne relation + condition.generateJoinWithoutFK( + objectType, + field, + ) + + condition.generateInverseJoin( + objectType, + field, + ) + } + } else { + // field is not a Badaas Model + if field.Type.IsGormCustomType() || field.TypeString() == "time.Time" { + // field is a Gorm Custom type (implements Scanner and Valuer interfaces) + // or a named type supported by gorm (time.Time, gorm.DeletedAt) + condition.param.ToCustomType(condition.destPkg, field.Type) + condition.generateWhere( + objectType, + field, + ) + } else { + log.Logger.Debugf("struct field type not handled: %s", field.TypeString()) + } + } +} + +// Generate a WhereCondition between object and field +func (condition *Condition) generateWhere(objectType Type, field Field) { + whereCondition := jen.Qual( + badaasORMPath, badaasORMWhereCondition, + ).Types( + jen.Qual( + getRelativePackagePath(condition.destPkg, objectType), + objectType.Name(), + ), + ) + + conditionName := getConditionName(objectType, field) + log.Logger.Debugf("Generated %q", conditionName) + + params := jen.Dict{ + jen.Id("Value"): jen.Id("v"), + } + columnName := field.getColumnName() + if columnName != "" { + params[jen.Id("Column")] = jen.Lit(columnName) + } else { + params[jen.Id("Field")] = jen.Lit(field.Name) + } + + columnPrefix := field.ColumnPrefix + if columnPrefix != "" { + params[jen.Id("ColumnPrefix")] = jen.Lit(columnPrefix) + } + + condition.codes = append( + condition.codes, + jen.Func().Id( + conditionName, + ).Params( + condition.param.Statement(), + ).Add( + whereCondition.Clone(), + ).Block( + jen.Return( + whereCondition.Clone().Values(params), + ), + ), + ) +} + +// Generate a inverse JoinCondition, so from the field's object to the object +func (condition *Condition) generateInverseJoin(objectType Type, field Field) { + condition.generateJoinWithFK( + field.Type, + Field{ + Name: objectType.Name(), + Type: objectType, + Tags: field.Tags, + }, + ) +} + +// Generate a JoinCondition between the object and field's object +// when object has a foreign key to the field's object +func (condition *Condition) generateJoinWithFK(objectType Type, field Field) { + condition.generateJoin( + objectType, + field, + field.getFKAttribute(), + field.getFKReferencesAttribute(), + ) +} + +// Generate a JoinCondition between the object and field's object +// when object has not a foreign key to the field's object +// (so the field's object has it) +func (condition *Condition) generateJoinWithoutFK(objectType Type, field Field) { + condition.generateJoin( + objectType, + field, + field.getFKReferencesAttribute(), + field.getRelatedTypeFKAttribute(objectType.Name()), + ) +} + +// Generate a JoinCondition +func (condition *Condition) generateJoin(objectType Type, field Field, t1Field, t2Field string) { + t1 := jen.Qual( + getRelativePackagePath(condition.destPkg, objectType), + objectType.Name(), + ) + + t2 := jen.Qual( + getRelativePackagePath(condition.destPkg, field.Type), + field.TypeName(), + ) + + conditionName := getConditionName(objectType, field) + log.Logger.Debugf("Generated %q", conditionName) + + ormT1Condition := jen.Qual( + badaasORMPath, badaasORMCondition, + ).Types(t1) + ormT2Condition := jen.Qual( + badaasORMPath, badaasORMCondition, + ).Types(t2) + ormJoinCondition := jen.Qual( + badaasORMPath, badaasORMJoinCondition, + ).Types( + t1, t2, + ) + + condition.codes = append( + condition.codes, + jen.Func().Id( + conditionName, + ).Params( + jen.Id("conditions").Op("...").Add(ormT2Condition), + ).Add( + ormT1Condition, + ).Block( + jen.Return( + ormJoinCondition.Values(jen.Dict{ + jen.Id("T1Field"): jen.Lit(t1Field), + jen.Id("T2Field"): jen.Lit(t2Field), + jen.Id("Conditions"): jen.Id("conditions"), + }), + ), + ), + ) +} + +// Generate condition names +func getConditionName(typeV Type, field Field) string { + return typeV.Name() + strcase.ToPascal(field.ColumnPrefix) + strcase.ToPascal(field.Name) +} + +// Avoid importing the same package as the destination one +func getRelativePackagePath(destPkg string, typeV Type) string { + srcPkg := typeV.Pkg() + if srcPkg == nil || srcPkg.Name() == destPkg { + return "" + } + + return srcPkg.Path() +} diff --git a/cmd/gen/conditions/field.go b/cmd/gen/conditions/field.go new file mode 100644 index 0000000..42537a2 --- /dev/null +++ b/cmd/gen/conditions/field.go @@ -0,0 +1,119 @@ +package conditions + +import ( + "errors" + "go/types" +) + +type Field struct { + Name string + Type Type + Embedded bool + Tags GormTags + ColumnPrefix string +} + +// Get the name of the column where the data for a field will be saved +func (field Field) getColumnName() string { + columnTag, isPresent := field.Tags[columnTagName] + if isPresent { + // field has a gorm column tag, so the name of the column will be that tag + return columnTag + } + + return "" +} + +// Get name of the attribute of the object that is a foreign key to the field's object +func (field Field) getFKAttribute() string { + foreignKeyTag, isPresent := field.Tags[foreignKeyTagName] + if isPresent { + // field has a foreign key tag, so the name will be that tag + return foreignKeyTag + } + + // gorm default + return field.Name + "ID" +} + +// Get name of the attribute of the field's object that is references by the foreign key +func (field Field) getFKReferencesAttribute() string { + referencesTag, isPresent := field.Tags[referencesTagName] + if isPresent { + // field has a references tag, so the name will be that tag + return referencesTag + } + + // gorm default + return "ID" +} + +// Get name of the attribute of field's object that is a foreign key to the object +func (field Field) getRelatedTypeFKAttribute(structName string) string { + foreignKeyTag, isPresent := field.Tags[foreignKeyTagName] + if isPresent { + // field has a foreign key tag, so the name will that tag + return foreignKeyTag + } + + // gorm default + return structName + "ID" +} + +// Get field's type full string (pkg + name) +func (field Field) TypeString() string { + return field.Type.String() +} + +// Get field's type name +func (field Field) TypeName() string { + return field.Type.Name() +} + +// Create a new field with the same name and tags but a different type +func (field Field) ChangeType(newType types.Type) Field { + return Field{ + Name: field.Name, + Type: Type{newType}, + Tags: field.Tags, + } +} + +// Get fields of a Badaas model +// Returns error is objectType is not a Badaas model +func getFields(objectType Type, prefix string) ([]Field, error) { + // The underlying type has to be a struct and a Badaas Model + // (ignore const, var, func, etc.) + structType, err := objectType.BadaasModelStruct() + if err != nil { + return nil, err + } + + return getStructFields(structType, prefix) +} + +// Get fields of a struct +// Returns errors if the struct has not fields +func getStructFields(structType *types.Struct, prefix string) ([]Field, error) { + numFields := structType.NumFields() + if numFields == 0 { + return nil, errors.New("struct has 0 fields") + } + + fields := []Field{} + + // Iterate over struct fields + for i := 0; i < numFields; i++ { + fieldObject := structType.Field(i) + gormTags := getGormTags(structType.Tag(i)) + fields = append(fields, Field{ + Name: fieldObject.Name(), + Type: Type{fieldObject.Type()}, + Embedded: fieldObject.Embedded() || gormTags.hasEmbedded(), + Tags: gormTags, + ColumnPrefix: prefix, + }) + } + + return fields, nil +} diff --git a/cmd/gen/conditions/file.go b/cmd/gen/conditions/file.go new file mode 100644 index 0000000..24c2e98 --- /dev/null +++ b/cmd/gen/conditions/file.go @@ -0,0 +1,98 @@ +package conditions + +import ( + "errors" + "go/types" + + "github.com/dave/jennifer/jen" + "github.com/ditrit/badaas-cli/cmd/log" + "github.com/ditrit/badaas-cli/cmd/version" +) + +const badaasORMPath = "github.com/ditrit/badaas/orm" + +type File struct { + destPkg string + jenFile *jen.File + name string +} + +func NewConditionsFile(destPkg string, name string) *File { + // Start a new file in destination package + f := jen.NewFile(destPkg) + + // Add a package comment, so IDEs detect files as generated + f.PackageComment("Code generated by badaas-cli v" + version.Version + ", DO NOT EDIT.") + + return &File{ + destPkg: destPkg, + name: name, + jenFile: f, + } +} + +// Add conditions for an object in the file +func (file File) AddConditionsFor(object types.Object) error { + fields, err := getFields(Type{object.Type()}, "") + if err != nil { + return err + } + + log.Logger.Infof("Generating conditions for type %q in %s", object.Name(), file.name) + + file.addConditionsForEachField(object, fields) + return nil +} + +// Add one condition for each field of the object +func (file File) addConditionsForEachField(object types.Object, fields []Field) { + conditions := file.generateConditionsForEachField(object, fields) + + for _, condition := range conditions { + for _, code := range condition.codes { + file.jenFile.Add(code) + } + } +} + +// Write generated file +func (file File) Save() error { + return file.jenFile.Save(file.name) +} + +// Generate the conditions for each of the object's fields +func (file File) generateConditionsForEachField(object types.Object, fields []Field) []*Condition { + conditions := []*Condition{} + for _, field := range fields { + log.Logger.Debugf("Generating condition for field %q", field.Name) + if field.Embedded { + conditions = append(conditions, file.generateEmbeddedConditions( + object, + field, + )...) + } else { + conditions = append(conditions, NewCondition( + file.destPkg, Type{object.Type()}, field, + )) + } + } + + return conditions +} + +// Generate conditions for a embedded field +// it will generate a condition for each of the field of the embedded field's type +func (file File) generateEmbeddedConditions(object types.Object, field Field) []*Condition { + embeddedStructType, ok := field.Type.Underlying().(*types.Struct) + if !ok { + panic(errors.New("unreachable! embedded objects are always structs")) + } + + fields, err := getStructFields(embeddedStructType, field.Tags.getEmbeddedPrefix()) + if err != nil { + // embedded field's type has not fields + return []*Condition{} + } + + return file.generateConditionsForEachField(object, fields) +} diff --git a/cmd/gen/conditions/gormTag.go b/cmd/gen/conditions/gormTag.go new file mode 100644 index 0000000..6df96aa --- /dev/null +++ b/cmd/gen/conditions/gormTag.go @@ -0,0 +1,60 @@ +package conditions + +import ( + "strings" + + "github.com/fatih/structtag" +) + +type GormTag string + +const ( + embeddedTagName GormTag = "embedded" + embeddedPrefixTagName GormTag = "embeddedPrefix" + columnTagName GormTag = "column" + foreignKeyTagName GormTag = "foreignKey" + referencesTagName GormTag = "references" +) + +type GormTags map[GormTag]string + +func (tags GormTags) getEmbeddedPrefix() string { + embeddedPrefix, isPresent := tags[embeddedPrefixTagName] + if !isPresent { + return "" + } + + return embeddedPrefix +} + +func (tags GormTags) hasEmbedded() bool { + _, isPresent := tags[embeddedTagName] + return isPresent +} + +func getGormTags(tag string) GormTags { + tagMap := GormTags{} + + allTags, err := structtag.Parse(tag) + if err != nil { + return tagMap + } + + gormTag, err := allTags.Get("gorm") + if err != nil { + return tagMap + } + + gormTags := strings.Split(gormTag.Name, ";") + for _, tag := range gormTags { + splitted := strings.Split(tag, ":") + tagName := GormTag(splitted[0]) + if len(splitted) == 1 { + tagMap[tagName] = "" + } else { + tagMap[tagName] = splitted[1] + } + } + + return tagMap +} diff --git a/cmd/gen/conditions/jenParam.go b/cmd/gen/conditions/jenParam.go new file mode 100644 index 0000000..890a0ce --- /dev/null +++ b/cmd/gen/conditions/jenParam.go @@ -0,0 +1,71 @@ +package conditions + +import ( + "go/types" + + "github.com/dave/jennifer/jen" +) + +type JenParam struct { + statement *jen.Statement +} + +func NewJenParam() *JenParam { + return &JenParam{ + statement: jen.Id("v"), + } +} + +func (param JenParam) Statement() *jen.Statement { + return param.statement +} + +func (param JenParam) ToBasicKind(basicType *types.Basic) { + switch basicType.Kind() { + case types.Bool: + param.statement.Bool() + case types.Int: + param.statement.Int() + case types.Int8: + param.statement.Int8() + case types.Int16: + param.statement.Int16() + case types.Int32: + param.statement.Int32() + case types.Int64: + param.statement.Int64() + case types.Uint: + param.statement.Uint() + case types.Uint8: + param.statement.Uint8() + case types.Uint16: + param.statement.Uint16() + case types.Uint32: + param.statement.Uint32() + case types.Uint64: + param.statement.Uint64() + case types.Uintptr: + param.statement.Uintptr() + case types.Float32: + param.statement.Float32() + case types.Float64: + param.statement.Float64() + case types.Complex64: + param.statement.Complex64() + case types.Complex128: + param.statement.Complex128() + case types.String: + param.statement.String() + } +} + +func (param JenParam) ToSlice() { + param.statement.Index() +} + +func (param JenParam) ToCustomType(destPkg string, typeV Type) { + param.statement.Qual( + getRelativePackagePath(destPkg, typeV), + typeV.Name(), + ) +} diff --git a/cmd/gen/conditions/main.go b/cmd/gen/conditions/main.go new file mode 100644 index 0000000..35e7bd7 --- /dev/null +++ b/cmd/gen/conditions/main.go @@ -0,0 +1,115 @@ +package conditions + +import ( + "errors" + "fmt" + "go/types" + "os" + + "github.com/ettle/strcase" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/ditrit/badaas-cli/cmd/log" + "github.com/ditrit/verdeter" + + "golang.org/x/tools/go/packages" +) + +var GenConditionsCmd = verdeter.BuildVerdeterCommand(verdeter.VerdeterConfig{ + Use: "conditions", + Short: "Generate conditions to query your objects using badaas-orm", + Long: `gen is the command you can use to generate the files and configurations necessary for your project to use BadAss in a simple way.`, + Run: generateConditions, + Args: cobra.MinimumNArgs(1), +}) + +const DestPackageKey = "dest_package" + +func init() { + err := GenConditionsCmd.LKey( + DestPackageKey, verdeter.IsStr, "d", + "Destination package (not used if ran with go generate)", + ) + if err != nil { + panic(err) + } +} + +// GenConditionsCmd Run func +func generateConditions(_ *cobra.Command, args []string) { + log.SetLevel() + // Inspect package and use type checker to infer imported types + pkgs := loadPackages(args) + + // Get the package of the file with go:generate comment or in command params + destPkg := os.Getenv("GOPACKAGE") + if destPkg == "" { + destPkg = viper.GetString(DestPackageKey) + if destPkg == "" { + panic(errors.New("config --dest_package or use go generate")) + } + } + + // Generate conditions for each package + for _, pkg := range pkgs { + generateConditionsForPkg(destPkg, pkg) + } +} + +// Generates a file with conditions for each Badaas model in the package +func generateConditionsForPkg(destPkg string, pkg *packages.Package) { + log.Logger.Infof("Generating conditions for types in package %q", pkg.Types.Name()) + + for _, name := range pkg.Types.Scope().Names() { + object := getObject(pkg, name) + if object != nil { + file := NewConditionsFile( + destPkg, + strcase.ToSnake(object.Name())+"_conditions.go", + ) + + err := file.AddConditionsFor(object) + if err != nil { + // object is not a Badaas model, do not generate conditions + continue + } + + err = file.Save() + if err != nil { + panic(err) + } + } + } +} + +// Load package information from paths +func loadPackages(paths []string) []*packages.Package { + cfg := &packages.Config{Mode: packages.NeedTypes} + pkgs, err := packages.Load(cfg, paths...) + if err != nil { + panic(fmt.Errorf("loading packages for inspection: %w", err)) + } + + // print compilation errors of source packages + packages.PrintErrors(pkgs) + + return pkgs +} + +// Get object by name in the package +func getObject(pkg *packages.Package, name string) types.Object { + obj := pkg.Types.Scope().Lookup(name) + if obj == nil { + panic(fmt.Errorf("%s not found in declared types of %s", + name, pkg)) + } + + // Generate only if it is a declared type + object, ok := obj.(*types.TypeName) + if !ok { + return nil + } + + return object +} diff --git a/cmd/gen/conditions/main_test.go b/cmd/gen/conditions/main_test.go new file mode 100644 index 0000000..b3f9823 --- /dev/null +++ b/cmd/gen/conditions/main_test.go @@ -0,0 +1,193 @@ +package conditions + +import ( + "bytes" + "io" + "os" + "testing" + + "github.com/spf13/viper" + "gotest.tools/assert" + + "github.com/ditrit/badaas-cli/cmd/utils" +) + +const chunkSize = 100000 + +func TestUIntModel(t *testing.T) { + doTest(t, "./tests/uintmodel", []Comparison{ + {Have: "uint_model_conditions.go", Expected: "./tests/results/uintmodel.go"}, + }) +} + +func TestUUIDModel(t *testing.T) { + doTest(t, "./tests/uuidmodel", []Comparison{ + {Have: "uuid_model_conditions.go", Expected: "./tests/results/uuidmodel.go"}, + }) +} + +func TestBasicTypes(t *testing.T) { + doTest(t, "./tests/basictypes", []Comparison{ + {Have: "basic_types_conditions.go", Expected: "./tests/results/basictypes.go"}, + }) +} + +func TestBasicPointers(t *testing.T) { + doTest(t, "./tests/basicpointers", []Comparison{ + {Have: "basic_pointers_conditions.go", Expected: "./tests/results/basicpointers.go"}, + }) +} + +func TestBasicSlices(t *testing.T) { + doTest(t, "./tests/basicslices", []Comparison{ + {Have: "basic_slices_conditions.go", Expected: "./tests/results/basicslices.go"}, + }) +} + +func TestBasicSlicesPointer(t *testing.T) { + doTest(t, "./tests/basicslicespointer", []Comparison{ + {Have: "basic_slices_pointer_conditions.go", Expected: "./tests/results/basicslicespointer.go"}, + }) +} + +func TestGoEmbedded(t *testing.T) { + doTest(t, "./tests/goembedded", []Comparison{ + {Have: "go_embedded_conditions.go", Expected: "./tests/results/goembedded.go"}, + }) +} + +func TestGormEmbedded(t *testing.T) { + doTest(t, "./tests/gormembedded", []Comparison{ + {Have: "gorm_embedded_conditions.go", Expected: "./tests/results/gormembedded.go"}, + }) +} + +func TestCustomType(t *testing.T) { + doTest(t, "./tests/customtype", []Comparison{ + {Have: "custom_type_conditions.go", Expected: "./tests/results/customtype.go"}, + }) +} + +func TestBelongsTo(t *testing.T) { + doTest(t, "./tests/belongsto", []Comparison{ + {Have: "owner_conditions.go", Expected: "./tests/results/belongsto_owner.go"}, + {Have: "owned_conditions.go", Expected: "./tests/results/belongsto_owned.go"}, + }) +} + +func TestHasOne(t *testing.T) { + doTest(t, "./tests/hasone", []Comparison{ + {Have: "country_conditions.go", Expected: "./tests/results/hasone_country.go"}, + {Have: "city_conditions.go", Expected: "./tests/results/hasone_city.go"}, + }) +} + +func TestHasMany(t *testing.T) { + doTest(t, "./tests/hasmany", []Comparison{ + {Have: "company_conditions.go", Expected: "./tests/results/hasmany_company.go"}, + {Have: "seller_conditions.go", Expected: "./tests/results/hasmany_seller.go"}, + }) +} + +func TestSelfReferential(t *testing.T) { + doTest(t, "./tests/selfreferential", []Comparison{ + {Have: "employee_conditions.go", Expected: "./tests/results/selfreferential.go"}, + }) +} + +func TestMultiplePackage(t *testing.T) { + doTest(t, "./tests/multiplepackage/package1", []Comparison{ + {Have: "package1_conditions.go", Expected: "./tests/results/multiplepackage_package1.go"}, + }) +} + +func TestColumnDefinition(t *testing.T) { + doTest(t, "./tests/columndefinition", []Comparison{ + {Have: "column_definition_conditions.go", Expected: "./tests/results/columndefinition.go"}, + }) +} + +func TestOverrideForeignKey(t *testing.T) { + doTest(t, "./tests/overrideforeignkey", []Comparison{ + {Have: "bicycle_conditions.go", Expected: "./tests/results/overrideforeignkey.go"}, + }) + utils.RemoveFile("person_conditions.go") +} + +func TestOverrideReferences(t *testing.T) { + doTest(t, "./tests/overridereferences", []Comparison{ + {Have: "phone_conditions.go", Expected: "./tests/results/overridereferences.go"}, + }) + utils.RemoveFile("brand_conditions.go") +} + +func TestOverrideForeignKeyInverse(t *testing.T) { + doTest(t, "./tests/overrideforeignkeyinverse", []Comparison{ + {Have: "user_conditions.go", Expected: "./tests/results/overrideforeignkeyinverse.go"}, + }) + utils.RemoveFile("credit_card_conditions.go") +} + +func TestOverrideReferencesInverse(t *testing.T) { + doTest(t, "./tests/overridereferencesinverse", []Comparison{ + {Have: "computer_conditions.go", Expected: "./tests/results/overridereferencesinverse.go"}, + }) + utils.RemoveFile("processor_conditions.go") +} + +type Comparison struct { + Have string + Expected string +} + +func doTest(t *testing.T, sourcePkg string, comparisons []Comparison) { + viper.Set(DestPackageKey, "conditions") + generateConditions(nil, []string{sourcePkg}) + for _, comparison := range comparisons { + checkFilesEqual(t, comparison.Have, comparison.Expected) + } +} + +func checkFilesEqual(t *testing.T, file1, file2 string) { + stat1 := utils.CheckFileExists(t, file1) + stat2 := utils.CheckFileExists(t, file2) + + // do inputs at least have the same size? + assert.Equal(t, stat1.Size(), stat2.Size(), "File lens are not equal") + + // long way: compare contents + f1, err := os.Open(file1) + if err != nil { + t.Error(err) + } + defer f1.Close() + + f2, err := os.Open(file2) + if err != nil { + t.Error(err) + } + defer f2.Close() + + b1 := make([]byte, chunkSize) + b2 := make([]byte, chunkSize) + for { + n1, err1 := io.ReadFull(f1, b1) + n2, err2 := io.ReadFull(f2, b2) + + assert.Assert(t, bytes.Equal(b1[:n1], b2[:n2])) + + if (err1 == io.EOF && err2 == io.EOF) || (err1 == io.ErrUnexpectedEOF && err2 == io.ErrUnexpectedEOF) { + break + } + + // some other error, like a dropped network connection or a bad transfer + if err1 != nil { + t.Error(err1) + } + if err2 != nil { + t.Error(err2) + } + } + + utils.RemoveFile(file1) +} diff --git a/cmd/gen/conditions/tests/basicpointers/basicpointers.go b/cmd/gen/conditions/tests/basicpointers/basicpointers.go new file mode 100644 index 0000000..bebe0e9 --- /dev/null +++ b/cmd/gen/conditions/tests/basicpointers/basicpointers.go @@ -0,0 +1,26 @@ +package basicpointers + +import "github.com/ditrit/badaas/orm" + +type BasicPointers struct { + orm.UUIDModel + + Bool *bool + Int *int + Int8 *int8 + Int16 *int16 + Int32 *int32 + Int64 *int64 + UInt *uint + UInt8 *uint8 + UInt16 *uint16 + UInt32 *uint32 + UInt64 *uint64 + UIntptr *uintptr + Float32 *float32 + Float64 *float64 + Complex64 *complex64 + Complex128 *complex128 + String *string + Byte *byte +} diff --git a/cmd/gen/conditions/tests/basicslices/basicslices.go b/cmd/gen/conditions/tests/basicslices/basicslices.go new file mode 100644 index 0000000..eead356 --- /dev/null +++ b/cmd/gen/conditions/tests/basicslices/basicslices.go @@ -0,0 +1,26 @@ +package basicslices + +import "github.com/ditrit/badaas/orm" + +type BasicSlices struct { + orm.UUIDModel + + Bool []bool + Int []int + Int8 []int8 + Int16 []int16 + Int32 []int32 + Int64 []int64 + UInt []uint + UInt8 []uint8 + UInt16 []uint16 + UInt32 []uint32 + UInt64 []uint64 + UIntptr []uintptr + Float32 []float32 + Float64 []float64 + Complex64 []complex64 + Complex128 []complex128 + String []string + Byte []byte +} diff --git a/cmd/gen/conditions/tests/basicslicespointer/basicslicespointer.go b/cmd/gen/conditions/tests/basicslicespointer/basicslicespointer.go new file mode 100644 index 0000000..c0f1da1 --- /dev/null +++ b/cmd/gen/conditions/tests/basicslicespointer/basicslicespointer.go @@ -0,0 +1,26 @@ +package basicslicespointer + +import "github.com/ditrit/badaas/orm" + +type BasicSlicesPointer struct { + orm.UUIDModel + + Bool []*bool + Int []*int + Int8 []*int8 + Int16 []*int16 + Int32 []*int32 + Int64 []*int64 + UInt []*uint + UInt8 []*uint8 + UInt16 []*uint16 + UInt32 []*uint32 + UInt64 []*uint64 + UIntptr []*uintptr + Float32 []*float32 + Float64 []*float64 + Complex64 []*complex64 + Complex128 []*complex128 + String []*string + Byte []*byte +} diff --git a/cmd/gen/conditions/tests/basictypes/basictypes.go b/cmd/gen/conditions/tests/basictypes/basictypes.go new file mode 100644 index 0000000..d5170e3 --- /dev/null +++ b/cmd/gen/conditions/tests/basictypes/basictypes.go @@ -0,0 +1,26 @@ +package basictypes + +import "github.com/ditrit/badaas/orm" + +type BasicTypes struct { + orm.UUIDModel + + Bool bool + Int int + Int8 int8 + Int16 int16 + Int32 int32 + Int64 int64 + UInt uint + UInt8 uint8 + UInt16 uint16 + UInt32 uint32 + UInt64 uint64 + UIntptr uintptr + Float32 float32 + Float64 float64 + Complex64 complex64 + Complex128 complex128 + String string + Byte byte +} diff --git a/cmd/gen/conditions/tests/belongsto/belongsto.go b/cmd/gen/conditions/tests/belongsto/belongsto.go new file mode 100644 index 0000000..aa3f100 --- /dev/null +++ b/cmd/gen/conditions/tests/belongsto/belongsto.go @@ -0,0 +1,14 @@ +package belongsto + +import "github.com/ditrit/badaas/orm" + +type Owner struct { + orm.UUIDModel +} +type Owned struct { + orm.UUIDModel + + // Owned belongsTo Owner (Owned 0..* -> 1 Owner) + Owner Owner + OwnerID orm.UUID +} diff --git a/cmd/gen/conditions/tests/columndefinition/columndefinition.go b/cmd/gen/conditions/tests/columndefinition/columndefinition.go new file mode 100644 index 0000000..775395d --- /dev/null +++ b/cmd/gen/conditions/tests/columndefinition/columndefinition.go @@ -0,0 +1,9 @@ +package columndefinition + +import "github.com/ditrit/badaas/orm" + +type ColumnDefinition struct { + orm.UUIDModel + + String string `gorm:"column:string_something_else"` +} diff --git a/cmd/gen/conditions/tests/customtype/customtype.go b/cmd/gen/conditions/tests/customtype/customtype.go new file mode 100644 index 0000000..2a208d4 --- /dev/null +++ b/cmd/gen/conditions/tests/customtype/customtype.go @@ -0,0 +1,42 @@ +package customtype + +import ( + "database/sql/driver" + "fmt" + "strings" + + "github.com/ditrit/badaas/orm" +) + +type MultiString []string + +func (s *MultiString) Scan(src interface{}) error { + switch typedSrc := src.(type) { + case string: + *s = strings.Split(typedSrc, ",") + return nil + case []byte: + str := string(typedSrc) + *s = strings.Split(str, ",") + return nil + default: + return fmt.Errorf("failed to scan multistring field - source is not a string, is %T", src) + } +} + +func (s MultiString) Value() (driver.Value, error) { + if len(s) == 0 { + return nil, nil + } + return strings.Join(s, ","), nil +} + +func (MultiString) GormDataType() string { + return "text" +} + +type CustomType struct { + orm.UUIDModel + + Custom MultiString +} diff --git a/cmd/gen/conditions/tests/goembedded/goembedded.go b/cmd/gen/conditions/tests/goembedded/goembedded.go new file mode 100644 index 0000000..ff7c0e1 --- /dev/null +++ b/cmd/gen/conditions/tests/goembedded/goembedded.go @@ -0,0 +1,13 @@ +package goembedded + +import "github.com/ditrit/badaas/orm" + +type ToBeEmbedded struct { + EmbeddedInt int +} + +type GoEmbedded struct { + orm.UIntModel + + ToBeEmbedded +} diff --git a/cmd/gen/conditions/tests/gormembedded/gormembedded.go b/cmd/gen/conditions/tests/gormembedded/gormembedded.go new file mode 100644 index 0000000..6b7c219 --- /dev/null +++ b/cmd/gen/conditions/tests/gormembedded/gormembedded.go @@ -0,0 +1,13 @@ +package gormembedded + +import "github.com/ditrit/badaas/orm" + +type ToBeGormEmbedded struct { + Int int +} + +type GormEmbedded struct { + orm.UIntModel + + GormEmbedded ToBeGormEmbedded `gorm:"embedded;embeddedPrefix:gorm_embedded_"` +} diff --git a/cmd/gen/conditions/tests/hasmany/hasmany.go b/cmd/gen/conditions/tests/hasmany/hasmany.go new file mode 100644 index 0000000..0eafe59 --- /dev/null +++ b/cmd/gen/conditions/tests/hasmany/hasmany.go @@ -0,0 +1,15 @@ +package hasone + +import "github.com/ditrit/badaas/orm" + +type Company struct { + orm.UUIDModel + + Sellers []Seller // Company HasMany Sellers (Company 0..1 -> 0..* Seller) +} + +type Seller struct { + orm.UUIDModel + + CompanyID *orm.UUID // Company HasMany Sellers (Company 0..1 -> 0..* Seller) +} diff --git a/cmd/gen/conditions/tests/hasone/hasone.go b/cmd/gen/conditions/tests/hasone/hasone.go new file mode 100644 index 0000000..cc29a90 --- /dev/null +++ b/cmd/gen/conditions/tests/hasone/hasone.go @@ -0,0 +1,15 @@ +package hasone + +import "github.com/ditrit/badaas/orm" + +type Country struct { + orm.UUIDModel + + Capital City // Country HasOne City (Country 1 -> 1 City) +} + +type City struct { + orm.UUIDModel + + CountryID orm.UUID // Country HasOne City (Country 1 -> 1 City) +} diff --git a/cmd/gen/conditions/tests/multiplepackage/package1/package1.go b/cmd/gen/conditions/tests/multiplepackage/package1/package1.go new file mode 100644 index 0000000..fbe09c3 --- /dev/null +++ b/cmd/gen/conditions/tests/multiplepackage/package1/package1.go @@ -0,0 +1,12 @@ +package package1 + +import ( + "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/multiplepackage/package2" + "github.com/ditrit/badaas/orm" +) + +type Package1 struct { + orm.UUIDModel + + Package2 package2.Package2 // Package1 HasOne Package2 (Package1 1 -> 1 Package2) +} diff --git a/cmd/gen/conditions/tests/multiplepackage/package2/package2.go b/cmd/gen/conditions/tests/multiplepackage/package2/package2.go new file mode 100644 index 0000000..26ffe55 --- /dev/null +++ b/cmd/gen/conditions/tests/multiplepackage/package2/package2.go @@ -0,0 +1,9 @@ +package package2 + +import "github.com/ditrit/badaas/orm" + +type Package2 struct { + orm.UUIDModel + + Package1ID orm.UUID // Package1 HasOne Package2 (Package1 1 -> 1 Package2) +} diff --git a/cmd/gen/conditions/tests/overrideforeignkey/overrideforeignkey.go b/cmd/gen/conditions/tests/overrideforeignkey/overrideforeignkey.go new file mode 100644 index 0000000..f699577 --- /dev/null +++ b/cmd/gen/conditions/tests/overrideforeignkey/overrideforeignkey.go @@ -0,0 +1,15 @@ +package overrideforeignkey + +import "github.com/ditrit/badaas/orm" + +type Person struct { + orm.UUIDModel +} + +type Bicycle struct { + orm.UUIDModel + + // Bicycle BelongsTo Person (Bicycle 0..* -> 1 Person) + Owner Person `gorm:"foreignKey:OwnerSomethingID"` + OwnerSomethingID string +} diff --git a/cmd/gen/conditions/tests/overrideforeignkeyinverse/overrideforeignkeyinverse.go b/cmd/gen/conditions/tests/overrideforeignkeyinverse/overrideforeignkeyinverse.go new file mode 100644 index 0000000..b2d0974 --- /dev/null +++ b/cmd/gen/conditions/tests/overrideforeignkeyinverse/overrideforeignkeyinverse.go @@ -0,0 +1,13 @@ +package overrideforeignkeyinverse + +import "github.com/ditrit/badaas/orm" + +type User struct { + orm.UUIDModel + CreditCard CreditCard `gorm:"foreignKey:UserReference"` +} + +type CreditCard struct { + orm.UUIDModel + UserReference orm.UUID +} diff --git a/cmd/gen/conditions/tests/overridereferences/overridereferences.go b/cmd/gen/conditions/tests/overridereferences/overridereferences.go new file mode 100644 index 0000000..08d49a2 --- /dev/null +++ b/cmd/gen/conditions/tests/overridereferences/overridereferences.go @@ -0,0 +1,17 @@ +package overridereferences + +import "github.com/ditrit/badaas/orm" + +type Brand struct { + orm.UUIDModel + + Name string `gorm:"unique;type:VARCHAR(255)"` +} + +type Phone struct { + orm.UUIDModel + + // Bicycle BelongsTo Person (Bicycle 0..* -> 1 Person) + Brand Brand `gorm:"references:Name;foreignKey:BrandName"` + BrandName string +} diff --git a/cmd/gen/conditions/tests/overridereferencesinverse/overridereferencesinverse.go b/cmd/gen/conditions/tests/overridereferencesinverse/overridereferencesinverse.go new file mode 100644 index 0000000..08bc3b2 --- /dev/null +++ b/cmd/gen/conditions/tests/overridereferencesinverse/overridereferencesinverse.go @@ -0,0 +1,14 @@ +package overridereferencesinverse + +import "github.com/ditrit/badaas/orm" + +type Computer struct { + orm.UUIDModel + Name string + Processor Processor `gorm:"foreignKey:ComputerName;references:Name"` +} + +type Processor struct { + orm.UUIDModel + ComputerName string +} diff --git a/cmd/gen/conditions/tests/results/basicpointers.go b/cmd/gen/conditions/tests/results/basicpointers.go new file mode 100644 index 0000000..0aaa477 --- /dev/null +++ b/cmd/gen/conditions/tests/results/basicpointers.go @@ -0,0 +1,142 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + basicpointers "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/basicpointers" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func BasicPointersId(v orm.UUID) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "ID", + Value: v, + } +} +func BasicPointersCreatedAt(v time.Time) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "CreatedAt", + Value: v, + } +} +func BasicPointersUpdatedAt(v time.Time) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "UpdatedAt", + Value: v, + } +} +func BasicPointersDeletedAt(v gorm.DeletedAt) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "DeletedAt", + Value: v, + } +} +func BasicPointersBool(v bool) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Bool", + Value: v, + } +} +func BasicPointersInt(v int) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Int", + Value: v, + } +} +func BasicPointersInt8(v int8) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Int8", + Value: v, + } +} +func BasicPointersInt16(v int16) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Int16", + Value: v, + } +} +func BasicPointersInt32(v int32) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Int32", + Value: v, + } +} +func BasicPointersInt64(v int64) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Int64", + Value: v, + } +} +func BasicPointersUInt(v uint) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "UInt", + Value: v, + } +} +func BasicPointersUInt8(v uint8) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "UInt8", + Value: v, + } +} +func BasicPointersUInt16(v uint16) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "UInt16", + Value: v, + } +} +func BasicPointersUInt32(v uint32) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "UInt32", + Value: v, + } +} +func BasicPointersUInt64(v uint64) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "UInt64", + Value: v, + } +} +func BasicPointersUIntptr(v uintptr) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "UIntptr", + Value: v, + } +} +func BasicPointersFloat32(v float32) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Float32", + Value: v, + } +} +func BasicPointersFloat64(v float64) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Float64", + Value: v, + } +} +func BasicPointersComplex64(v complex64) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Complex64", + Value: v, + } +} +func BasicPointersComplex128(v complex128) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Complex128", + Value: v, + } +} +func BasicPointersString(v string) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "String", + Value: v, + } +} +func BasicPointersByte(v uint8) orm.WhereCondition[basicpointers.BasicPointers] { + return orm.WhereCondition[basicpointers.BasicPointers]{ + Field: "Byte", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/basicslices.go b/cmd/gen/conditions/tests/results/basicslices.go new file mode 100644 index 0000000..2db14c1 --- /dev/null +++ b/cmd/gen/conditions/tests/results/basicslices.go @@ -0,0 +1,142 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + basicslices "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/basicslices" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func BasicSlicesId(v orm.UUID) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "ID", + Value: v, + } +} +func BasicSlicesCreatedAt(v time.Time) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "CreatedAt", + Value: v, + } +} +func BasicSlicesUpdatedAt(v time.Time) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "UpdatedAt", + Value: v, + } +} +func BasicSlicesDeletedAt(v gorm.DeletedAt) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "DeletedAt", + Value: v, + } +} +func BasicSlicesBool(v []bool) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Bool", + Value: v, + } +} +func BasicSlicesInt(v []int) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Int", + Value: v, + } +} +func BasicSlicesInt8(v []int8) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Int8", + Value: v, + } +} +func BasicSlicesInt16(v []int16) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Int16", + Value: v, + } +} +func BasicSlicesInt32(v []int32) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Int32", + Value: v, + } +} +func BasicSlicesInt64(v []int64) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Int64", + Value: v, + } +} +func BasicSlicesUInt(v []uint) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "UInt", + Value: v, + } +} +func BasicSlicesUInt8(v []uint8) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "UInt8", + Value: v, + } +} +func BasicSlicesUInt16(v []uint16) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "UInt16", + Value: v, + } +} +func BasicSlicesUInt32(v []uint32) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "UInt32", + Value: v, + } +} +func BasicSlicesUInt64(v []uint64) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "UInt64", + Value: v, + } +} +func BasicSlicesUIntptr(v []uintptr) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "UIntptr", + Value: v, + } +} +func BasicSlicesFloat32(v []float32) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Float32", + Value: v, + } +} +func BasicSlicesFloat64(v []float64) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Float64", + Value: v, + } +} +func BasicSlicesComplex64(v []complex64) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Complex64", + Value: v, + } +} +func BasicSlicesComplex128(v []complex128) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Complex128", + Value: v, + } +} +func BasicSlicesString(v []string) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "String", + Value: v, + } +} +func BasicSlicesByte(v []uint8) orm.WhereCondition[basicslices.BasicSlices] { + return orm.WhereCondition[basicslices.BasicSlices]{ + Field: "Byte", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/basicslicespointer.go b/cmd/gen/conditions/tests/results/basicslicespointer.go new file mode 100644 index 0000000..71e772f --- /dev/null +++ b/cmd/gen/conditions/tests/results/basicslicespointer.go @@ -0,0 +1,142 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + basicslicespointer "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/basicslicespointer" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func BasicSlicesPointerId(v orm.UUID) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "ID", + Value: v, + } +} +func BasicSlicesPointerCreatedAt(v time.Time) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "CreatedAt", + Value: v, + } +} +func BasicSlicesPointerUpdatedAt(v time.Time) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "UpdatedAt", + Value: v, + } +} +func BasicSlicesPointerDeletedAt(v gorm.DeletedAt) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "DeletedAt", + Value: v, + } +} +func BasicSlicesPointerBool(v []bool) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Bool", + Value: v, + } +} +func BasicSlicesPointerInt(v []int) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Int", + Value: v, + } +} +func BasicSlicesPointerInt8(v []int8) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Int8", + Value: v, + } +} +func BasicSlicesPointerInt16(v []int16) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Int16", + Value: v, + } +} +func BasicSlicesPointerInt32(v []int32) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Int32", + Value: v, + } +} +func BasicSlicesPointerInt64(v []int64) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Int64", + Value: v, + } +} +func BasicSlicesPointerUInt(v []uint) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "UInt", + Value: v, + } +} +func BasicSlicesPointerUInt8(v []uint8) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "UInt8", + Value: v, + } +} +func BasicSlicesPointerUInt16(v []uint16) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "UInt16", + Value: v, + } +} +func BasicSlicesPointerUInt32(v []uint32) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "UInt32", + Value: v, + } +} +func BasicSlicesPointerUInt64(v []uint64) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "UInt64", + Value: v, + } +} +func BasicSlicesPointerUIntptr(v []uintptr) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "UIntptr", + Value: v, + } +} +func BasicSlicesPointerFloat32(v []float32) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Float32", + Value: v, + } +} +func BasicSlicesPointerFloat64(v []float64) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Float64", + Value: v, + } +} +func BasicSlicesPointerComplex64(v []complex64) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Complex64", + Value: v, + } +} +func BasicSlicesPointerComplex128(v []complex128) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Complex128", + Value: v, + } +} +func BasicSlicesPointerString(v []string) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "String", + Value: v, + } +} +func BasicSlicesPointerByte(v []uint8) orm.WhereCondition[basicslicespointer.BasicSlicesPointer] { + return orm.WhereCondition[basicslicespointer.BasicSlicesPointer]{ + Field: "Byte", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/basictypes.go b/cmd/gen/conditions/tests/results/basictypes.go new file mode 100644 index 0000000..877943d --- /dev/null +++ b/cmd/gen/conditions/tests/results/basictypes.go @@ -0,0 +1,142 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + basictypes "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/basictypes" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func BasicTypesId(v orm.UUID) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "ID", + Value: v, + } +} +func BasicTypesCreatedAt(v time.Time) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "CreatedAt", + Value: v, + } +} +func BasicTypesUpdatedAt(v time.Time) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "UpdatedAt", + Value: v, + } +} +func BasicTypesDeletedAt(v gorm.DeletedAt) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "DeletedAt", + Value: v, + } +} +func BasicTypesBool(v bool) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Bool", + Value: v, + } +} +func BasicTypesInt(v int) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Int", + Value: v, + } +} +func BasicTypesInt8(v int8) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Int8", + Value: v, + } +} +func BasicTypesInt16(v int16) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Int16", + Value: v, + } +} +func BasicTypesInt32(v int32) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Int32", + Value: v, + } +} +func BasicTypesInt64(v int64) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Int64", + Value: v, + } +} +func BasicTypesUInt(v uint) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "UInt", + Value: v, + } +} +func BasicTypesUInt8(v uint8) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "UInt8", + Value: v, + } +} +func BasicTypesUInt16(v uint16) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "UInt16", + Value: v, + } +} +func BasicTypesUInt32(v uint32) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "UInt32", + Value: v, + } +} +func BasicTypesUInt64(v uint64) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "UInt64", + Value: v, + } +} +func BasicTypesUIntptr(v uintptr) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "UIntptr", + Value: v, + } +} +func BasicTypesFloat32(v float32) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Float32", + Value: v, + } +} +func BasicTypesFloat64(v float64) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Float64", + Value: v, + } +} +func BasicTypesComplex64(v complex64) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Complex64", + Value: v, + } +} +func BasicTypesComplex128(v complex128) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Complex128", + Value: v, + } +} +func BasicTypesString(v string) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "String", + Value: v, + } +} +func BasicTypesByte(v uint8) orm.WhereCondition[basictypes.BasicTypes] { + return orm.WhereCondition[basictypes.BasicTypes]{ + Field: "Byte", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/belongsto_owned.go b/cmd/gen/conditions/tests/results/belongsto_owned.go new file mode 100644 index 0000000..9b22347 --- /dev/null +++ b/cmd/gen/conditions/tests/results/belongsto_owned.go @@ -0,0 +1,47 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + belongsto "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/belongsto" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func OwnedId(v orm.UUID) orm.WhereCondition[belongsto.Owned] { + return orm.WhereCondition[belongsto.Owned]{ + Field: "ID", + Value: v, + } +} +func OwnedCreatedAt(v time.Time) orm.WhereCondition[belongsto.Owned] { + return orm.WhereCondition[belongsto.Owned]{ + Field: "CreatedAt", + Value: v, + } +} +func OwnedUpdatedAt(v time.Time) orm.WhereCondition[belongsto.Owned] { + return orm.WhereCondition[belongsto.Owned]{ + Field: "UpdatedAt", + Value: v, + } +} +func OwnedDeletedAt(v gorm.DeletedAt) orm.WhereCondition[belongsto.Owned] { + return orm.WhereCondition[belongsto.Owned]{ + Field: "DeletedAt", + Value: v, + } +} +func OwnedOwner(conditions ...orm.Condition[belongsto.Owner]) orm.Condition[belongsto.Owned] { + return orm.JoinCondition[belongsto.Owned, belongsto.Owner]{ + Conditions: conditions, + T1Field: "OwnerID", + T2Field: "ID", + } +} +func OwnedOwnerId(v orm.UUID) orm.WhereCondition[belongsto.Owned] { + return orm.WhereCondition[belongsto.Owned]{ + Field: "OwnerID", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/belongsto_owner.go b/cmd/gen/conditions/tests/results/belongsto_owner.go new file mode 100644 index 0000000..b712824 --- /dev/null +++ b/cmd/gen/conditions/tests/results/belongsto_owner.go @@ -0,0 +1,34 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + belongsto "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/belongsto" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func OwnerId(v orm.UUID) orm.WhereCondition[belongsto.Owner] { + return orm.WhereCondition[belongsto.Owner]{ + Field: "ID", + Value: v, + } +} +func OwnerCreatedAt(v time.Time) orm.WhereCondition[belongsto.Owner] { + return orm.WhereCondition[belongsto.Owner]{ + Field: "CreatedAt", + Value: v, + } +} +func OwnerUpdatedAt(v time.Time) orm.WhereCondition[belongsto.Owner] { + return orm.WhereCondition[belongsto.Owner]{ + Field: "UpdatedAt", + Value: v, + } +} +func OwnerDeletedAt(v gorm.DeletedAt) orm.WhereCondition[belongsto.Owner] { + return orm.WhereCondition[belongsto.Owner]{ + Field: "DeletedAt", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/columndefinition.go b/cmd/gen/conditions/tests/results/columndefinition.go new file mode 100644 index 0000000..899d821 --- /dev/null +++ b/cmd/gen/conditions/tests/results/columndefinition.go @@ -0,0 +1,40 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + columndefinition "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/columndefinition" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func ColumnDefinitionId(v orm.UUID) orm.WhereCondition[columndefinition.ColumnDefinition] { + return orm.WhereCondition[columndefinition.ColumnDefinition]{ + Field: "ID", + Value: v, + } +} +func ColumnDefinitionCreatedAt(v time.Time) orm.WhereCondition[columndefinition.ColumnDefinition] { + return orm.WhereCondition[columndefinition.ColumnDefinition]{ + Field: "CreatedAt", + Value: v, + } +} +func ColumnDefinitionUpdatedAt(v time.Time) orm.WhereCondition[columndefinition.ColumnDefinition] { + return orm.WhereCondition[columndefinition.ColumnDefinition]{ + Field: "UpdatedAt", + Value: v, + } +} +func ColumnDefinitionDeletedAt(v gorm.DeletedAt) orm.WhereCondition[columndefinition.ColumnDefinition] { + return orm.WhereCondition[columndefinition.ColumnDefinition]{ + Field: "DeletedAt", + Value: v, + } +} +func ColumnDefinitionString(v string) orm.WhereCondition[columndefinition.ColumnDefinition] { + return orm.WhereCondition[columndefinition.ColumnDefinition]{ + Column: "string_something_else", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/customtype.go b/cmd/gen/conditions/tests/results/customtype.go new file mode 100644 index 0000000..6eec5fd --- /dev/null +++ b/cmd/gen/conditions/tests/results/customtype.go @@ -0,0 +1,40 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + customtype "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/customtype" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func CustomTypeId(v orm.UUID) orm.WhereCondition[customtype.CustomType] { + return orm.WhereCondition[customtype.CustomType]{ + Field: "ID", + Value: v, + } +} +func CustomTypeCreatedAt(v time.Time) orm.WhereCondition[customtype.CustomType] { + return orm.WhereCondition[customtype.CustomType]{ + Field: "CreatedAt", + Value: v, + } +} +func CustomTypeUpdatedAt(v time.Time) orm.WhereCondition[customtype.CustomType] { + return orm.WhereCondition[customtype.CustomType]{ + Field: "UpdatedAt", + Value: v, + } +} +func CustomTypeDeletedAt(v gorm.DeletedAt) orm.WhereCondition[customtype.CustomType] { + return orm.WhereCondition[customtype.CustomType]{ + Field: "DeletedAt", + Value: v, + } +} +func CustomTypeCustom(v customtype.MultiString) orm.WhereCondition[customtype.CustomType] { + return orm.WhereCondition[customtype.CustomType]{ + Field: "Custom", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/goembedded.go b/cmd/gen/conditions/tests/results/goembedded.go new file mode 100644 index 0000000..1f2cf3e --- /dev/null +++ b/cmd/gen/conditions/tests/results/goembedded.go @@ -0,0 +1,40 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + goembedded "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/goembedded" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func GoEmbeddedId(v uint) orm.WhereCondition[goembedded.GoEmbedded] { + return orm.WhereCondition[goembedded.GoEmbedded]{ + Field: "ID", + Value: v, + } +} +func GoEmbeddedCreatedAt(v time.Time) orm.WhereCondition[goembedded.GoEmbedded] { + return orm.WhereCondition[goembedded.GoEmbedded]{ + Field: "CreatedAt", + Value: v, + } +} +func GoEmbeddedUpdatedAt(v time.Time) orm.WhereCondition[goembedded.GoEmbedded] { + return orm.WhereCondition[goembedded.GoEmbedded]{ + Field: "UpdatedAt", + Value: v, + } +} +func GoEmbeddedDeletedAt(v gorm.DeletedAt) orm.WhereCondition[goembedded.GoEmbedded] { + return orm.WhereCondition[goembedded.GoEmbedded]{ + Field: "DeletedAt", + Value: v, + } +} +func GoEmbeddedEmbeddedInt(v int) orm.WhereCondition[goembedded.GoEmbedded] { + return orm.WhereCondition[goembedded.GoEmbedded]{ + Field: "EmbeddedInt", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/gormembedded.go b/cmd/gen/conditions/tests/results/gormembedded.go new file mode 100644 index 0000000..510e654 --- /dev/null +++ b/cmd/gen/conditions/tests/results/gormembedded.go @@ -0,0 +1,41 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + gormembedded "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/gormembedded" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func GormEmbeddedId(v uint) orm.WhereCondition[gormembedded.GormEmbedded] { + return orm.WhereCondition[gormembedded.GormEmbedded]{ + Field: "ID", + Value: v, + } +} +func GormEmbeddedCreatedAt(v time.Time) orm.WhereCondition[gormembedded.GormEmbedded] { + return orm.WhereCondition[gormembedded.GormEmbedded]{ + Field: "CreatedAt", + Value: v, + } +} +func GormEmbeddedUpdatedAt(v time.Time) orm.WhereCondition[gormembedded.GormEmbedded] { + return orm.WhereCondition[gormembedded.GormEmbedded]{ + Field: "UpdatedAt", + Value: v, + } +} +func GormEmbeddedDeletedAt(v gorm.DeletedAt) orm.WhereCondition[gormembedded.GormEmbedded] { + return orm.WhereCondition[gormembedded.GormEmbedded]{ + Field: "DeletedAt", + Value: v, + } +} +func GormEmbeddedGormEmbeddedInt(v int) orm.WhereCondition[gormembedded.GormEmbedded] { + return orm.WhereCondition[gormembedded.GormEmbedded]{ + ColumnPrefix: "gorm_embedded_", + Field: "Int", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/hasmany_company.go b/cmd/gen/conditions/tests/results/hasmany_company.go new file mode 100644 index 0000000..7bdda4b --- /dev/null +++ b/cmd/gen/conditions/tests/results/hasmany_company.go @@ -0,0 +1,41 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + hasmany "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/hasmany" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func CompanyId(v orm.UUID) orm.WhereCondition[hasmany.Company] { + return orm.WhereCondition[hasmany.Company]{ + Field: "ID", + Value: v, + } +} +func CompanyCreatedAt(v time.Time) orm.WhereCondition[hasmany.Company] { + return orm.WhereCondition[hasmany.Company]{ + Field: "CreatedAt", + Value: v, + } +} +func CompanyUpdatedAt(v time.Time) orm.WhereCondition[hasmany.Company] { + return orm.WhereCondition[hasmany.Company]{ + Field: "UpdatedAt", + Value: v, + } +} +func CompanyDeletedAt(v gorm.DeletedAt) orm.WhereCondition[hasmany.Company] { + return orm.WhereCondition[hasmany.Company]{ + Field: "DeletedAt", + Value: v, + } +} +func SellerCompany(conditions ...orm.Condition[hasmany.Company]) orm.Condition[hasmany.Seller] { + return orm.JoinCondition[hasmany.Seller, hasmany.Company]{ + Conditions: conditions, + T1Field: "CompanyID", + T2Field: "ID", + } +} diff --git a/cmd/gen/conditions/tests/results/hasmany_seller.go b/cmd/gen/conditions/tests/results/hasmany_seller.go new file mode 100644 index 0000000..6d1cfb8 --- /dev/null +++ b/cmd/gen/conditions/tests/results/hasmany_seller.go @@ -0,0 +1,40 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + hasmany "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/hasmany" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func SellerId(v orm.UUID) orm.WhereCondition[hasmany.Seller] { + return orm.WhereCondition[hasmany.Seller]{ + Field: "ID", + Value: v, + } +} +func SellerCreatedAt(v time.Time) orm.WhereCondition[hasmany.Seller] { + return orm.WhereCondition[hasmany.Seller]{ + Field: "CreatedAt", + Value: v, + } +} +func SellerUpdatedAt(v time.Time) orm.WhereCondition[hasmany.Seller] { + return orm.WhereCondition[hasmany.Seller]{ + Field: "UpdatedAt", + Value: v, + } +} +func SellerDeletedAt(v gorm.DeletedAt) orm.WhereCondition[hasmany.Seller] { + return orm.WhereCondition[hasmany.Seller]{ + Field: "DeletedAt", + Value: v, + } +} +func SellerCompanyId(v orm.UUID) orm.WhereCondition[hasmany.Seller] { + return orm.WhereCondition[hasmany.Seller]{ + Field: "CompanyID", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/hasone_city.go b/cmd/gen/conditions/tests/results/hasone_city.go new file mode 100644 index 0000000..5594228 --- /dev/null +++ b/cmd/gen/conditions/tests/results/hasone_city.go @@ -0,0 +1,40 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + hasone "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/hasone" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func CityId(v orm.UUID) orm.WhereCondition[hasone.City] { + return orm.WhereCondition[hasone.City]{ + Field: "ID", + Value: v, + } +} +func CityCreatedAt(v time.Time) orm.WhereCondition[hasone.City] { + return orm.WhereCondition[hasone.City]{ + Field: "CreatedAt", + Value: v, + } +} +func CityUpdatedAt(v time.Time) orm.WhereCondition[hasone.City] { + return orm.WhereCondition[hasone.City]{ + Field: "UpdatedAt", + Value: v, + } +} +func CityDeletedAt(v gorm.DeletedAt) orm.WhereCondition[hasone.City] { + return orm.WhereCondition[hasone.City]{ + Field: "DeletedAt", + Value: v, + } +} +func CityCountryId(v orm.UUID) orm.WhereCondition[hasone.City] { + return orm.WhereCondition[hasone.City]{ + Field: "CountryID", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/hasone_country.go b/cmd/gen/conditions/tests/results/hasone_country.go new file mode 100644 index 0000000..7001bdb --- /dev/null +++ b/cmd/gen/conditions/tests/results/hasone_country.go @@ -0,0 +1,48 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + hasone "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/hasone" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func CountryId(v orm.UUID) orm.WhereCondition[hasone.Country] { + return orm.WhereCondition[hasone.Country]{ + Field: "ID", + Value: v, + } +} +func CountryCreatedAt(v time.Time) orm.WhereCondition[hasone.Country] { + return orm.WhereCondition[hasone.Country]{ + Field: "CreatedAt", + Value: v, + } +} +func CountryUpdatedAt(v time.Time) orm.WhereCondition[hasone.Country] { + return orm.WhereCondition[hasone.Country]{ + Field: "UpdatedAt", + Value: v, + } +} +func CountryDeletedAt(v gorm.DeletedAt) orm.WhereCondition[hasone.Country] { + return orm.WhereCondition[hasone.Country]{ + Field: "DeletedAt", + Value: v, + } +} +func CountryCapital(conditions ...orm.Condition[hasone.City]) orm.Condition[hasone.Country] { + return orm.JoinCondition[hasone.Country, hasone.City]{ + Conditions: conditions, + T1Field: "ID", + T2Field: "CountryID", + } +} +func CityCountry(conditions ...orm.Condition[hasone.Country]) orm.Condition[hasone.City] { + return orm.JoinCondition[hasone.City, hasone.Country]{ + Conditions: conditions, + T1Field: "CountryID", + T2Field: "ID", + } +} diff --git a/cmd/gen/conditions/tests/results/multiplepackage_package1.go b/cmd/gen/conditions/tests/results/multiplepackage_package1.go new file mode 100644 index 0000000..90e793b --- /dev/null +++ b/cmd/gen/conditions/tests/results/multiplepackage_package1.go @@ -0,0 +1,49 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + package1 "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/multiplepackage/package1" + package2 "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/multiplepackage/package2" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func Package1Id(v orm.UUID) orm.WhereCondition[package1.Package1] { + return orm.WhereCondition[package1.Package1]{ + Field: "ID", + Value: v, + } +} +func Package1CreatedAt(v time.Time) orm.WhereCondition[package1.Package1] { + return orm.WhereCondition[package1.Package1]{ + Field: "CreatedAt", + Value: v, + } +} +func Package1UpdatedAt(v time.Time) orm.WhereCondition[package1.Package1] { + return orm.WhereCondition[package1.Package1]{ + Field: "UpdatedAt", + Value: v, + } +} +func Package1DeletedAt(v gorm.DeletedAt) orm.WhereCondition[package1.Package1] { + return orm.WhereCondition[package1.Package1]{ + Field: "DeletedAt", + Value: v, + } +} +func Package1Package2(conditions ...orm.Condition[package2.Package2]) orm.Condition[package1.Package1] { + return orm.JoinCondition[package1.Package1, package2.Package2]{ + Conditions: conditions, + T1Field: "ID", + T2Field: "Package1ID", + } +} +func Package2Package1(conditions ...orm.Condition[package1.Package1]) orm.Condition[package2.Package2] { + return orm.JoinCondition[package2.Package2, package1.Package1]{ + Conditions: conditions, + T1Field: "Package1ID", + T2Field: "ID", + } +} diff --git a/cmd/gen/conditions/tests/results/overrideforeignkey.go b/cmd/gen/conditions/tests/results/overrideforeignkey.go new file mode 100644 index 0000000..ab713c0 --- /dev/null +++ b/cmd/gen/conditions/tests/results/overrideforeignkey.go @@ -0,0 +1,47 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + overrideforeignkey "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/overrideforeignkey" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func BicycleId(v orm.UUID) orm.WhereCondition[overrideforeignkey.Bicycle] { + return orm.WhereCondition[overrideforeignkey.Bicycle]{ + Field: "ID", + Value: v, + } +} +func BicycleCreatedAt(v time.Time) orm.WhereCondition[overrideforeignkey.Bicycle] { + return orm.WhereCondition[overrideforeignkey.Bicycle]{ + Field: "CreatedAt", + Value: v, + } +} +func BicycleUpdatedAt(v time.Time) orm.WhereCondition[overrideforeignkey.Bicycle] { + return orm.WhereCondition[overrideforeignkey.Bicycle]{ + Field: "UpdatedAt", + Value: v, + } +} +func BicycleDeletedAt(v gorm.DeletedAt) orm.WhereCondition[overrideforeignkey.Bicycle] { + return orm.WhereCondition[overrideforeignkey.Bicycle]{ + Field: "DeletedAt", + Value: v, + } +} +func BicycleOwner(conditions ...orm.Condition[overrideforeignkey.Person]) orm.Condition[overrideforeignkey.Bicycle] { + return orm.JoinCondition[overrideforeignkey.Bicycle, overrideforeignkey.Person]{ + Conditions: conditions, + T1Field: "OwnerSomethingID", + T2Field: "ID", + } +} +func BicycleOwnerSomethingId(v string) orm.WhereCondition[overrideforeignkey.Bicycle] { + return orm.WhereCondition[overrideforeignkey.Bicycle]{ + Field: "OwnerSomethingID", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/overrideforeignkeyinverse.go b/cmd/gen/conditions/tests/results/overrideforeignkeyinverse.go new file mode 100644 index 0000000..7181c81 --- /dev/null +++ b/cmd/gen/conditions/tests/results/overrideforeignkeyinverse.go @@ -0,0 +1,48 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + overrideforeignkeyinverse "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/overrideforeignkeyinverse" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func UserId(v orm.UUID) orm.WhereCondition[overrideforeignkeyinverse.User] { + return orm.WhereCondition[overrideforeignkeyinverse.User]{ + Field: "ID", + Value: v, + } +} +func UserCreatedAt(v time.Time) orm.WhereCondition[overrideforeignkeyinverse.User] { + return orm.WhereCondition[overrideforeignkeyinverse.User]{ + Field: "CreatedAt", + Value: v, + } +} +func UserUpdatedAt(v time.Time) orm.WhereCondition[overrideforeignkeyinverse.User] { + return orm.WhereCondition[overrideforeignkeyinverse.User]{ + Field: "UpdatedAt", + Value: v, + } +} +func UserDeletedAt(v gorm.DeletedAt) orm.WhereCondition[overrideforeignkeyinverse.User] { + return orm.WhereCondition[overrideforeignkeyinverse.User]{ + Field: "DeletedAt", + Value: v, + } +} +func UserCreditCard(conditions ...orm.Condition[overrideforeignkeyinverse.CreditCard]) orm.Condition[overrideforeignkeyinverse.User] { + return orm.JoinCondition[overrideforeignkeyinverse.User, overrideforeignkeyinverse.CreditCard]{ + Conditions: conditions, + T1Field: "ID", + T2Field: "UserReference", + } +} +func CreditCardUser(conditions ...orm.Condition[overrideforeignkeyinverse.User]) orm.Condition[overrideforeignkeyinverse.CreditCard] { + return orm.JoinCondition[overrideforeignkeyinverse.CreditCard, overrideforeignkeyinverse.User]{ + Conditions: conditions, + T1Field: "UserReference", + T2Field: "ID", + } +} diff --git a/cmd/gen/conditions/tests/results/overridereferences.go b/cmd/gen/conditions/tests/results/overridereferences.go new file mode 100644 index 0000000..f0ec909 --- /dev/null +++ b/cmd/gen/conditions/tests/results/overridereferences.go @@ -0,0 +1,47 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + overridereferences "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/overridereferences" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func PhoneId(v orm.UUID) orm.WhereCondition[overridereferences.Phone] { + return orm.WhereCondition[overridereferences.Phone]{ + Field: "ID", + Value: v, + } +} +func PhoneCreatedAt(v time.Time) orm.WhereCondition[overridereferences.Phone] { + return orm.WhereCondition[overridereferences.Phone]{ + Field: "CreatedAt", + Value: v, + } +} +func PhoneUpdatedAt(v time.Time) orm.WhereCondition[overridereferences.Phone] { + return orm.WhereCondition[overridereferences.Phone]{ + Field: "UpdatedAt", + Value: v, + } +} +func PhoneDeletedAt(v gorm.DeletedAt) orm.WhereCondition[overridereferences.Phone] { + return orm.WhereCondition[overridereferences.Phone]{ + Field: "DeletedAt", + Value: v, + } +} +func PhoneBrand(conditions ...orm.Condition[overridereferences.Brand]) orm.Condition[overridereferences.Phone] { + return orm.JoinCondition[overridereferences.Phone, overridereferences.Brand]{ + Conditions: conditions, + T1Field: "BrandName", + T2Field: "Name", + } +} +func PhoneBrandName(v string) orm.WhereCondition[overridereferences.Phone] { + return orm.WhereCondition[overridereferences.Phone]{ + Field: "BrandName", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/overridereferencesinverse.go b/cmd/gen/conditions/tests/results/overridereferencesinverse.go new file mode 100644 index 0000000..f0433cb --- /dev/null +++ b/cmd/gen/conditions/tests/results/overridereferencesinverse.go @@ -0,0 +1,54 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + overridereferencesinverse "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/overridereferencesinverse" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func ComputerId(v orm.UUID) orm.WhereCondition[overridereferencesinverse.Computer] { + return orm.WhereCondition[overridereferencesinverse.Computer]{ + Field: "ID", + Value: v, + } +} +func ComputerCreatedAt(v time.Time) orm.WhereCondition[overridereferencesinverse.Computer] { + return orm.WhereCondition[overridereferencesinverse.Computer]{ + Field: "CreatedAt", + Value: v, + } +} +func ComputerUpdatedAt(v time.Time) orm.WhereCondition[overridereferencesinverse.Computer] { + return orm.WhereCondition[overridereferencesinverse.Computer]{ + Field: "UpdatedAt", + Value: v, + } +} +func ComputerDeletedAt(v gorm.DeletedAt) orm.WhereCondition[overridereferencesinverse.Computer] { + return orm.WhereCondition[overridereferencesinverse.Computer]{ + Field: "DeletedAt", + Value: v, + } +} +func ComputerName(v string) orm.WhereCondition[overridereferencesinverse.Computer] { + return orm.WhereCondition[overridereferencesinverse.Computer]{ + Field: "Name", + Value: v, + } +} +func ComputerProcessor(conditions ...orm.Condition[overridereferencesinverse.Processor]) orm.Condition[overridereferencesinverse.Computer] { + return orm.JoinCondition[overridereferencesinverse.Computer, overridereferencesinverse.Processor]{ + Conditions: conditions, + T1Field: "Name", + T2Field: "ComputerName", + } +} +func ProcessorComputer(conditions ...orm.Condition[overridereferencesinverse.Computer]) orm.Condition[overridereferencesinverse.Processor] { + return orm.JoinCondition[overridereferencesinverse.Processor, overridereferencesinverse.Computer]{ + Conditions: conditions, + T1Field: "ComputerName", + T2Field: "Name", + } +} diff --git a/cmd/gen/conditions/tests/results/selfreferential.go b/cmd/gen/conditions/tests/results/selfreferential.go new file mode 100644 index 0000000..78f79f3 --- /dev/null +++ b/cmd/gen/conditions/tests/results/selfreferential.go @@ -0,0 +1,47 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + selfreferential "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/selfreferential" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func EmployeeId(v orm.UUID) orm.WhereCondition[selfreferential.Employee] { + return orm.WhereCondition[selfreferential.Employee]{ + Field: "ID", + Value: v, + } +} +func EmployeeCreatedAt(v time.Time) orm.WhereCondition[selfreferential.Employee] { + return orm.WhereCondition[selfreferential.Employee]{ + Field: "CreatedAt", + Value: v, + } +} +func EmployeeUpdatedAt(v time.Time) orm.WhereCondition[selfreferential.Employee] { + return orm.WhereCondition[selfreferential.Employee]{ + Field: "UpdatedAt", + Value: v, + } +} +func EmployeeDeletedAt(v gorm.DeletedAt) orm.WhereCondition[selfreferential.Employee] { + return orm.WhereCondition[selfreferential.Employee]{ + Field: "DeletedAt", + Value: v, + } +} +func EmployeeBoss(conditions ...orm.Condition[selfreferential.Employee]) orm.Condition[selfreferential.Employee] { + return orm.JoinCondition[selfreferential.Employee, selfreferential.Employee]{ + Conditions: conditions, + T1Field: "BossID", + T2Field: "ID", + } +} +func EmployeeBossId(v orm.UUID) orm.WhereCondition[selfreferential.Employee] { + return orm.WhereCondition[selfreferential.Employee]{ + Field: "BossID", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/uintmodel.go b/cmd/gen/conditions/tests/results/uintmodel.go new file mode 100644 index 0000000..ae351ac --- /dev/null +++ b/cmd/gen/conditions/tests/results/uintmodel.go @@ -0,0 +1,34 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + uintmodel "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/uintmodel" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func UintModelId(v uint) orm.WhereCondition[uintmodel.UintModel] { + return orm.WhereCondition[uintmodel.UintModel]{ + Field: "ID", + Value: v, + } +} +func UintModelCreatedAt(v time.Time) orm.WhereCondition[uintmodel.UintModel] { + return orm.WhereCondition[uintmodel.UintModel]{ + Field: "CreatedAt", + Value: v, + } +} +func UintModelUpdatedAt(v time.Time) orm.WhereCondition[uintmodel.UintModel] { + return orm.WhereCondition[uintmodel.UintModel]{ + Field: "UpdatedAt", + Value: v, + } +} +func UintModelDeletedAt(v gorm.DeletedAt) orm.WhereCondition[uintmodel.UintModel] { + return orm.WhereCondition[uintmodel.UintModel]{ + Field: "DeletedAt", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/results/uuidmodel.go b/cmd/gen/conditions/tests/results/uuidmodel.go new file mode 100644 index 0000000..82cbaba --- /dev/null +++ b/cmd/gen/conditions/tests/results/uuidmodel.go @@ -0,0 +1,34 @@ +// Code generated by badaas-cli v0.0.0, DO NOT EDIT. +package conditions + +import ( + uuidmodel "github.com/ditrit/badaas-cli/cmd/gen/conditions/tests/uuidmodel" + orm "github.com/ditrit/badaas/orm" + gorm "gorm.io/gorm" + "time" +) + +func UUIDModelId(v orm.UUID) orm.WhereCondition[uuidmodel.UUIDModel] { + return orm.WhereCondition[uuidmodel.UUIDModel]{ + Field: "ID", + Value: v, + } +} +func UUIDModelCreatedAt(v time.Time) orm.WhereCondition[uuidmodel.UUIDModel] { + return orm.WhereCondition[uuidmodel.UUIDModel]{ + Field: "CreatedAt", + Value: v, + } +} +func UUIDModelUpdatedAt(v time.Time) orm.WhereCondition[uuidmodel.UUIDModel] { + return orm.WhereCondition[uuidmodel.UUIDModel]{ + Field: "UpdatedAt", + Value: v, + } +} +func UUIDModelDeletedAt(v gorm.DeletedAt) orm.WhereCondition[uuidmodel.UUIDModel] { + return orm.WhereCondition[uuidmodel.UUIDModel]{ + Field: "DeletedAt", + Value: v, + } +} diff --git a/cmd/gen/conditions/tests/selfreferential/selfreferential.go b/cmd/gen/conditions/tests/selfreferential/selfreferential.go new file mode 100644 index 0000000..3223518 --- /dev/null +++ b/cmd/gen/conditions/tests/selfreferential/selfreferential.go @@ -0,0 +1,10 @@ +package selfreferential + +import "github.com/ditrit/badaas/orm" + +type Employee struct { + orm.UUIDModel + + Boss *Employee `gorm:"constraint:OnDelete:SET NULL;"` // Self-Referential Has One (Employee 0..* -> 0..1 Employee) + BossID *orm.UUID +} diff --git a/cmd/gen/conditions/tests/uintmodel/uintmodel.go b/cmd/gen/conditions/tests/uintmodel/uintmodel.go new file mode 100644 index 0000000..39046fc --- /dev/null +++ b/cmd/gen/conditions/tests/uintmodel/uintmodel.go @@ -0,0 +1,7 @@ +package uintmodel + +import "github.com/ditrit/badaas/orm" + +type UintModel struct { + orm.UIntModel +} diff --git a/cmd/gen/conditions/tests/uuidmodel/uuidmodel.go b/cmd/gen/conditions/tests/uuidmodel/uuidmodel.go new file mode 100644 index 0000000..4df2fdc --- /dev/null +++ b/cmd/gen/conditions/tests/uuidmodel/uuidmodel.go @@ -0,0 +1,7 @@ +package uuidmodel + +import "github.com/ditrit/badaas/orm" + +type UUIDModel struct { + orm.UUIDModel +} diff --git a/cmd/gen/conditions/type.go b/cmd/gen/conditions/type.go new file mode 100644 index 0000000..8718476 --- /dev/null +++ b/cmd/gen/conditions/type.go @@ -0,0 +1,98 @@ +package conditions + +import ( + "fmt" + "go/types" + "regexp" + "strings" + + "github.com/elliotchance/pie/v2" +) + +// badaas/orm/baseModels.go +var badaasORMBaseModels = []string{"github.com/ditrit/badaas/orm.UUIDModel", "github.com/ditrit/badaas/orm.UIntModel", "gorm.io/gorm.Model"} + +type Type struct { + types.Type +} + +// Get the name of the type depending of the internal type +func (t Type) Name() string { + switch typeTyped := t.Type.(type) { + case *types.Named: + return typeTyped.Obj().Name() + default: + return pie.Last(strings.Split(t.String(), ".")) + } +} + +// Get the package of the type depending of the internal type +func (t Type) Pkg() *types.Package { + switch typeTyped := t.Type.(type) { + case *types.Named: + return typeTyped.Obj().Pkg() + default: + return nil + } +} + +// Get the struct under type if it is a Badaas model +// Returns error if the type is not a Badaas model +func (t Type) BadaasModelStruct() (*types.Struct, error) { + structType, ok := t.Underlying().(*types.Struct) + if !ok || !isBadaasModel(structType) { + return nil, fmt.Errorf("type %s is not a Badaas Model", t.String()) + } + + return structType, nil +} + +// Returns true if the type is a Badaas model +func isBadaasModel(structType *types.Struct) bool { + for i := 0; i < structType.NumFields(); i++ { + field := structType.Field(i) + + if field.Embedded() && pie.Contains(badaasORMBaseModels, field.Type().String()) { + return true + } + } + + return false +} + +// Returns true is the type has a foreign key to the field's object +// (another field that references that object) +func (t Type) HasFK(field Field) (bool, error) { + objectFields, err := getFields(t, "") + if err != nil { + return false, err + } + return pie.Any(objectFields, func(otherField Field) bool { + return otherField.Name == field.getFKAttribute() + }), nil +} + +var scanMethod = regexp.MustCompile(`func \(\*.*\)\.Scan\([a-zA-Z0-9_-]* interface\{\}\) error$`) +var valueMethod = regexp.MustCompile(`func \(.*\)\.Value\(\) \(database/sql/driver\.Value\, error\)$`) + +// Returns true if the type is a Gorm Custom type (https://gorm.io/docs/data_types.html) +func (t Type) IsGormCustomType() bool { + typeNamed, isNamedType := t.Type.(*types.Named) + if !isNamedType { + return false + } + + hasScanMethod := false + hasValueMethod := false + for i := 0; i < typeNamed.NumMethods(); i++ { + methodSignature := typeNamed.Method(i).String() + + if !hasScanMethod && scanMethod.MatchString(methodSignature) { + hasScanMethod = true + } else if !hasValueMethod && valueMethod.MatchString(methodSignature) { + hasValueMethod = true + } + } + + return hasScanMethod && hasValueMethod +} diff --git a/cmd/gen/config/badaas.yml b/cmd/gen/config/badaas.yml new file mode 100644 index 0000000..5628860 --- /dev/null +++ b/cmd/gen/config/badaas.yml @@ -0,0 +1,28 @@ +database: + host: badaas-db + name: badaas_db + password: postgres + sslmode: disable + username: root + port: 26257 + init: + retry: 10 + retryTime: 5 +server: + host: "" + port: 8000 + timeout: 15 + pagination: + page: + max: 100 +logger: + mode: prod + request: + template: "Receive {{method}} request on {{url}}" +session: + duration: 14400 + pullInterval: 30 + rollDuration: 3600 +default: + admin: + password: admin \ No newline at end of file diff --git a/cmd/gen/docker.go b/cmd/gen/docker.go new file mode 100644 index 0000000..313028b --- /dev/null +++ b/cmd/gen/docker.go @@ -0,0 +1,100 @@ +package gen + +import ( + "embed" + "fmt" + "os" + "path/filepath" + + "github.com/spf13/cobra" + + "github.com/ditrit/verdeter" +) + +// File system embed in the executable that will have the following files: +// +//go:embed docker/* +//go:embed config/* +var genEmbedFS embed.FS + +// genCommand represents the badaas-cli gen command +var genDockerCmd = verdeter.BuildVerdeterCommand(verdeter.VerdeterConfig{ + Use: "docker", + Short: "Generate files and configurations necessary to use badaas over docker", + Long: `gen docker is the command you can use to generate the files and configurations necessary for your project to use BadAss in a simple way.`, + Run: generateDockerFiles, +}) + +// directory where the generated files will be saved +const destBadaasDir = "badaas" + +// copies all docker and configurations related files from the embed file system to the destination folder +func generateDockerFiles(cmd *cobra.Command, args []string) { + sourceDockerDir := "docker" + + copyDir( + filepath.Join(sourceDockerDir, "db"), + filepath.Join(destBadaasDir, "docker", "db"), + ) + + copyDir( + filepath.Join(sourceDockerDir, "api"), + filepath.Join(destBadaasDir, "docker", "api"), + ) + + copyFile( + filepath.Join(sourceDockerDir, ".dockerignore"), + ".dockerignore", + ) + + copyFile( + filepath.Join(sourceDockerDir, "Makefile"), + "Makefile", + ) + + copyDir( + "config", + filepath.Join(destBadaasDir, "config"), + ) +} + +// copies a file from the embed file system to the destination folder +func copyFile(sourcePath, destPath string) { + fileContent, err := genEmbedFS.ReadFile(sourcePath) + if err != nil { + panic(fmt.Errorf("error reading source file %s: %w", sourcePath, err)) + } + + if err := os.WriteFile(destPath, fileContent, 0o0600); err != nil { + panic(fmt.Errorf("error writing on destination file %s: %w", destPath, err)) + } +} + +// copies a directory from the embed file system to the destination folder +func copyDir(sourceDir, destDir string) { + files, err := genEmbedFS.ReadDir(sourceDir) + if err != nil { + panic(fmt.Errorf("error reading source directory %s: %w", sourceDir, err)) + } + + fileInfo, err := os.Stat(destDir) + if err != nil { + if !os.IsNotExist(err) { + panic(fmt.Errorf("error running stat on %s: %w", destDir, err)) + } + + err = os.MkdirAll(destDir, os.ModePerm) + if err != nil { + panic(fmt.Errorf("error creating directory %s: %w", destDir, err)) + } + } else if !fileInfo.IsDir() { + panic(fmt.Errorf("destination path %s is not a directory", destDir)) + } + + for _, file := range files { + copyFile( + filepath.Join(sourceDir, file.Name()), + filepath.Join(destDir, file.Name()), + ) + } +} diff --git a/cmd/gen/docker/.dockerignore b/cmd/gen/docker/.dockerignore new file mode 100644 index 0000000..f7db608 --- /dev/null +++ b/cmd/gen/docker/.dockerignore @@ -0,0 +1,11 @@ +# general +.editorconfig +.git +.gitignore +.github +*.md +LICENSE +.vscode + +# badaas +badaas/docker diff --git a/cmd/gen/docker/Makefile b/cmd/gen/docker/Makefile new file mode 100644 index 0000000..634c8ef --- /dev/null +++ b/cmd/gen/docker/Makefile @@ -0,0 +1,2 @@ +badaas_run: + docker compose -f badaas/docker/db/docker-compose.yml -f badaas/docker/api/docker-compose.yml up --build -d \ No newline at end of file diff --git a/cmd/gen/docker/api/Dockerfile b/cmd/gen/docker/api/Dockerfile new file mode 100644 index 0000000..1ea62ae --- /dev/null +++ b/cmd/gen/docker/api/Dockerfile @@ -0,0 +1,17 @@ +# builder image +FROM golang:1.19-alpine AS builder +RUN apk add build-base +WORKDIR /app +COPY . . +RUN CGO_ENABLED=1 go build -o badaas_service -a . + + +# final image for end users +FROM alpine:3.16.2 +RUN addgroup -S badaas \ + && adduser -S badaas -G badaas +USER badaas +COPY --from=builder /app/badaas_service . +COPY ./badaas/config/badaas.yml . +EXPOSE 8000 +ENTRYPOINT ["./badaas_service", "--config_path", "badaas.yml"] \ No newline at end of file diff --git a/cmd/gen/docker/api/docker-compose.yml b/cmd/gen/docker/api/docker-compose.yml new file mode 100644 index 0000000..6fc1187 --- /dev/null +++ b/cmd/gen/docker/api/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3.5' + +services: + api: + image: badaas-api:latest + build: + context: ../../.. + dockerfile: ./badaas/docker/api/Dockerfile + container_name: "badaas-api" + ports: + - "8000:8000" + depends_on: + - db diff --git a/cmd/gen/docker/db/docker-compose.yml b/cmd/gen/docker/db/docker-compose.yml new file mode 100644 index 0000000..d249a53 --- /dev/null +++ b/cmd/gen/docker/db/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.5' + +services: + db: + image: cockroachdb/cockroach:latest + container_name: badaas-db + ports: + - "8080:8080" # Web based dashboard + # TODO make this container secure + command: start-single-node --insecure + volumes: + - "${PWD}/badaas/docker/db/.cockroach-data:/cockroach/cockroach-data" + environment: + - COCKROACH_USER=root + - COCKROACH_DATABASE=badaas_db diff --git a/cmd/gen/docker_test.go b/cmd/gen/docker_test.go new file mode 100644 index 0000000..d20a7f7 --- /dev/null +++ b/cmd/gen/docker_test.go @@ -0,0 +1,179 @@ +package gen + +import ( + "os" + "path/filepath" + "testing" + + "github.com/ditrit/badaas-cli/cmd/utils" + "github.com/stretchr/testify/assert" +) + +func TestGenerateDockerFilesCreateFilesWhenDestinationFolderNotExists(t *testing.T) { + generateDockerFiles(nil, nil) + checkFilesExist(t) + teardown() +} + +func TestGenerateDockerFilesOverwriteFilesWhenDestinationFolderExists(t *testing.T) { + destDir := filepath.Join("badaas", "docker", "db") + err := os.MkdirAll(destDir, os.ModePerm) + assert.Nil(t, err) + + destFile := filepath.Join(destDir, "docker-compose.yml") + err = os.WriteFile(destFile, []byte("hello"), 0o0600) + assert.Nil(t, err) + + generateDockerFiles(nil, nil) + checkFilesExist(t) + + fileContent, err := os.ReadFile(destFile) + assert.Nil(t, err) + assert.NotEqual(t, string(fileContent), "hello") + + teardown() +} + +func TestCopyDirCreatesDestinationDirIfItDoesNotExist(t *testing.T) { + copyDir( + filepath.Join("docker", "db"), + filepath.Join("badaas", "docker", "db"), + ) + checkDockerDBFilesExist(t) + teardown() +} + +func TestCopyDirCopyFilesIfTheDestinationFolderAlreadyExists(t *testing.T) { + destDir := filepath.Join("badaas", "docker", "db") + err := os.MkdirAll(destDir, os.ModePerm) + assert.Nil(t, err) + + copyDir(filepath.Join("docker", "db"), destDir) + checkDockerDBFilesExist(t) + teardown() +} + +func TestCopyDirPanicsIfStatOnDestDirIsNotPossible(t *testing.T) { + assertPanic(t, func() { + copyDir(filepath.Join("docker", "db"), "\000") + }, "error running stat") +} + +func TestCopyDirPanicsIfDestDirCreationFails(t *testing.T) { + assertPanic(t, func() { + copyDir(filepath.Join("docker", "db"), "") + }, "error creating directory") +} + +func TestCopyDirPanicsIfReadOnEmbedFileSystemIsNotPossible(t *testing.T) { + assertPanic(t, func() { + copyDir("not_exists", filepath.Join("badaas", "docker", "db")) + }, "error reading source directory") +} + +func TestCopyDirPanicsIfDestDirIsNotADirectory(t *testing.T) { + err := os.WriteFile("file.txt", []byte("hello"), 0o0600) + assert.Nil(t, err) + + assertPanic(t, func() { + copyDir(filepath.Join("docker", "db"), "file.txt") + }, "destination path file.txt is not a directory") +} + +func TestCopyFilePanicsWhenDestPathDoesNotExist(t *testing.T) { + assertPanic(t, func() { + copyFile( + filepath.Join("docker", "db", "docker-compose.yml"), + filepath.Join("badaas", "docker", "db", "docker-compose.yml"), + ) + }, "error writing on destination file") +} + +func TestCopyFileWorksWhenDestPathAlreadyExistsButNotTheFile(t *testing.T) { + destDir := filepath.Join("badaas", "docker", "db") + err := os.MkdirAll(destDir, os.ModePerm) + assert.Nil(t, err) + + copyFile( + filepath.Join("docker", "db", "docker-compose.yml"), + filepath.Join(destDir, "docker-compose.yml"), + ) + checkDockerDBFilesExist(t) + teardown() +} + +func TestCopyFileWorksWhenDestPathAndFileAlready(t *testing.T) { + destDir := filepath.Join("badaas", "docker", "db") + err := os.MkdirAll(destDir, os.ModePerm) + assert.Nil(t, err) + destFile := filepath.Join(destDir, "docker-compose.yml") + err = os.WriteFile(destFile, []byte("hello"), 0o0600) + assert.Nil(t, err) + + copyFile(filepath.Join("docker", "db", "docker-compose.yml"), destFile) + + checkDockerDBFilesExist(t) + fileContent, err := os.ReadFile(destFile) + assert.Nil(t, err) + assert.NotEqual(t, string(fileContent), "hello") + + teardown() +} + +func TestCopyFilePanicsIfReadOnEmbedFileSystemIsNotPossible(t *testing.T) { + assertPanic(t, func() { + copyFile( + filepath.Join("docker", "db", "not_exists"), + filepath.Join("badaas", "docker", "db"), + ) + }, "error reading source file") +} + +func TestCopyFilePanicsIfDestPathIsADirectory(t *testing.T) { + err := os.MkdirAll("badaas", os.ModePerm) + assert.Nil(t, err) + + assertPanic(t, func() { + copyFile(filepath.Join("docker", "db", "docker-compose.yml"), "badaas/") + }, "error writing on destination file") + + teardown() +} + +func TestCopyFilePanicsIfWriteOnDestPathIsNotPossible(t *testing.T) { + assertPanic(t, func() { + copyFile(filepath.Join("docker", "db", "docker-compose.yml"), "/badaas.txt") + }, "permission denied") +} + +func assertPanic(t *testing.T, functionShouldPanic func(), errorMessage string) { + defer func() { + if r := recover(); r == nil { + t.Errorf("The function did not panic") + } else { + err := r.(error) + assert.ErrorContains(t, err, errorMessage) + } + }() + functionShouldPanic() +} + +func checkFilesExist(t *testing.T) { + utils.CheckFileExists(t, ".dockerignore") + utils.CheckFileExists(t, "Makefile") + utils.CheckFileExists(t, filepath.Join("badaas", "config", "badaas.yml")) + utils.CheckFileExists(t, filepath.Join("badaas", "docker", "api", "docker-compose.yml")) + utils.CheckFileExists(t, filepath.Join("badaas", "docker", "api", "Dockerfile")) + checkDockerDBFilesExist(t) +} + +func checkDockerDBFilesExist(t *testing.T) { + utils.CheckFileExists(t, filepath.Join("badaas", "docker", "db", "docker-compose.yml")) +} + +func teardown() { + utils.RemoveFile(".dockerignore") + utils.RemoveFile("Makefile") + utils.RemoveFile("file.txt") + utils.RemoveFile("badaas") +} diff --git a/cmd/gen/gen.go b/cmd/gen/gen.go new file mode 100644 index 0000000..4e97bad --- /dev/null +++ b/cmd/gen/gen.go @@ -0,0 +1,17 @@ +package gen + +import ( + "github.com/ditrit/badaas-cli/cmd/gen/conditions" + "github.com/ditrit/verdeter" +) + +var GenCmd = verdeter.BuildVerdeterCommand(verdeter.VerdeterConfig{ + Use: "gen", + Short: "Files and configurations generator", + Long: `gen is the command you can use to generate the files and configurations necessary for your project to use BadAss in a simple way.`, +}) + +func init() { + GenCmd.AddSubCommand(genDockerCmd) + GenCmd.AddSubCommand(conditions.GenConditionsCmd) +} diff --git a/cmd/log/config.go b/cmd/log/config.go new file mode 100644 index 0000000..e56bfcd --- /dev/null +++ b/cmd/log/config.go @@ -0,0 +1,23 @@ +package log + +import ( + "github.com/ditrit/badaas-cli/cmd/version" + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +var Logger = log.WithField("version", version.Version) + +const VerboseKey = "verbose" + +func init() { + log.SetFormatter(&log.TextFormatter{}) + log.SetLevel(log.InfoLevel) +} + +func SetLevel() { + verbose := viper.GetBool(VerboseKey) + if verbose { + log.SetLevel(log.DebugLevel) + } +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..39dbdc3 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,35 @@ +package cmd + +import ( + "github.com/ditrit/badaas-cli/cmd/gen" + "github.com/ditrit/badaas-cli/cmd/log" + "github.com/ditrit/badaas-cli/cmd/version" + "github.com/ditrit/verdeter" +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = verdeter.BuildVerdeterCommand(verdeter.VerdeterConfig{ + Use: "badaas-cli", + Short: "the badaas command line client", + Long: `badaas-cli is the command line tool that makes it possible to configure and run your badaas applications easily.`, + Version: version.Version, +}) + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + rootCmd.Execute() +} + +func init() { + rootCmd.AddSubCommand(gen.GenCmd) + + err := rootCmd.GKey( + log.VerboseKey, verdeter.IsBool, "v", + "Verbose logging", + ) + if err != nil { + panic(err) + } + rootCmd.SetDefault(log.VerboseKey, false) +} diff --git a/cmd/utils/file.go b/cmd/utils/file.go new file mode 100644 index 0000000..add5520 --- /dev/null +++ b/cmd/utils/file.go @@ -0,0 +1,24 @@ +package utils + +import ( + "io/fs" + "log" + "os" + "testing" +) + +func CheckFileExists(t *testing.T, name string) fs.FileInfo { + stat, err := os.Stat(name) + if err != nil { + t.Error(err) + } + + return stat +} + +func RemoveFile(name string) { + err := os.RemoveAll(name) + if err != nil { + log.Fatal(err) + } +} diff --git a/cmd/version/version.go b/cmd/version/version.go new file mode 100644 index 0000000..415100d --- /dev/null +++ b/cmd/version/version.go @@ -0,0 +1,3 @@ +package version + +var Version = "0.0.0" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4dfffda --- /dev/null +++ b/go.mod @@ -0,0 +1,57 @@ +module github.com/ditrit/badaas-cli + +go 1.18 + +require ( + github.com/dave/jennifer v1.6.1 + github.com/ditrit/badaas v0.0.0-20230801092312-f93496a71501 + github.com/ditrit/verdeter v0.4.0 + github.com/elliotchance/pie/v2 v2.7.0 + github.com/ettle/strcase v0.1.1 + github.com/fatih/structtag v1.2.0 + github.com/sirupsen/logrus v1.9.3 + github.com/spf13/cobra v1.7.0 + github.com/spf13/viper v1.16.0 + github.com/stretchr/testify v1.8.4 + golang.org/x/tools v0.11.1 + gorm.io/gorm v1.25.1 + gotest.tools v2.2.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.3.1 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/dig v1.17.0 // indirect + go.uber.org/fx v1.19.3 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.9.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + gorm.io/driver/postgres v1.5.2 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c4bf298 --- /dev/null +++ b/go.sum @@ -0,0 +1,547 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/dave/jennifer v1.6.1 h1:T4T/67t6RAA5AIV6+NP8Uk/BIsXgDoqEowgycdQQLuk= +github.com/dave/jennifer v1.6.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ditrit/badaas v0.0.0-20230801092312-f93496a71501 h1:pnPSbgcYboxR8SLQg49yZuxRIL6Fs3+YAGfMnMEuqV4= +github.com/ditrit/badaas v0.0.0-20230801092312-f93496a71501/go.mod h1:FS3I+obfV7FiYp3tUbZObckOclqmEPtGwTXsGOk8WJs= +github.com/ditrit/verdeter v0.4.0 h1:DzEOFauuXEGNQYP6OgYtHwEyb3w9riem99u0xE/l7+o= +github.com/ditrit/verdeter v0.4.0/go.mod h1:sKpWuOvYqNabLN4aNXqeBhcWpt7nf0frwqk0B5M6ax0= +github.com/elliotchance/pie/v2 v2.7.0 h1:FqoIKg4uj0G/CrLGuMS9ejnFKa92lxE1dEgBD3pShXg= +github.com/elliotchance/pie/v2 v2.7.0/go.mod h1:18t0dgGFH006g4eVdDtWfgFZPQEgl10IoEO8YWEq3Og= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= +github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= +go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= +go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 h1:ba9YlqfDGTTQ5aZ2fwOoQ1hf32QySyQkR6ODGDzHlnE= +golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.11.1 h1:ojD5zOW8+7dOGzdnNgersm8aPfcDjhMp12UfG93NIMc= +golang.org/x/tools v0.11.1/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0= +gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8= +gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64= +gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/main.go b/main.go new file mode 100644 index 0000000..3a3c979 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/ditrit/badaas-cli/cmd" + +func main() { + cmd.Execute() +} diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..fa62460 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,13 @@ +sonar.projectKey=ditrit_badaas-cli +sonar.organization=ditrit +sonar.projectName=badaas-cli +sonar.host.url=https://sonarcloud.io +sonar.sources=. +# as cmd/docker/api/Dockerfile will be used by the user, +# we can't avoid doing COPY . . because we don't know the project structure. +# Anyway, this is done in the builder image, +# so it is not a safety risk even if sonar marks it as such. +sonar.exclusions=**/*_test.go,mocks/***,vendor/***,cmd/gen/docker/api/Dockerfile +sonar.tests=. +sonar.test.inclusions=**/*_test.go,cmd/gen/conditions/tests/*** +sonar.go.coverage.reportPaths=coverage_unit.out/coverage_unit.out \ No newline at end of file