├── .github
├── .golangci.yml
├── FUNDING.yml
└── workflows
│ ├── build.yml
│ ├── verify-all-committed.yml
│ └── verify-templates.yml
├── LICENSE
├── cli
├── cli.go
└── cli_test.go
├── codegen
├── codegen.go
└── codegen_test.go
├── docs
├── CNAME
├── README.md
├── README_by.md
├── README_es.md
├── README_fr.md
├── README_he.md
├── README_id.md
├── README_jp.md
├── README_ko.md
├── README_pt-br.md
├── README_tr.md
├── README_ua.md
├── README_zh.md
├── _config.yml
├── _includes
│ ├── footer.html
│ ├── head.html
│ └── header.html
├── android-chrome-192x192.png
├── apple-touch-icon.png
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── flag-by.svg
├── logo.svg
└── showcase.gif
├── go.mod
├── main.go
├── static
└── generated.go
├── templates
├── .dockerignore
├── .gitignore
├── angular.webapp
│ ├── .editorconfig
│ ├── .gitignore
│ ├── .vscode
│ │ ├── extensions.json
│ │ ├── launch.json
│ │ └── tasks.json
│ ├── angular.json
│ ├── package.json
│ ├── src
│ │ ├── app
│ │ │ ├── app.component.css
│ │ │ ├── app.component.html
│ │ │ ├── app.component.ts
│ │ │ ├── app.module.ts
│ │ │ └── tech
│ │ │ │ ├── tech.component.html
│ │ │ │ ├── tech.component.ts
│ │ │ │ ├── tech.model.ts
│ │ │ │ └── tech.service.ts
│ │ ├── assets
│ │ │ ├── .gitkeep
│ │ │ └── logo.svg
│ │ ├── environments
│ │ │ ├── environment.development.ts
│ │ │ └── environment.ts
│ │ ├── favico.ico
│ │ ├── index.html
│ │ ├── main.ts
│ │ └── styles.css
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ └── tsconfig.spec.json
├── mongo.Dockerfile
├── mongo.README.md
├── mongo.docker-compose-dev.yml
├── mongo.docker-compose.yml
├── mongo.init-db.js
├── mongo.server
│ ├── db
│ │ └── db.go
│ ├── go.mod
│ ├── go.sum
│ └── server.go
├── mysql.Dockerfile
├── mysql.README.md
├── mysql.docker-compose-dev.yml
├── mysql.docker-compose.yml
├── mysql.init-db.sql
├── mysql.server
│ ├── db
│ │ └── db.go
│ ├── go.mod
│ ├── go.sum
│ └── server.go
├── postgres.Dockerfile
├── postgres.README.md
├── postgres.docker-compose-dev.yml
├── postgres.docker-compose.yml
├── postgres.init-db.sql
├── postgres.server
│ ├── db
│ │ └── db.go
│ ├── go.mod
│ ├── go.sum
│ └── server.go
├── react.webapp
│ ├── .env.development
│ ├── .env.production
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── Logo.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── setupTests.js
│ │ └── tech
│ │ ├── Tech.css
│ │ └── Tech.js
├── server
│ ├── model
│ │ └── technology.go
│ └── web
│ │ ├── app.go
│ │ └── app_test.go
└── vue.webapp
│ ├── .env.local
│ ├── .env.production
│ ├── .eslintrc.cjs
│ ├── .vscode
│ └── extensions.json
│ ├── index.html
│ ├── package.json
│ ├── public
│ └── favicon.ico
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.svg
│ ├── components
│ │ └── TechItems.vue
│ └── main.js
│ └── vite.config.js
└── transform
├── go.mod
├── transformer.go
└── transformer_test.go
/.github/.golangci.yml:
--------------------------------------------------------------------------------
1 | run:
2 | output:
3 | format: tab
4 | issues:
5 | exclude-dirs:
6 | - templates
7 | linters:
8 | disable-all: true
9 | enable:
10 | - bodyclose
11 | - depguard
12 | - dogsled
13 | - dupl
14 | - errcheck
15 | - funlen
16 | - gochecknoinits
17 | - goconst
18 | - gocritic
19 | - gocyclo
20 | - gofmt
21 | - mnd
22 | - goprintffuncname
23 | - gosec
24 | - gosimple
25 | - govet
26 | - ineffassign
27 | - lll
28 | - misspell
29 | - nakedret
30 | - rowserrcheck
31 | - staticcheck
32 | - stylecheck
33 | - typecheck
34 | - unconvert
35 | - unparam
36 | - unused
37 | - whitespace
38 | - gocognit
39 | - godox
40 | - prealloc
41 | linters-settings:
42 | depguard:
43 | rules:
44 | prevent_unmaintained_packages:
45 | list-mode: lax # allow unless explicitely denied
46 | files:
47 | - $all
48 | - "!$test"
49 | allow:
50 | - github.com/Shpota/goxygen
51 | deny:
52 | - pkg: io/ioutil
53 | desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
54 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [Shpota]
2 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 | on: [push, pull_request]
3 | jobs:
4 |
5 | test:
6 | name: Build & Test
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v4
11 | - name: Set up go 1.22
12 | uses: actions/setup-go@v4
13 | with:
14 | go-version: '1.22'
15 | id: go
16 | - name: Build
17 | run: go build .
18 | - name: Test
19 | run: go test -v . ./cli ./codegen
20 | - name: Test Transformer
21 | run: cd transform && go test ./...
22 | - name: Lint
23 | run: |
24 | docker run -v $(pwd):/app -w /app golangci/golangci-lint:v1.61-alpine \
25 | golangci-lint run --config .github/.golangci.yml cli codegen static .
26 |
27 | build:
28 | name: Build
29 | runs-on: ubuntu-latest
30 | strategy:
31 | fail-fast: false
32 | matrix:
33 | go: [ '1.16', '1.17', '1.18', '1.19', '1.20', '1.21' ]
34 | steps:
35 | - name: Checkout
36 | uses: actions/checkout@v4
37 | - name: Set up Go ${{ matrix.go }}
38 | uses: actions/setup-go@v5
39 | with:
40 | go-version: ${{ matrix.go }}
41 | id: go
42 | - name: Build
43 | run: go build .
44 |
--------------------------------------------------------------------------------
/.github/workflows/verify-all-committed.yml:
--------------------------------------------------------------------------------
1 | name: Verify template changes are committed
2 | on: [push]
3 | jobs:
4 | verify:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: actions/checkout@v4
8 | - uses: actions/setup-go@v5
9 | with:
10 | go-version: '1.23'
11 | - name: Generate and format code
12 | run: |
13 | go generate ./...
14 | go fmt ./...
15 | - name: Check for changes
16 | run: |
17 | if [ -n "$(git status --porcelain)" ]; then
18 | echo "Generated files are not up to date!"
19 | git status
20 | exit 1
21 | fi
--------------------------------------------------------------------------------
/.github/workflows/verify-templates.yml:
--------------------------------------------------------------------------------
1 | name: verify-templates
2 | on:
3 | push:
4 | pull_request:
5 | schedule:
6 | - cron: '0 14 * * *'
7 | jobs:
8 |
9 | build:
10 | name: Test generated project
11 | runs-on: ubuntu-latest
12 | strategy:
13 | fail-fast: false
14 | matrix:
15 | db: [mongo, mysql, postgres]
16 | frontend: [angular, vue, react]
17 | steps:
18 | - name: Checkout project
19 | uses: actions/checkout@v4
20 | - name: Set up Go
21 | uses: actions/setup-go@v5
22 | with:
23 | go-version: '1.22'
24 | - name: Generate application
25 | run: go run main.go init --db ${{ matrix.db }} --frontend ${{ matrix.frontend }} app
26 | - name: Start the application
27 | run: cd app && docker compose up -d
28 | - name: Check availability of backend
29 | run: timeout 60 bash -c 'until curl -s localhost:8080/api/technologies | grep Go > /dev/null; do sleep 1; done'
30 | - name: Check availability of frontend
31 | run: |
32 | npm i puppeteer
33 | cat > index.js << EOF
34 | const puppeteer = require('puppeteer');
35 | (async () => {
36 | try {
37 | const browser = await puppeteer.launch({
38 | headless: "new",
39 | args: ['--no-sandbox', '--disable-setuid-sandbox']
40 | });
41 | const page = await browser.newPage();
42 | await page.goto('http://localhost:8080');
43 | page.on('console', (message) => {
44 | console.log('Console ' + message.type().toUpperCase() + ': ' + message.text());
45 | });
46 | await page.waitForSelector('.technologies', { timeout: 60000 });
47 | const content = await page.content();
48 | console.log(content);
49 | await browser.close();
50 | } catch (error) {
51 | console.error('Error:', error);
52 | throw error;
53 | }
54 | })();
55 | EOF
56 | node index.js
57 | - name: Stop application
58 | run: cd app && docker compose down
59 | if: always()
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [2020] [Oleksandr Shpota]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/cli/cli.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "io"
7 | "regexp"
8 | )
9 |
10 | type flag struct {
11 | name string
12 | options []string
13 | defaultValue string
14 | }
15 |
16 | func (f flag) valid(input string) bool {
17 | for _, val := range f.options {
18 | if input == val {
19 | return true
20 | }
21 | }
22 | return false
23 | }
24 |
25 | func Start(w io.Writer, commands []string, generate func(string, []string)) {
26 | if len(commands) == 1 && commands[0] == "help" {
27 | fmt.Fprintln(w, usage)
28 | return
29 | }
30 | if len(commands) >= 2 && commands[0] == "init" {
31 | projectName := commands[len(commands)-1]
32 | input := commands[1 : len(commands)-1]
33 | values, err := parseFlags(input, flags())
34 | if err != nil {
35 | fmt.Fprintln(w, "Wrong input: "+err.Error())
36 | fmt.Fprintln(w, usage)
37 | return
38 | }
39 | validName, _ := regexp.MatchString("^[a-zA-Z0-9_-]+quot;, projectName)
40 | if !validName {
41 | fmt.Fprintln(w, invalidName)
42 | return
43 | }
44 | generate(projectName, values)
45 | return
46 | }
47 | fmt.Fprintln(w, "Wrong input!")
48 | fmt.Fprintln(w, usage)
49 | }
50 |
51 | // Retrieves flag values from user input matching them
52 | // against the flags. Returns a map of flags with
53 | // their values or error in case of invalid input.
54 | func parseFlags(input []string, flags []flag) ([]string, error) {
55 | paramCount := 0
56 | values := make([]string, 0, len(flags))
57 | for _, fl := range flags {
58 | var value string
59 | for index, val := range input {
60 | if val == fl.name && len(input) > index+1 {
61 | value = input[index+1]
62 | if !fl.valid(value) {
63 | return nil, errors.New(`invalid value of "` + fl.name + `" flag`)
64 | }
65 | }
66 | }
67 | if value == "" {
68 | value = fl.defaultValue
69 | } else {
70 | paramCount += 2
71 | }
72 | values = append(values, value)
73 | }
74 | if paramCount != len(input) {
75 | return nil, errors.New("flag mismatch")
76 | }
77 | return values, nil
78 | }
79 |
80 | func flags() []flag {
81 | return []flag{
82 | {"--frontend", []string{"angular", "react", "vue"}, "react"},
83 | {"--db", []string{"mongo", "mysql", "postgres"}, "mongo"},
84 | }
85 | }
86 |
87 | const usage = `Usage:
88 |
89 | go run github.com/shpota/goxygen init [options] <project-directory>
90 |
91 | Options:
92 |
93 | --frontend <framework-name> Specify the front end framework. Possible ` +
94 | `options are "angular", "react" and "vue". If not specified "react" is used.
95 | --db <db-name> Specify the database. Possible options are ` +
96 | `"mongo" "mysql" and "postgres". If not specified "mongo" is used.`
97 |
98 | const invalidName = "Project name is not valid. The allowed symbols are " +
99 | "letters, numbers, underscores, and dashes."
100 |
--------------------------------------------------------------------------------
/cli/cli_test.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | "reflect"
7 | "strings"
8 | "testing"
9 | )
10 |
11 | func TestStart(t *testing.T) {
12 | w := &bytes.Buffer{}
13 | var pjName string
14 | var techStack []string
15 | generate := func(pj string, tech []string) {
16 | pjName = pj
17 | techStack = tech
18 | }
19 |
20 | Start(w, []string{"init", "--frontend", "vue", "my-app"}, generate)
21 |
22 | if pjName != "my-app" || techStack[0] != "vue" {
23 | t.Error("Generation function function received wrong arguments")
24 | }
25 | if w.String() != "" {
26 | t.Errorf("No output expected but got %v", w.String())
27 | }
28 | }
29 |
30 | func TestStartGivenHelp(t *testing.T) {
31 | w := &bytes.Buffer{}
32 |
33 | Start(w, []string{"help"}, nil)
34 |
35 | got := strings.TrimRight(w.String(), "\n")
36 | if got != usage {
37 | t.Errorf("Start() = %v, want %v", got, usage)
38 | }
39 | }
40 |
41 | func TestStartGivenWrongArguments(t *testing.T) {
42 | w := &bytes.Buffer{}
43 |
44 | Start(w, []string{"wrong", "arguments"}, nil)
45 |
46 | got := strings.TrimRight(w.String(), "\n")
47 | expected := "Wrong input!\n" + usage
48 | if got != expected {
49 | t.Errorf("Start() = %v, want %v", got, expected)
50 | }
51 | }
52 |
53 | func TestStartGivenWrongNameFormat(t *testing.T) {
54 | w := &bytes.Buffer{}
55 |
56 | Start(w, []string{"init", "name.with.dots"}, nil)
57 |
58 | got := strings.TrimRight(w.String(), "\n")
59 | if got != invalidName {
60 | t.Errorf("Start() = %v, want %v", got, invalidName)
61 | }
62 | }
63 |
64 | func TestParseFlags(t *testing.T) {
65 | flags := []flag{{
66 | "--frontend", []string{"react", "vue"}, "react",
67 | }}
68 | options := []string{"--frontend", "vue"}
69 |
70 | values, err := parseFlags(options, flags)
71 |
72 | if err != nil {
73 | t.Error("parseFlags must not return an error")
74 | }
75 | if len(values) != 1 && values[0] != "vue" {
76 | t.Error(`parseFlags must return ["vue"]`)
77 | }
78 | }
79 |
80 | func TestParseFlagsGivenSeveralFlags(t *testing.T) {
81 | flags := []flag{
82 | {"--frontend", []string{"react", "vue"}, "react"},
83 | {"--db", []string{"mysql", "mongo"}, "mongo"},
84 | }
85 | options := []string{"--frontend", "vue", "--db", "mysql"}
86 |
87 | got, err := parseFlags(options, flags)
88 |
89 | if err != nil {
90 | t.Error("parseFlags must not return an error")
91 | }
92 | exp := []string{"vue", "mysql"}
93 | if !reflect.DeepEqual(got, exp) {
94 | t.Error(`parseFlags must return "vue" and "mysql"`)
95 | }
96 | }
97 |
98 | func TestParseFlagsGivenDefaultValues(t *testing.T) {
99 | flags := []flag{{
100 | "--frontend", []string{"react", "vue"}, "react",
101 | }}
102 |
103 | got, err := parseFlags([]string{}, flags)
104 |
105 | if err != nil {
106 | t.Error("parseFlags must not return an error")
107 | }
108 | exp := []string{"react"}
109 | if !reflect.DeepEqual(got, exp) {
110 | t.Error(`parseFlags must return "react"`)
111 | }
112 | }
113 |
114 | func TestParseFlagsGivenUnknownArguments(t *testing.T) {
115 | flags := []flag{{
116 | "--frontend", []string{"react", "vue"}, "react",
117 | }}
118 | options := []string{"--unknown", "test"}
119 |
120 | got, err := parseFlags(options, flags)
121 |
122 | if !reflect.DeepEqual(err, errors.New("flag mismatch")) {
123 | t.Error("parseFlags must return an error")
124 | }
125 | if got != nil {
126 | t.Error("parseFlags must return nil values")
127 | }
128 | }
129 |
130 | func TestParseFlagsGivenWrongFlagValue(t *testing.T) {
131 | flags := []flag{{
132 | "--frontend", []string{"react", "vue"}, "react",
133 | }}
134 | options := []string{"--frontend", "unknown"}
135 |
136 | values, err := parseFlags(options, flags)
137 |
138 | expected := errors.New(`invalid value of "--frontend" flag`)
139 | if !reflect.DeepEqual(err, expected) {
140 | t.Error("parseFlags must return an error")
141 | }
142 | if values != nil {
143 | t.Error("parseFlags must return nil values")
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/codegen/codegen.go:
--------------------------------------------------------------------------------
1 | package codegen
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "os"
7 | "os/exec"
8 | "strings"
9 |
10 | "github.com/shpota/goxygen/static"
11 | )
12 |
13 | type generator struct {
14 | projectName string
15 | techStack []string
16 | }
17 |
18 | func Generate(projectName string, techStack []string) {
19 | g := generator{projectName, techStack}
20 | g.generate()
21 | }
22 |
23 | func (g generator) generate() {
24 | fmt.Println("Generating", g.projectName)
25 | for path, srcText := range static.Sources() {
26 | srcText = strings.ReplaceAll(srcText, "project-name", g.projectName)
27 | binary := []byte(srcText)
28 | g.processFile(path, binary)
29 | }
30 | for path, binary := range static.Images() {
31 | g.processFile(path, binary)
32 | }
33 | err := g.initGitRepo()
34 | if err != nil {
35 | fmt.Println("Failed to setup a Git repository:", err)
36 | }
37 | fmt.Println("Generation completed.")
38 | }
39 |
40 | // Checks if a file with the given path has to be generated, creates
41 | // a directory structure, and a file with the given content.
42 | func (g generator) processFile(path string, content []byte) {
43 | if !g.needed(path) {
44 | return
45 | }
46 | for _, tech := range g.techStack {
47 | path = strings.Replace(path, tech+".", "", 1)
48 | }
49 | pathElements := strings.Split(path, "/")
50 | separator := string(os.PathSeparator)
51 | pathElements = append([]string{g.projectName}, pathElements...)
52 | _ = os.MkdirAll(
53 | strings.Join(pathElements[:len(pathElements)-1], separator),
54 | os.ModePerm,
55 | )
56 | fmt.Println("creating: " + strings.Join(pathElements, separator))
57 | const FILEMODE = os.FileMode(0644)
58 | err := os.WriteFile(
59 | strings.Join(pathElements, separator),
60 | content,
61 | FILEMODE,
62 | )
63 | if err != nil {
64 | log.Fatal(err)
65 | }
66 | }
67 |
68 | func (g generator) initGitRepo() error {
69 | fmt.Println("setting up Git repository")
70 | cmd := exec.Command("git", "init", "-b", "main", ".")
71 | cmd.Dir = g.projectName
72 | err := cmd.Run()
73 | if err != nil {
74 | return err
75 | }
76 | cmd = exec.Command("git", "add", ".")
77 | cmd.Dir = g.projectName
78 | err = cmd.Run()
79 | if err != nil {
80 | return err
81 | }
82 | cmd = exec.Command("git", "commit", "-m", "Initial commit from Goxygen")
83 | cmd.Dir = g.projectName
84 | return cmd.Run()
85 | }
86 |
87 | // Checks if a path is a framework-specific path (starts
88 | // with framework name). Returns true if a path is
89 | // prefixed with the provided framework followed by dot
90 | // or if a path has no prefix.
91 | func (g generator) needed(path string) bool {
92 | if !hasTechPrefix(path) {
93 | return true
94 | }
95 | for _, tech := range g.techStack {
96 | if strings.HasPrefix(path, tech+".") {
97 | return true
98 | }
99 | }
100 | return false
101 | }
102 |
103 | func hasTechPrefix(path string) bool {
104 | for _, tech := range []string{
105 | "angular", "react", "vue", "mongo", "mysql", "postgres",
106 | } {
107 | if strings.HasPrefix(path, tech+".") {
108 | return true
109 | }
110 | }
111 | return false
112 | }
113 |
--------------------------------------------------------------------------------
/codegen/codegen_test.go:
--------------------------------------------------------------------------------
1 | package codegen
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestNeeded(t *testing.T) {
8 | g := generator{techStack: []string{"react"}}
9 |
10 | got := g.needed("react.webapp/test.js")
11 |
12 | if !got {
13 | t.Error("Framework specific paths must be needed")
14 | }
15 | }
16 |
17 | func TestNeededGivenGeneralPath(t *testing.T) {
18 | g := generator{techStack: []string{"react"}}
19 |
20 | got := g.needed("server/server.go")
21 |
22 | if !got {
23 | t.Error("General paths must be needed")
24 | }
25 | }
26 |
27 | func TestNeededGivenExcludedPath(t *testing.T) {
28 | g := generator{techStack: []string{"react"}}
29 |
30 | got := g.needed("angular.webapp/test.js")
31 |
32 | if got {
33 | t.Error("Angular files must not be needed for react")
34 | }
35 | }
36 |
37 | func Test_hasTechPrefix(t *testing.T) {
38 | got := hasTechPrefix("mongo.server/go.mod")
39 |
40 | if !got {
41 | t.Errorf("Must recognize prefix")
42 | }
43 | }
44 |
45 | func Test_hasTechPrefix_GeneralPath(t *testing.T) {
46 | got := hasTechPrefix("unknown.server/go.mod")
47 |
48 | if got {
49 | t.Errorf("Must not recognize prefix")
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | goxygen.dev
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Generate a Web project with Go and Angular, React or Vue.**
57 |
58 | Goxygen aims at saving your time while setting up a new project. It
59 | creates a skeleton of an application with all configuration done for
60 | you. You can start implementing your business logic straight away.
61 | Goxygen generates back end Go code, connects it with front end
62 | components, provides a Dockerfile for the application and creates
63 | docker-compose files for convenient run in development and production
64 | environments.
65 |
66 | <table>
67 | <thead>
68 | <tr align="center">
69 | <td colspan=4><b>Supported Technologies</b></td>
70 | </tr>
71 | </thead>
72 | <tbody>
73 | <tr align="center">
74 | <td align="center">Front End</td>
75 | <td>Angular</td>
76 | <td>React</td>
77 | <td>Vue</td>
78 | </tr>
79 | <tr align="center">
80 | <td>Back End</td>
81 | <td colspan=3>Go</td>
82 | </tr>
83 | <tr align="center">
84 | <td>Database</td>
85 | <td>MongoDB</td>
86 | <td>MySQL</td>
87 | <td>PostgreSQL</td>
88 | </tr>
89 | </tbody>
90 | </table>
91 |
92 | ## Requirements
93 |
94 | You need to have Go 1.16 or newer on your machine.
95 |
96 | ## How to use
97 |
98 | Run:
99 |
100 | ```go
101 | go run github.com/shpota/goxygen@latest init my-app
102 | ```
103 |
104 | This generates a project in `my-app` folder.
105 |
106 | By default, it will use React and MongoDB. You can select
107 | a different front end framework and a database using
108 | `--frontend` and `--db` flags. For instance, this command
109 | will create a project with Vue and PostgreSQL:
110 |
111 | ```go
112 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
113 | ```
114 |
115 | The `--frontend` flag accepts `angular`, `react` and `vue`.
116 | The `--db` flag accepts `mongo`, `mysql` and `postgres`.
117 |
118 | The generated project is ready to run with Docker Compose:
119 |
120 | ```sh
121 | cd my-app
122 | docker compose up
123 | ```
124 |
125 | After the build is completed, the application is accessible
126 | on http://localhost:8080.
127 |
128 | You can find more details on how to work with the generated
129 | project in its README file.
130 |
131 | 
132 |
133 | ## Structure of a generated project (React/MongoDB example)
134 |
135 | my-app
136 | ├── server # Go project files
137 | │ ├── db # MongoDB communications
138 | │ ├── model # domain objects
139 | │ ├── web # REST APIs, web server
140 | │ ├── server.go # the starting point of the server
141 | │ └── go.mod # server dependencies
142 | ├── webapp
143 | │ ├── public # icons, static files, and index.html
144 | │ ├── src
145 | │ │ ├── App.js # the main React component
146 | │ │ ├── App.css # App component-specific styles
147 | │ │ ├── index.js # the entry point of the application
148 | │ │ └── index.css # global styles
149 | │ ├── package.json # front end dependencies
150 | │ ├── .env.development # holds API endpoint for dev environment
151 | │ └── .env.production # API endpoint for prod environment
152 | ├── Dockerfile # builds back end and front end together
153 | ├── docker-compose.yml # prod environment deployment descriptor
154 | ├── docker-compose-dev.yml # runs local MongoDB for development needs
155 | ├── init-db.js # creates a MongoDB collection with test data
156 | ├── .dockerignore # specifies files ignored in Docker builds
157 | ├── .gitignore
158 | └── README.md # guide on how to use the generated repo
159 |
160 | Files such as unit tests or sample components are not included here
161 | for simplicity.
162 |
163 | ## Dependencies
164 |
165 | Goxygen generates a basic structure of a project and doesn't force you
166 | to use a specific set of tools. That's why it doesn't bring unneeded
167 | dependencies to your project. It uses only a database driver on the
168 | back end side and [axios](https://github.com/axios/axios) in React
169 | and Vue projects. Angular projects use only Angular specific libraries.
170 |
171 | ## How to contribute
172 |
173 | If you found a bug or have an idea on how to improve the project
174 | [open an issue](https://github.com/Shpota/goxygen/issues)
175 | and we will fix it as soon as possible. You can also propose your
176 | changes via a Pull Request. Fork the repository, make changes, send
177 | us a pull request and we'll review it shortly. We also have a
178 | [Gitter chat](https://gitter.im/goxygen/community) where we discuss
179 | all the changes.
180 |
181 | ## Credits
182 |
183 | Goxygen's logo was created by [Egon Elbre](https://twitter.com/egonelbre).
184 |
--------------------------------------------------------------------------------
/docs/README_by.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="25px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Goxygen генеруе Web праекты на Go і сучасных SPA фреймворках.**
57 |
58 | Goxygen захавае ваш час пры стварэнні новых дадаткаў. Ён генеруе
59 | базавую структуру Web праекта і дазваляе адразу ж перайсці да
60 | рэалізацыі бізнес логікі без клопатаў аб канфігурацыі. Goxygen
61 | стварае back end код на Go, звязвае яго з front end кампанентамі,
62 | дадае `Dockerfile` і `docker-compose` для зручнага запуску
63 | лакальна і ў production асяроддзі.
64 |
65 | <table>
66 | <thead>
67 | <tr align="center">
68 | <td colspan=4><b>Падтрымліваюцца тэхналогіі</b></td>
69 | </tr>
70 | </thead>
71 | <tbody>
72 | <tr align="center">
73 | <td align="center">Front End</td>
74 | <td>Angular</td>
75 | <td>React</td>
76 | <td>Vue</td>
77 | </tr>
78 | <tr align="center">
79 | <td>Back End</td>
80 | <td colspan=3>Go</td>
81 | </tr>
82 | <tr align="center">
83 | <td>База даных</td>
84 | <td>MongoDB</td>
85 | <td>MySQL</td>
86 | <td>PostgreSQL</td>
87 | </tr>
88 | </tbody>
89 | </table>
90 |
91 | ## Requirements
92 | Вам трэба мець Go 1.16 або навей вэрсію.
93 |
94 | The `GO111MODULE` environment variable has to be set to `auto`
95 | for the generation logic to work. It is a default for Go
96 | versions up to 1.15. For Go 1.16, you need to set it explicitly:
97 | ```
98 | export GO111MODULE=auto
99 | ```
100 |
101 | ## Выкарыстанне
102 |
103 | ```go
104 | go run github.com/shpota/goxygen@latest init my-app
105 | ```
106 |
107 | У выніку будзе згенераваны праект у дырэкторыі `my-app`.
108 |
109 | React і MongoDB выкарыстоўваецца па змаўчанню. Вы
110 | можаце выбраць розныя front end фреймворк і розныя
111 | базу даных з дапамогай `--frontend` і `--db` сцягі.
112 | Напрыклад, гэтая каманда створыць праект з Vue і PostgreSQL:
113 |
114 | ```go
115 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
116 | ```
117 |
118 | Сцяг `--frontend` прымае `angular`, `react` або ` vue`.
119 | Сцяг `--db` прымае `mongo`, `mysql` або `postgres`.
120 |
121 | Сфарміраваны праект гатовы да запуску з `docker-compose`:
122 | ```sh
123 | cd my-app
124 | docker compose up
125 | ```
126 | Пасля завяршэння зборкі, дадатак будзе даступны на
127 | http://localhost:8080.
128 |
129 | Больш дэталяў пра дадатак і як з ім працаваць можна знайсці ў
130 | яго README.
131 |
132 | 
133 |
134 | ## Структура генераванага праекта (прыкладанне на аснове React/MongoDB)
135 |
136 | my-app
137 | ├── server # серверная частка дадатку (Go)
138 | │ ├── db # камунікацыі з MongoDB
139 | │ ├── model # даменныя аб'екты
140 | │ ├── web # REST API і Web сервер
141 | │ ├── server.go # ўваходная кропка сервернага кода
142 | │ └── go.mod # апісанне Go модуля і залежнасці
143 | ├── webapp
144 | │ ├── public # іконкі, статычныя файлы і index.html
145 | │ ├── src
146 | │ │ ├── App.js # галоўны React кампанент
147 | │ │ ├── App.css # стылі галоўнага кампанента
148 | │ │ ├── index.js # ўходная кропка front end дадатку
149 | │ │ └── index.css # глабальныя стылі
150 | │ ├── package.json # front end залежнасці
151 | │ ├── .env.development # API URL для запуску ў development асяроддзі
152 | │ └── .env.production # API URL для запуску ў production асяроддзі
153 | ├── Dockerfile # збірае front end і back end разам
154 | ├── docker-compose.yml # настройкі для запуску ў production асяроддзі
155 | ├── docker-compose-dev.yml # настройкі для запуску лакальнай базы даных
156 | ├── init-db.js # напаўняе базу даных пачатковымі данымі
157 | ├── .dockerignore # вызначае файлы, якія ігнаруюцца ў Docker зборцы
158 | ├── .gitignore
159 | └── README.md # інструкцыя па выкарыстанні праекта
160 |
161 | Юніт тэсты і дэманстрацыйныя кампаненты не ўключаны ў структуру для прастаты.
162 |
163 | ## Залежнасці
164 |
165 | Goxygen генеруе толькі базавая структуру праекта і не навязвае
166 | вам выкарыстанне спецыфічных бібліятэк або утыліт. Згенераваны
167 | праект будзе мець толькі два старонніх залежнасці: драйвер для базы
168 | даных і бібліятэку для асінхронных REST запытаў,
169 | [axios](https://github.com/axios/axios), для праектаў React і Vue.
170 |
171 | ## Як далучыцца да праекта
172 |
173 | Калі вы знайшлі памылку, ці хочаце прапанаваць паляпшэння,
174 | [адкрыйце issue](https://github.com/Shpota/goxygen/issues) і мы з гэтым
175 | разбярэмся. Таксама можаце прапанаваць свае змены
176 | [у нашым Gitter чаце](https://gitter.im/goxygen/community), або
177 | стварыўшы Pull Request.
178 |
179 | ### Падзякі
180 |
181 | Лагатып Goxygen стварыў [Egon Elbre](https://twitter.com/egonelbre).
182 |
--------------------------------------------------------------------------------
/docs/README_es.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Genera un proyecto Web con Go y Angular/React/Vue en segundos.**
57 |
58 | Goxygen aspira a salverte tiempo a la hora de crear un nuevo proyecto,
59 | creando el esqueleto de una aplicacion con la configuracion ya generada,
60 | para que puedas comenzar a implementar la logica de tu negocio inmediatamente.
61 | Goxygen genera el backend con Go, lo conecta con los componentes del frontend
62 | y te ofrece los archivos necesarios para que docker componga los entornos de desarrollo y produccion.
63 |
64 | <table>
65 | <thead>
66 | <tr align="center">
67 | <td colspan=4><b>Supported Technologies</b></td>
68 | </tr>
69 | </thead>
70 | <tbody>
71 | <tr align="center">
72 | <td align="center">Front End</td>
73 | <td>Angular</td>
74 | <td>React</td>
75 | <td>Vue</td>
76 | </tr>
77 | <tr align="center">
78 | <td>Back End</td>
79 | <td colspan=3>Go</td>
80 | </tr>
81 | <tr align="center">
82 | <td>Database</td>
83 | <td>MongoDB</td>
84 | <td>MySQL</td>
85 | <td>PostgreSQL</td>
86 | </tr>
87 | </tbody>
88 | </table>
89 |
90 | ## Como se usa
91 |
92 | ```go
93 | go run github.com/shpota/goxygen@latest init my-app
94 | ```
95 |
96 | Este codigo genera un proyecto en el directorio ``my-app``.
97 |
98 | By default, it will use React and MongoDB. You can select
99 | a different front end framework and a database using
100 | `--frontend` and `--db` flags. For instance, this command
101 | will create a project with Vue and PostgreSQL:
102 |
103 | ```go
104 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
105 | ```
106 |
107 | The `--frontend` flag accepts `angular`, `react` and `vue`.
108 | The `--db` flag accepts `mongo`, `mysql` and `postgres`.
109 |
110 | El proyecto generado se puede correr utilizando `docker-compose`:
111 | ```sh
112 | cd my-app
113 | docker compose up
114 | ```
115 |
116 | Una vez la construccion se haya completado la aplicacion estara accesible
117 | a traves de http://localhost:8080.
118 |
119 | Puedes encontrar más detalles en como trabajar con el proyecto generado en su archivo README.
120 |
121 |
122 | 
123 |
124 | ## Estructura de un proyecto generado (Aplicacion basada en React/MongoDB)
125 |
126 |
127 | my-app
128 | ├── server # archivos de GO
129 | │ ├── db # comunicaciones de MongoDB
130 | │ ├── model # objetos de dominio
131 | │ ├── web # REST APIs, web server
132 | │ ├── server.go # el punto de entrada del servidor
133 | │ └── go.mod # Dependencias del servidor
134 | ├── webapp
135 | │ ├── public # iconos, archivos estaticos e index.html
136 | │ ├── src
137 | │ │ ├── App.js # componente principal de React
138 | │ │ ├── App.css # estilos componente-especifico de la App
139 | │ │ ├── index.js # punto de entrada principal de la aplicacion
140 | │ │ └── index.css # estilos globales
141 | │ ├── package.json # dependencias del front end
142 | │ ├── .env.development # contiene endpoint del API para entorno de desarrollo
143 | │ └── .env.production # endpoint de la API para entornos de produccion
144 | ├── Dockerfile # constructor de backend y frontend juntos
145 | ├── docker-compose.yml # descriptor del despliegue para el entorno de produccion
146 | ├── docker-compose-dev.yml # ejecuta MongoDB localmente para necesidad de desarrollo
147 | ├── init-db.js # genera una collecion de MongoDB con informacion de prueba
148 | ├── .dockerignore # especifica archivos a ignorar en la construccion de Docker
149 | ├── .gitignore
150 | └── README.md # guia de como utilizar la repo generada
151 |
152 | No se han incluido archivos como las informacion de prueba o ejemplos de los componentes para simplicar.
153 |
154 | ## Dependencias
155 |
156 | Goxygen genera la estructura basico de uin proyecto y no te obliga a
157 | utilizar ningun set especifico de herramientas. Es por eso que no incluye
158 | dependencias innecesarias, tan solo utiliza database driver en el backend y
159 | [axios](https://github.com/axios/axios) para pryectos de React y Vue.
160 | Proyectos en Angular solo utilizan librerias especificas.
161 |
162 | ## Como contribuir
163 |
164 | Si encuentras algun bug o tiene ideas para mejorar el proyecto
165 | [abre una hilo](https://github.com/Shpota/goxygen/issues) y lo
166 | solucionaremos lo antes posible. Tambien puedes proponer cambios
167 | a traves de pull request. Haz un fork, realiza cambios y mandanos
168 | un pull request y lo revisaremos. Tambien tenemos un
169 | [Gitter chat](https://gitter.im/goxygen/community) donde discutimos los cambios.
170 |
171 | ### Creditos
172 | Goxygen's logo was created by [Egon Elbre](https://twitter.com/egonelbre).
173 |
--------------------------------------------------------------------------------
/docs/README_fr.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Générer un projet web avec Go et Angular/React/Vue en quelques secondes.**
57 |
58 | Goxygen vise à vous faire gagner du temps lors de la mise en place d'un nouveau projet. Il
59 | crée un squelette d'application avec une configuration complète par défaut.
60 | Vous pouvez commencer immédiatement à implémenter votre logique métier.
61 | Goxygen génère du code Backend en Go, le connecte aux composants Frontend, fournit un
62 | Dockerfile pour l'application et crée des fichiers Docker-compose pour une exécution pratique
63 | dans des environnements de développement et de production.
64 |
65 | <table>
66 | <thead>
67 | <tr align="center">
68 | <td colspan=4><b>Technoligies supportées</b></td>
69 | </tr>
70 | </thead>
71 | <tbody>
72 | <tr align="center">
73 | <td align="center">Front End</td>
74 | <td>Angular</td>
75 | <td>React</td>
76 | <td>Vue</td>
77 | </tr>
78 | <tr align="center">
79 | <td>Back End</td>
80 | <td colspan=3>Go</td>
81 | </tr>
82 | <tr align="center">
83 | <td>Base de données</td>
84 | <td>MongoDB</td>
85 | <td>MySQL</td>
86 | <td>PostgreSQL</td>
87 | </tr>
88 | </tbody>
89 | </table>
90 |
91 | ## Guide d'utilisation
92 |
93 | ```go
94 | go run github.com/shpota/goxygen@latest init my-app
95 | ```
96 |
97 | Ces commandes génèrent un projet dans le dossier `my-app`.
98 |
99 | Par défaut, React et MongoDB seront utilisés. Vous pouvez
100 | choisir divers frameworks frontend ou bases de données en
101 | utilisant les flags `--frontend` et `--db`. Par exemple, cette
102 | commande va créer un projet avec Vue et PostreSQL:
103 |
104 | ```go
105 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
106 | ```
107 |
108 | Le flag `--frontend` accepte les valeurs `angular`, `react` and `vue`.
109 | Le flag `--db` accepte les valeurs `mongo`, `mysql` and `postgres`.
110 |
111 | Le projet généré est prêt à l'utilisation avec `docker-compose`:
112 |
113 | ```sh
114 | cd my-app
115 | docker compose up
116 | ```
117 |
118 | Aprés la fin du build, l'application est
119 | accessible sur http://localhost:8080.
120 |
121 | Vous trouverez plus de détails sur l'utilisation
122 | du projet généré dans son fichier README.
123 |
124 | 
125 |
126 | ## Structure d'un projet généré (application React/MongoDB)
127 |
128 | my-app
129 | ├── server # fichier du projet Go
130 | │ ├── db # communications avec MongoDB
131 | │ ├── model # objets du domaine
132 | │ ├── web # REST APIs, serveur web
133 | │ ├── server.go # point d'entrée du serveur
134 | │ └── go.mod # dépendances du serveur
135 | ├── webapp
136 | │ ├── public # icones, fichiers statiques, et index.html
137 | │ ├── src
138 | │ │ ├── App.js # le composant React principale
139 | │ │ ├── App.css # style spécifiques au composant App
140 | │ │ ├── index.js # le point d'entrée de l'application
141 | │ │ └── index.css # styles globaux
142 | │ ├── package.json # dépendances du frontend
143 | │ ├── .env.development # endpoint de l'API pour l'environnement de développement
144 | │ └── .env.production # endpoint de l'API pour l'environnement de production
145 | ├── Dockerfile # build du backend et du frontend
146 | ├── docker-compose.yml # description des déploiements dans un environnement de production
147 | ├── docker-compose-dev.yml # lance une instance de MongoDB en local pour développement
148 | ├── init-db.js # crée une collection MongoDB avec des données de test
149 | ├── .dockerignore # spécifie les fichiers ignorés lors des builds docker
150 | ├── .gitignore
151 | └── README.md # guide d'utilisation du projet généré
152 |
153 | Les fichiers de tests unitaires ou d'exemples de composants ne sont pas inclus
154 | pour des raisons de simplicité.
155 |
156 | ## Dépendances
157 |
158 | Goxygen génére un projet avec une structure basique et ne vous force pas à utiliser des
159 | outils spécifiques. C'est pour cela que les seules dépendances utilisées dans le projet
160 | sont database driver côté backend et [axios](https://github.com/axios/axios) côté
161 | frontend les projets React et Vue. Les projets Angular utilisent leurs propres librairies.
162 |
163 | ## Comment contribuer
164 |
165 | Si vous trouvez un bug ou avez une idée sur comment améliorer le projet
166 | [créez une issue](https://github.com/Shpota/goxygen/issues)
167 | et nous corrigerons le problème le plus rapidement possible. Vous pouvez aussi
168 | proposer vos propres changement avec des Pull Request. Faites un Fork du dépôt,
169 | effectuer vos modifications, envoyez-nous un pull request et nous le consulterons dans
170 | les plus brefs délais. Nous disposons aussi d'un [chat Gitter](https://gitter.im/goxygen/community)
171 | où nous discutons tous les changements.
172 |
173 | ### Crédits
174 |
175 | Le logo de Goxygen à été crée par [Egon Elbre](https://twitter.com/egonelbre).
176 |
--------------------------------------------------------------------------------
/docs/README_he.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | <div dir="rtl">
40 | Goxygen
41 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
42 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
43 | </a>
44 | <a href="https://github.com/Shpota/goxygen/releases">
45 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
46 | </a>
47 | <a href="https://gitter.im/goxygen/community">
48 | <img src="https://badges.gitter.im/goxygen/community.svg">
49 | </a>
50 | <a href="https://github.com/Shpota/goxygen/pulls">
51 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
52 | </a>
53 | </div>
54 | </h1>
55 |
56 |
57 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="left" width="230px" alt="goxygen logo">
58 |
59 |
60 | <div dir="rtl">
61 |
62 | **יצירה אוטומטית של פרויקט Web באמצעות Go ו-Angular, React או Vue.**
63 |
64 | מטרת Goxygen היא לחסוך זמן במהלך הקמת פרויקט חדש.
65 | הוא מייצר שלד עבור יישום עם כל הקונפיגורציה מוכנה עבורכם.
66 | אתם יכולים ישר להתחיל לממש את ההיגיון העסקי שלכם.
67 | Goxygen מג'נרט back-end בשפת Go, מחבר אותו עם הרכיבים של ה-front-end, מספק Dockerfile עבור היישום ומייצר קבצי docker-compose להפעלה נוחה בסביבות הפיתוח והייצור (production).
68 | </div>
69 |
70 | <div dir="rtl">
71 | <table>
72 | <thead>
73 | <tr align="center">
74 | <td colspan=4><b>טכנולוגיות נתמכות</b></td>
75 | </tr>
76 | </thead>
77 | <tbody>
78 | <tr align="center">
79 | <td align="center">Front End</td>
80 | <td>Angular</td>
81 | <td>React</td>
82 | <td>Vue</td>
83 | </tr>
84 | <tr align="center">
85 | <td>Back End</td>
86 | <td colspan=3>Go</td>
87 | </tr>
88 | <tr align="center">
89 | <td>בסיס נתונים</td>
90 | <td>MongoDB</td>
91 | <td>MySQL</td>
92 | <td>PostgreSQL</td>
93 | </tr>
94 | </tbody>
95 | </table>
96 | </div>
97 |
98 | <div dir="rtl">
99 |
100 | ## Requirements
101 | עליכם להתקין Go 1.16 ומעלה במחשב שלכם.
102 |
103 | ## איך להשתמש
104 | </div>
105 |
106 | ```go
107 | go run github.com/shpota/goxygen@latest init my-app
108 | ```
109 |
110 | <div dir="rtl">
111 |
112 | פקודה זו תייצר פרויקט בתיקיית <span dir="ltr">`my-app`</span>.
113 | </div>
114 |
115 | <div dir="rtl">
116 |
117 | כברירת מחדל, הכלי ישתמש ב-React ו-MongoDB.
118 | אתם יכולים לבחור front-end framework ובסיס נתונים אחרים באמצעות הדגלים <span dir="ltr">`--frontend`</span> ו-<span dir="ltr">`--db`</span> בהתאמה.
119 | למשל פקודה זו תייצר פרויקט מבוסס Vue ו-PostgreSQL:
120 | </div>
121 |
122 | ```go
123 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
124 | ```
125 |
126 | <div dir="rtl">
127 |
128 | דגל <span dir="ltr">`--frontend`</span> תומך באפשרויות <span dir="ltr">`angular`</span>, <span dir="ltr">`react`</span> ו-<span dir="ltr">`vue`</span>.
129 | דגל <span dir="ltr">`--db`</span> תומך באפשרויות <span dir="ltr">`mongo`</span>, <span dir="ltr">`mysql`</span> ו-<span dir="ltr">`postgres`</span>.
130 | </div>
131 |
132 | <div dir="rtl">
133 |
134 | הפרויקט שנוצר מוכן להפעלה עם <span dir="ltr">`docker-compose`</span>:
135 | </div>
136 |
137 | ```sh
138 | cd my-app
139 | docker compose up
140 | ```
141 |
142 | <div dir="rtl">
143 |
144 | אחרי שה-build הסתיים, היישום נגיש ב-http://localhost:8080.
145 | </div>
146 |
147 | <div dir="rtl">
148 |
149 | אתם יכולים למצוא פרטים נוספים על איך לעבוד עם הפרויקט שנוצר בקובץ ה-README שלו.
150 | </div>
151 |
152 | 
153 |
154 | <div dir="rtl">
155 |
156 | ## מבנה של פרויקט שג'ונרט (דוגמת React/MongoDB)
157 | </div>
158 |
159 |
160 | my-app
161 | ├── server # Go קבצי פרויקט
162 | │ ├── db # MongoDB תקשורת
163 | │ ├── model # domain אובייקטי
164 | │ ├── web # REST APIs, web שרת
165 | │ ├── server.go # נקודת ההתחלה של השרת
166 | │ └── go.mod # של השרת dependencies
167 | ├── webapp
168 | │ ├── public # index.html-אייקונים, קבצים סטטיים ו
169 | │ ├── src
170 | │ │ ├── App.js # React הרכיב המרכזי של
171 | │ │ ├── App.css # App סגנונות ספציפיים עבור רכיב
172 | │ │ ├── index.js # נקודת הכניסה של היישום
173 | │ │ └── index.css # סגנונות גלובליים
174 | │ ├── package.json # front end-של ה dependencies
175 | │ ├── .env.development # dev-לסביבת ה API-מחזיק בנקודת הקצה של ה
176 | │ └── .env.production # prod-לסביבת ה API-מחזיק בנקודת הקצה של ה
177 | ├── Dockerfile # ביחד front end-וה back end-של ה build
178 | ├── docker-compose.yml # prod תיאור פריסת סביבת
179 | ├── docker-compose-dev.yml # מקומי לצרכי פיתוח MongoDB מפעיל
180 | ├── init-db.js # עם נתוני בדיקה MongoDB-יוצר אסופה ב
181 | ├── .dockerignore # Docker builds מציין קבצים שיש להתעלם מהם בעת
182 | ├── .gitignore
183 | └── README.md # שנוצר repo-מדריך כיצד להשתמש ב
184 |
185 | <div dir="rtl">
186 |
187 | קבצים כמו קבצי unit tests או רכיבי בסיס אינם כלולים כאן לצורך פשטות.
188 | </div>
189 |
190 | <div dir="rtl">
191 |
192 | ## תלויות - Dependencies
193 | </div>
194 |
195 | <div dir="rtl">
196 |
197 | Goxygen מג'נרט שלד בסיסי של פרויקט ואינו מכריח אתכם להשתמש בקבוצת כלים מסוימת. לכן, הוא לא מוסיף תלויות בלתי נחוצות לפרויקט שלכם.
198 | הוא משתמש רק ב-driver עבור בסיס נתונים ב-back end וב-[axios](https://github.com/axios/axios) בפרויקטים מבוססי React או Vue. בפרויקטים מבוססי Angular הוא משתמש רק בספריות ספציפיות של Angular.
199 | </div>
200 |
201 | <div dir="rtl">
202 |
203 | ## איך לתרום
204 | </div>
205 |
206 | <div dir="rtl">
207 |
208 | אם מצאתם באג או שיש לכם רעיון כיצד לשפר את הפרויקט [open an issue](https://github.com/Shpota/goxygen/issues) ואנחנו נתקן אותו בהקדם האפשרי. אתם יכולים גם להציע שינויים באמצעות Pull Request. תעשו Fork ל-repository, בצעו שינויים, שלחו לנו בקשת pull ואנחנו נבדוק אותה בקרוב. יש לנו גם [Gitter chat](https://gitter.im/goxygen/community) בו אנו דנים בכל השינויים.
209 | </div>
210 |
211 | <div dir="rtl">
212 |
213 | ### קרדיטים
214 | </div>
215 |
216 | <div dir="rtl">
217 |
218 | הלוגו של Goxygen נוצר על ידי [Egon Elbre](https://twitter.com/egonelbre).
219 | </div>
220 |
--------------------------------------------------------------------------------
/docs/README_id.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Menyiapkan web projek menggunakan Go dan Angular/React/Vue.**
57 |
58 | Goxygen bertujuan untuk menghemat waktu Anda dalam menyiapkan
59 | sebuah proyek web baru.Goxygen menciptakan kerangka aplikasi
60 | dengan semua konfigurasi yang telah disiapkan untuk Anda. Jadi
61 | Anda dapat langsung segera memulai menerapkan logika bisnis
62 | pada proyek Anda. Goxygen menghasilkan kode Go yang berfungsi
63 | sebagai back-end, menghubungkannya dengan komponen front-end,
64 | menyediakan Dockerfile untuk aplikasi docker dan membuat file
65 | docker-compose agar mudah dijalankan dalam fase pengembangan
66 | dan fase produksi.
67 |
68 | <table>
69 | <thead>
70 | <tr align="center">
71 | <td colspan=4><b>Supported Technologies</b></td>
72 | </tr>
73 | </thead>
74 | <tbody>
75 | <tr align="center">
76 | <td align="center">Front End</td>
77 | <td>Angular</td>
78 | <td>React</td>
79 | <td>Vue</td>
80 | </tr>
81 | <tr align="center">
82 | <td>Back End</td>
83 | <td colspan=3>Go</td>
84 | </tr>
85 | <tr align="center">
86 | <td>Database</td>
87 | <td>MongoDB</td>
88 | <td>MySQL</td>
89 | <td>PostgreSQL</td>
90 | </tr>
91 | </tbody>
92 | </table>
93 |
94 | ## Requirements
95 | Anda harus mempunyai Go versi 1.16 atau yang lebih pada mesin Anda.
96 |
97 |
98 | ## Cara penggunaan
99 |
100 | ```go
101 | go run github.com/shpota/goxygen@latest init my-app
102 | ```
103 |
104 | Ini akan meng-generate sebuah projek di dalam `my-app` folder.
105 |
106 | By default, it will use React and MongoDB. You can select
107 | a different front end framework and a database using
108 | `--frontend` and `--db` flags. For instance, this command
109 | will create a project with Vue and PostgreSQL:
110 |
111 | ```go
112 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
113 | ```
114 |
115 | The `--frontend` flag accepts `angular`, `react` and `vue`.
116 | The `--db` flag accepts `mongo`, `mysql` and `postgres`.
117 |
118 | Proyek yang telah di generate dapat dijalankan dengan perintah `docker-compose`:
119 | ```sh
120 | cd my-app
121 | docker compose up
122 | ```
123 | Setelah proses build selesai, aplikasi dapat diakses
124 | pada http://localhost:8080.
125 |
126 | Anda dapat menemukan detail lebih lanjut tentang bagaimana cara bekerja
127 | dengan proyek dengan membuka file README.
128 |
129 | 
130 |
131 | ## Struktur proyek yang dihasilkan (React-based app)
132 |
133 | my-app
134 | ├── server # Proyek file go
135 | │ ├── db # Komunikasi dengan MongoDB
136 | │ ├── model # domain objek
137 | │ ├── web # REST APIs, web server
138 | │ ├── server.go # titik awal dari server
139 | │ └── go.mod # server dependensi
140 | ├── webapp
141 | │ ├── public # icons, static file, dan index.html
142 | │ ├── src
143 | │ │ ├── App.js # titik awal komponen React
144 | │ │ ├── App.css # App component-specific style
145 | │ │ ├── index.js # titik awal dari the application
146 | │ │ └── index.css # style global
147 | │ ├── package.json # front end dependensi
148 | │ ├── .env.development # memegang API endpoint untuk fase pengembangan
149 | │ └── .env.production # API endpoint untuk fase produksi
150 | ├── Dockerfile # membangun back end dan front-end secara bersamaan
151 | ├── docker-compose.yml # prod environemnt deployment deskriptor
152 | ├── docker-compose-dev.yml # menjalankan local MongoDB untuk kepentingan pengembangan
153 | ├── init-db.js # membuat koleksi MongoDB dengan data uji
154 | ├── .dockerignore # menentukan file yang diabaikan dalam pembuatan Docker
155 | ├── .gitignore
156 | └── README.md # panduan tentang cara menggunakan repo yang dihasilkan
157 |
158 | File seperti unit test atau komponen sampel tidak termasuk di sini
159 | untuk kesederhanaan.
160 |
161 | ## Dependensi
162 |
163 | Goxygen menghasilkan struktur dasar suatu proyek dan tidak memaksa Anda
164 | untuk menggunakan seperangkat alat tertentu. Itu sebabnya Goxygen tidak
165 | membawa dependensi yang tidak dibutuhkan pada proyek Anda. Hanya menggunakan
166 | database driver pada back end side dan [axios](https://github.com/axios/axios)
167 | pada projek React dan Vue. Angular proyek hanya menggunakan Angular library
168 | tertentu.
169 |
170 | ## Bagaimana cara berkontribusi
171 |
172 | Jika Anda menemukan bug atau punya ide tentang cara meningkatkan proyek
173 | [open an issue](https://github.com/Shpota/goxygen/issues)
174 | dan kami akan memperbaikinya sesegera mungkin. Anda juga dapat mengusulkan
175 | perubahan melalui Pull Request. Fork repositori, buat perubahan, dan kirim
176 | kami pull request dan kami akan segera memeriksanya. Kami juga punya
177 | [Gitter chat](https://gitter.im/goxygen/community) dimana kita bahas
178 | semua perubahan.
179 |
180 | ### Penghargaan
181 | Goxygen's logo dibuat oleh [Egon Elbre](https://twitter.com/egonelbre).
182 |
--------------------------------------------------------------------------------
/docs/README_jp.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Go、Angular / React / Vue を用いた Web プロジェクトを生成します。**
57 |
58 | Goxygen は、新しいプロジェクトを始める際の時間の節約を目的としており、すべての
59 | 設定が済まされたアプリケーションの雛形を作成します。ビジネスロジックの実装をす
60 | ぐに開始できます。Goxygen はバックエンドの Go 言語のコードを生成し、それをフロ
61 | ントエンドコンポーネントと関連づけます。加えて、アプリケーション用の Dockerfile
62 | を提供し、開発および本番環境での実行に便利な docker-compose ファイルを作成しま
63 | す。
64 |
65 | <table>
66 | <thead>
67 | <tr align="center">
68 | <td colspan=4><b>対応技術</b></td>
69 | </tr>
70 | </thead>
71 | <tbody>
72 | <tr align="center">
73 | <td align="center">フロントエンド</td>
74 | <td>Angular</td>
75 | <td>React</td>
76 | <td>Vue</td>
77 | </tr>
78 | <tr align="center">
79 | <td>バックエンド</td>
80 | <td colspan=3>Go</td>
81 | </tr>
82 | <tr align="center">
83 | <td>データベース</td>
84 | <td>MongoDB</td>
85 | <td>MySQL</td>
86 | <td>PostgreSQL</td>
87 | </tr>
88 | </tbody>
89 | </table>
90 |
91 | ## Requirements
92 | Go 1.16 以上が必要です。
93 |
94 | ## 使用方法
95 | ```go
96 | go run github.com/shpota/goxygen@latest init my-app
97 | ```
98 | `my-app` プロジェクトを `my-app` フォルダに生成します。
99 |
100 | デフォルトでは、React 及び MongoDB を使用します。
101 | `--frontend` と `--db` フラグを使って異なる
102 | フロントエンドフレームワークとデータベースを選べます。
103 | 例えば、次のコマンドは Vue と PostgreSQL を含むプロジェクト作成します:
104 |
105 | ```go
106 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
107 | ```
108 |
109 | `--frontend` フラグは、`angular` や `react`、`vue` を受け取ります。
110 | `--db` フラグは、`mongo` や `mysql`、`postgres` を受け取ります。
111 |
112 | 生成されたプロジェクトは、`docker-compse` で実行する準備が整っています:
113 | ```sh
114 | cd my-app
115 | docker compose up
116 | ```
117 | ビルドが完了後、アプリケーションは http://localhost:8080 でアクセスできるように
118 | なります。
119 |
120 | 生成されたプロジェクトの操作方法に関する詳細については、READMEファイルを参照し
121 | てください。
122 |
123 | 
124 |
125 | ## 生成されるプロジェクトの構造 (React/MongoDBベースアプリケーション)
126 |
127 | my-app
128 | ├── server # Go プロジェクトファイル
129 | │ ├── db # MongoDB との通信
130 | │ ├── model # ドメインオブジェクト
131 | │ ├── web # REST APIs, web サーバ
132 | │ ├── server.go # サーバの開始点
133 | │ └── go.mod # サーバ依存関係
134 | ├── webapp
135 | │ ├── public # アイコン、静的ファイル、index.html
136 | │ ├── src
137 | │ │ ├── App.js # 主要な React コンポーネント
138 | │ │ ├── App.css # アプリコンポーネント固有のスタイル
139 | │ │ ├── index.js # アプリケーションのエントリポイント
140 | │ │ └── index.css # 全体のスタイル
141 | │ ├── package.json # フロントエンド依存関係
142 | │ ├── .env.development # 開発環境の API エンドポイント保持
143 | │ └── .env.production # プロダクション環境の API エンドポイント
144 | ├── Dockerfile # バックエンド・フロントエンドを共に構築します
145 | ├── docker-compose.yml # プロダクション環境の配置記述
146 | ├── docker-compose-dev.yml # 開発に必要なローカルの MongoDB を実行する
147 | ├── init-db.js # テストデータで MongoDB コレクションを作成します
148 | ├── .dockerignore # Docker のビルドで無視するファイルを指定します
149 | ├── .gitignore
150 | └── README.md # 生成したリポジトリの使用方法に関するガイド
151 |
152 | 単純にするため、ここには単体テストやサンプルコンポーネントなどのファイルは含ま
153 | れていません。
154 |
155 | ## 依存関係
156 |
157 | Goxygen は、プロジェクトの基本的な構造を生成し、特定のツール群を使用するように
158 | 強制しません。それが、プロジェクトに不要な依存関係をもたらさない理由です。バッ
159 | クエンド側では database driver を、
160 | React 及び Vue プロジェクトでは、[axios](https://github.com/axios/axios) のみを
161 | 使用します。Angular プロジェクトでは、Angular 固有のライブラリのみを使用します。
162 |
163 | ## 貢献の仕方
164 |
165 | バグを発見した場合、またはプロジェクトを改善する方法についてアイディアがある場
166 | 合 [open an issue](https://github.com/Shpota/goxygen/issues)、できるだけ早く修
167 | 正します。Pull Request を通して変更を提案することもできます。リポジトリを Fork
168 | し、変更を加え、Pull Request を送信してください。すぐに確認をします。また、あら
169 | ゆる変更点について話し合う [Gitter chat](https://gitter.im/goxygen/community)
170 | もあります。
171 |
172 | ### クレジット
173 | Goxygen のロゴは、[Egon Elbre](https://twitter.com/egonelbre) によって作成され
174 | ました。
175 |
--------------------------------------------------------------------------------
/docs/README_ko.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **순식간에 GO 그리고 Angular/React/Vue 를 활용한 웹 프로젝트를 생성해보세요**
57 | Goxygen은 사용자가 새로운 프로젝트를 설정하는데 필요한 시간을 아끼는데 중점을 두고있습니다.
58 | 사용자를 위한 모든 설정을 포함한 어플리케이션의 뼈대를 생성합니다. 사용자는 생각했던
59 | 비지니스 로직을 즉시 행동으로 옮길 수 있습니다. Goxygen 은 Go 코드로 벡엔드를 생성하고,
60 | 그것을 프론트엔드 요소들에 연결 시킨 후, 어플리케이션을 위한 Dockerfile 을 제공하면서
61 | 개발과 제작 환경에서 간단한 실행을 위한 docker-compose 파일을 만듭니다.
62 |
63 | <table>
64 | <thead>
65 | <tr align="center">
66 | <td colspan=4><b>Supported Technologies</b></td>
67 | </tr>
68 | </thead>
69 | <tbody>
70 | <tr align="center">
71 | <td align="center">Front End</td>
72 | <td>Angular</td>
73 | <td>React</td>
74 | <td>Vue</td>
75 | </tr>
76 | <tr align="center">
77 | <td>Back End</td>
78 | <td colspan=3>Go</td>
79 | </tr>
80 | <tr align="center">
81 | <td>Database</td>
82 | <td>MongoDB</td>
83 | <td>MySQL</td>
84 | <td>PostgreSQL</td>
85 | </tr>
86 | </tbody>
87 | </table>
88 |
89 | ## Requirements
90 | 사용자는 Go 1.16 또는 그 이상의 버젼이 필요합니다.
91 |
92 | ## 사용하는 방법
93 | ```go
94 | go run github.com/shpota/goxygen@latest init my-app
95 | ```
96 | `my-app` 폴더에 프로젝트를 생성합니다.
97 |
98 | 기본설정으로 React 와 MongoDB를 사용합니다.
99 | 다른 프런트엔드 프레임워크와 데이터베이스를 선택하고 싶다면 `--frontend`와 `--db` 플래그를 사용합니다. 예를 들어 아래의 명령은 Vue와 PostgreSQL을 사용하여 프로젝트를 생성합니다:
100 |
101 | ```go
102 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
103 | ```
104 |
105 | The `--frontend` flag accepts `angular`, `react` and `vue`.
106 | The `--db` flag accepts `mongo`, `mysql` and `postgres`.
107 |
108 | 생성된 프로젝트는 `docker-compose`를 통해 실행 될 수 있습니다.
109 | ```sh
110 | cd my-app
111 | docker compose up
112 | ```
113 | 빌드가 끝나면, 어플리케이션은 http://localhost:8080에서 연결이
114 | 가능합니다.
115 |
116 | 사용자는 프로젝트의 README 파일에서 더 자세한 사항을 알아볼 수 있습니다
117 |
118 | 
119 |
120 | ## 생성된 프로젝트의 구조 (React/MongoDB 기반 앱)
121 |
122 | my-app
123 | ├── server # Go 프로젝트 파일
124 | │ ├── db # MongoDB 연결
125 | │ ├── model # domain objects
126 | │ ├── web # REST APIs, web server
127 | │ ├── server.go # 서버의 시작점
128 | │ └── go.mod # server 필수 요소
129 | ├── webapp
130 | │ ├── public # icons, static 파일, 그리고 index.html
131 | │ ├── src
132 | │ │ ├── App.js # 주 React 요소
133 | │ │ ├── App.css # App 요소 중점의 스타일(styles)
134 | │ │ ├── index.js # application의 시작 기점
135 | │ │ └── index.css # global 스타일(styles)
136 | │ ├── package.json # front end 필수 요소
137 | │ ├── .env.development # 개발환경의 API endpoint
138 | │ └── .env.production # 제작환경의 API endpoint
139 | ├── Dockerfile # 벡엔드와 프론트엔드를 함께 빌드
140 | ├── docker-compose.yml # 제작환경 배포 설명서
141 | ├── docker-compose-dev.yml # 개발에 필요한 로컬 MongoDB를 실행
142 | ├── init-db.js # 테스트 data 로 MongoDB 컬렉션 생성
143 | ├── .dockerignore # Docker 빌드에서 무시할 파일 설정
144 | ├── .gitignore
145 | └── README.md # 생성된 레포지토리 사용 가이드
146 |
147 | 간략함을 위해 유닛 테스트나 샘플요소는 추가되지 않았습니다.
148 |
149 | ## 필수요소(dependencies)
150 | Goxygen 프로젝트의 기본적인 구조만을 생성하며 사용자가 구체적인 도구(tool)를
151 | 사용하라고 강요하지 않습니다. 프로젝트에 필요없는 필수요소(dependency)를
152 | 가져오지 않는 이유가 여기에 있습니다. 벡엔드에는 오직
153 | database driver을 사용하며
154 | React나 Vue 프로젝트에선 [axios](https://github.com/axios/axios) 만을 사용합니다.
155 | Angular 프로젝트는 오직 Angular 특화된 라이브러리만을 사용합니다.
156 |
157 |
158 | ## 기여하는 방법
159 |
160 | 만약 버그를 찾았더라던가 이 프로젝트를 더 나은 방향으로 인도할 수 있는
161 | 아이디어를 갖고 있다면
162 | [이슈를 열어주세요](https://github.com/Shpota/goxygen/issues)
163 | 그리고 빠른 시일내에 조치하겠습니다. Pull Request를 통해 변경사항을 제안할 수
164 | 있습니다. 레포지토리를 Fork하고 더 좋은 방향으로 변경하고 Pull Request 를
165 | 저희에게 보내주세요. 짧은 시일내로 반영하겠습니다. 또한 저희는
166 | [Gitter chat](https://gitter.im/goxygen/community) 에서 모든 사항을
167 | 공유 중 입니다.
168 |
169 | ### 크레딧
170 | Goxygen 로고는 [Egon Elbre](https://twitter.com/egonelbre) 에 의해 만들어 졌습니다.
171 |
--------------------------------------------------------------------------------
/docs/README_pt-br.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Crie um projeto Web com Go e Angular/React/Vue em segundos.**
57 |
58 | Goxygen visa poupar seu tempo ao montar um novo projeto. Ele
59 | cria o esqueleto de uma aplicação com todas as configurações
60 | prontas para você. Você pode começar a implementar sua lógica
61 | de negócios imediatamente. Goxygen gera o código back end em Go,
62 | conecta ele com os componentes front end, fornece o Dockerfile
63 | para a aplicação e cria o arquivo docker-compose para rapidamente
64 | executar em ambientes de desenvolvimento e produção.
65 |
66 | <table>
67 | <thead>
68 | <tr align="center">
69 | <td colspan=4><b>Tecnologias suportadas</b></td>
70 | </tr>
71 | </thead>
72 | <tbody>
73 | <tr align="center">
74 | <td align="center">Front End</td>
75 | <td>Angular</td>
76 | <td>React</td>
77 | <td>Vue</td>
78 | </tr>
79 | <tr align="center">
80 | <td>Back End</td>
81 | <td colspan=3>Go</td>
82 | </tr>
83 | <tr align="center">
84 | <td>Database</td>
85 | <td>MongoDB</td>
86 | <td>MySQL</td>
87 | <td>PostgreSQL</td>
88 | </tr>
89 | </tbody>
90 | </table>
91 |
92 | ## Requisitos
93 | Você precisa de Go 1.16 ou mais recente na sua máquina.
94 |
95 | ## Como utilizar
96 |
97 | ```go
98 | go run github.com/shpota/goxygen@latest init my-app
99 | ```
100 |
101 | Isso gera um projeto no diretório `my-app`.
102 |
103 | Por padrão, será usado React e MongoDB. Você pode selecionar
104 | um framework de front end e um banco de dados diferentes usando
105 | os argumentos `--frontend` e `--db`. Por exemplo, este comando
106 | criará um projeto usando Vue e PostgreSQL:
107 |
108 | ```go
109 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
110 | ```
111 |
112 | O argumento `--frontend` aceita as opções `angular`, `react` e `vue`.
113 | O argumento `--db` aceita as opções `mongo`, `mysql` e `postgres`.
114 |
115 | O projeto gerado está pronto para ser executado com `docker-compose`:
116 | ```sh
117 | cd my-app
118 | docker compose up
119 | ```
120 |
121 | Após o build ser concluído, a aplicação ficará disponível em
122 | http://localhost:8080.
123 |
124 | Você pode encontrar mais detalhes de como utilizar o projeto
125 | gerado em seu arquivo README.
126 |
127 | 
128 |
129 | ## Estrutura do projeto gerado (Exemplo com React/MongoDB)
130 |
131 | my-app
132 | ├── server # Arquivos do projeto Go
133 | │ ├── db # Comunicação com o MongoDB
134 | │ ├── model # Objetos de domínio
135 | │ ├── web # REST APIs, servidor web
136 | │ ├── server.go # O ponto de acesso do servidor
137 | │ └── go.mod # dependências do servidor
138 | ├── webapp
139 | │ ├── public # ícones, arquivos estáticos e index.html
140 | │ ├── src
141 | │ │ ├── App.js # O principal componente React
142 | │ │ ├── App.css # Estilização do componente App
143 | │ │ ├── index.js # Ponto de entrada da aplicação
144 | │ │ └── index.css # Estilos globais
145 | │ ├── package.json # dependências do front end
146 | │ ├── .env.development # API endpoint para ambiente de desenvolvimento
147 | │ └── .env.production # API endpoint para ambiente de produção
148 | ├── Dockerfile # faz o build do back end e o front end juntos
149 | ├── docker-compose.yml # deploy em ambiente de produção
150 | ├── docker-compose-dev.yml # executa um MongoDB local para fins de desenvolvimento
151 | ├── init-db.js # cria um MongoDB collection com dados de teste
152 | ├── .dockerignore # especifica arquivos ignorados no Docker build
153 | ├── .gitignore
154 | └── README.md # guia sobre como usar o repositório gerado
155 |
156 | Arquivos como testes unitários ou componentes de exemplo não estão incluídos
157 | aqui para fins de simplicidade.
158 |
159 | ## Dependências
160 |
161 | Goxygen gera uma estrutura básica de um projeto e não o força usar um
162 | conjunto específico de ferramentas. E por isso não traz dependências
163 | desnecessárias para o seu projeto. Ele usa apenas
164 | um driver de banco de dados no back end
165 | e [axios](https://github.com/axios/axios) nos projetos React e Vue.
166 | Projetos Angular usam apenas bibliotecas específicas do Angular.
167 |
168 | ## Como contribuir
169 |
170 | Se você encontrou um bug ou tem alguma ideia de como melhorar o projeto,
171 | [abra um issue](https://github.com/Shpota/goxygen/issues)
172 | e nós iremos consertar o mais rápido possível. Você também pode enviar
173 | suas alterações via Pull Request. Dê um fork no repositório, faça
174 | alterações, nos envie um pull request que nós iremos analisar em breve.
175 | Nós também temos um
176 | [Gitter chat](https://gitter.im/goxygen/community) onde discutimos todas
177 | as alterações.
178 |
179 | ### Créditos
180 | O logo do Goxygen foi criado por [Egon Elbre](https://twitter.com/egonelbre).
181 |
--------------------------------------------------------------------------------
/docs/README_tr.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Go ve Angular, React veya Vue ile bir web projesi oluşturun.**
57 |
58 | Goxygen, yeni bir proje oluştururken sizin zamandan tasarruf etmenize odaklanır. Sizin için bütün konfigürasyonları yapılmış bir uygulama iskeleti oluşturur. İş mantığınızı hemen uygulamaya başlayabilirsiniz. Goxygen, back-end Go kodu oluşturur, front-end tarafında componentlere bağlar, uygulama için bir Dockerfile sağlar ve production ortamında rahat çalışma için docker-compose dosyalarını oluşturur.
59 |
60 | <table>
61 | <thead>
62 | <tr align="center">
63 | <td colspan=4><b>Desteklenen Teknolojiler</b></td>
64 | </tr>
65 | </thead>
66 | <tbody>
67 | <tr align="center">
68 | <td align="center">Front End</td>
69 | <td>Angular</td>
70 | <td>React</td>
71 | <td>Vue</td>
72 | </tr>
73 | <tr align="center">
74 | <td>Back End</td>
75 | <td colspan=3>Go</td>
76 | </tr>
77 | <tr align="center">
78 | <td>Database</td>
79 | <td>MongoDB</td>
80 | <td>MySQL</td>
81 | <td>PostgreSQL</td>
82 | </tr>
83 | </tbody>
84 | </table>
85 |
86 | ## Gereksinimler
87 |
88 | Makinenizde Go 1.16 veya daha yenisine sahip olmanız gerekmektedir.
89 |
90 | ## Nasıl Kullanılır
91 |
92 | Çalıştır:
93 |
94 | ```go
95 | go run github.com/shpota/goxygen@latest init my-app
96 | ```
97 |
98 | `my-app` klasöründe bir proje oluşturur.
99 |
100 | Varsayılan olarak React ve MongoDB'yi kullanacaktır. Farklı bir front-end framework'ü ve veritabanını `--frontend` ve `--db` flag'lerini kullanarak seçebilirsin. Örneğin bu komut Vue ve PostgreSQL ile bir proje oluşturacaktır:
101 |
102 | ```go
103 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
104 | ```
105 |
106 | `--frontend` flag'i `angular`, `react` ve `vue` değerlerini kabul eder.
107 | `--db` flag'i `mongo`, `mysql` ve `postgres` değerlerini kabul eder.
108 |
109 | Oluşturulan proje `docker-compose` komutu ile çalıştırmaya hazır olacaktır:
110 |
111 | ```sh
112 | cd my-app
113 | docker compose up
114 | ```
115 |
116 | Build tamamlandıktan sonra, uygulama http://localhost:8080 adresinden erişilebilir olacaktır.
117 |
118 | Oluşturulan projeyle nasıl çalışılacağı hakkında daha fazla ayrıntıyı README dosyasında bulabilirsiniz.
119 |
120 | 
121 |
122 | ## Oluşturulmuş bir projenin yapısı (Örnek: React/MongoDB)
123 |
124 | my-app
125 | ├── server # Go proje dosyaları
126 | │ ├── db # MongoDB iletişimleri
127 | │ ├── model # domain nesneleri
128 | │ ├── web # REST APIs, web server
129 | │ ├── server.go # Sunucunun başlama noktası
130 | │ └── go.mod # Sunucu bağımlılıkları
131 | ├── webapp
132 | │ ├── public # ikonlar, sabit dosyalar, ve index.html
133 | │ ├── src
134 | │ │ ├── App.js # Ana React komponenti
135 | │ │ ├── App.css # Uygulama bileşenine özgü stiller
136 | │ │ ├── index.js # Uygulamanın giriş noktası
137 | │ │ └── index.css # global stiller
138 | │ ├── package.json # front end bağımlılıkları
139 | │ ├── .env.development # Geliştirme ortamı için API Endpointlerini barındırır.
140 | │ └── .env.production # Production ortamı için API endpoint'leri
141 | ├── Dockerfile # Back-end ve front-end'i birlikte oluşturur.
142 | ├── docker-compose.yml # Üretim ortamı dağıtım tanımlayıcısı
143 | ├── docker-compose-dev.yml # Geliştirme ihtiyaçları için yerel MongoDB çalıştırır.
144 | ├── init-db.js # Test verileriyle bir MongoDB koleksiyonu oluşturur.
145 | ├── .dockerignore # Docker yapılarında yok sayılan dosyaları belirtir.
146 | ├── .gitignore
147 | └── README.md # Oluşturulan repo'nun nasıl kullanılacağına dair kılavuz.
148 |
149 | Birim testleri veya örnek komponentler gibi dosyalar, basitlik açısından buraya dahil edilmemiştir.
150 |
151 | ## Bağımlılıklar
152 |
153 | Goxygen, bir projenin temel yapısını oluşturur ve sizi belirli bir takım araçları kullanmaya zorlamaz. Bu yüzden projenize gereksiz bağımlılıklar getirmez. React ve Vue projelerinde yalnızca arka uç tarafında bir veritabanı sürücüsü ve [axios] (https://github.com/axios/axios) kullanır. Angular projeleri yalnızca Angular'a özgü kütüphaneleri kullanır.
154 |
155 | ## Nasıl katkıda bulunulur
156 |
157 | Bir hata bulduysanız veya projeyi nasıl iyileştireceğiniz konusunda bir fikriniz varsa [issue oluşturun](https://github.com/Shpota/goxygen/issues) ve mümkün olan en kısa süre içerisinde düzelteceğiz. Ayrıca Pull Request ile önerebilirsin. Repository'i fork'layın, değişikleri yapın ve bize bir Pull Request gönderin ve kısa süre içerisinde inceleyeceğiz. Ayrıca tüm değişikleri tartıştığımız [Gitter chat](https://gitter.im/goxygen/community) var.
158 |
159 | ## Jenerik
160 |
161 | Goxygen'in logosu [Egon Elbre](https://twitter.com/egonelbre) tarafından yaratılmıştır.
162 |
--------------------------------------------------------------------------------
/docs/README_ua.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 |
54 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
55 |
56 | **Згенеруйте Web проєкт з використанням Go та сучасних SPA фреймворків.**
57 |
58 | Goxygen зберігає ваш час при створенні нових проєктів. Він
59 | генерує базову структуру проєкту і дозволяє вам відразу ж перейти до
60 | реалізації бізнес логіки без турбот про налаштування. Goxygen створює
61 | back end код на Go, зв'язує його з front end компонентами, додає
62 | `Dockerfile` та `docker-compose` для зручного запуску локально та в
63 | production середовищі.
64 |
65 | <table>
66 | <thead>
67 | <tr align="center">
68 | <td colspan=4><b>Доступні технології</b></td>
69 | </tr>
70 | </thead>
71 | <tbody>
72 | <tr align="center">
73 | <td align="center">Front End</td>
74 | <td>Angular</td>
75 | <td>React</td>
76 | <td>Vue</td>
77 | </tr>
78 | <tr align="center">
79 | <td>Back End</td>
80 | <td colspan=3>Go</td>
81 | </tr>
82 | <tr align="center">
83 | <td>База даних</td>
84 | <td>MongoDB</td>
85 | <td>MySQL</td>
86 | <td>PostgreSQL</td>
87 | </tr>
88 | </tbody>
89 | </table>
90 |
91 | ## Вимоги
92 | Ви повинні мати Go 1.16 або новішу версію на вашому комп'ютері.
93 |
94 | ## Як користуватися
95 | ```go
96 | go run github.com/shpota/goxygen@latest init my-app
97 | ```
98 | В результаті буде згенеровано проєкт в папці `my-app`.
99 |
100 | React і MongoDB використовуються за замовчанням. Ви можете
101 | обрати інший front end фреймворк та іншу базу даних
102 | використовуючи параметри `--frontend` та `--db` відповідно.
103 | Наступна команда генерує проєкт з Vue та PostgreSQL:
104 |
105 | ```go
106 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
107 | ```
108 |
109 | Параметер `--frontend` може бути встановленим в `angular`, `react` та `vue`.
110 | Параметер `--db` може бути встановленим в `mongo`, `mysql` та `postgres`.
111 |
112 | Згенерований проєкт готовий до запуску з `docker-compose`:
113 | ```sh
114 | cd my-app
115 | docker compose up
116 | ```
117 | Після завершення збірки, застосунок буде доступний на
118 | http://localhost:8080.
119 |
120 | Більше деталей про те, як працювати зі згенерованим проєктом,
121 | можна знайти в його README.
122 |
123 | 
124 |
125 | ## Структура згенерованого проєкту (на пиркладі React/MongoDB)
126 |
127 | my-app
128 | ├── server # серверна частина застосунку (Go)
129 | │ ├── db # комунікації MongoDB
130 | │ ├── model # доменні об'єкти
131 | │ ├── web # REST API та Web сервер
132 | │ ├── server.go # вхідна точка серверного коду
133 | │ └── go.mod # опис Go модуля та залежності
134 | ├── webapp
135 | │ ├── public # іконки, статичні файли та index.html
136 | │ ├── src
137 | │ │ ├── App.js # головний React компонент
138 | │ │ ├── App.css # стилі головного компоненту
139 | │ │ ├── index.js # вхідна точка front end застосунку
140 | │ │ └── index.css # глобальні стилі
141 | │ ├── package.json # front end залежності
142 | │ ├── .env.development # API URL для запуску в development середовищі
143 | │ └── .env.production # API URL для запуску в production середовищі
144 | ├── Dockerfile # збирає front end та back end разом
145 | ├── docker-compose.yml # налаштування для запуску в production середовищі
146 | ├── docker-compose-dev.yml # налаштування запуску локальної MongoDB
147 | ├── init-db.js # наповнює базу даних початковими даними
148 | ├── .dockerignore # перерахунок файлів, які ігноруються при збірці Docker
149 | ├── .gitignore
150 | └── README.md # інструкція по використанню проєкту
151 |
152 | Юніт тести та демонстраційні компоненти не відображені в
153 | структурі задля простоти.
154 |
155 | ## Залежності
156 |
157 | Goxygen генерує лише базову структуру проєкту і не нав'язує вам
158 | використання специфічних бібліотек чи утиліт. Згенерований проєкт
159 | використовує лише драйвер бази даних в back end частині та
160 | [axios](https://github.com/axios/axios) для асинхронних REST запитів
161 | (для React i Vue проєктів).
162 |
163 | ## Як долучитися до проєкту
164 |
165 | Якщо ви знайшли помилку або маєте ідеї щодо покращення проєкту,
166 | [відкрийте issue](https://github.com/Shpota/goxygen/issues)
167 | і ми ним займемся. Якщо хочете запропонувати зміни - можете
168 | обговорити їх [в нашому Gitter чаті](https://gitter.im/goxygen/community)
169 | або створити Pull Request.
170 |
171 | ### Подяки
172 | Лого Goxygen створив [Egon Elbre](https://twitter.com/egonelbre).
173 |
--------------------------------------------------------------------------------
/docs/README_zh.md:
--------------------------------------------------------------------------------
1 | <h1 align="center">
2 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README.md">
3 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
4 | </a>
5 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_zh.md">
6 | <img height="25px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
7 | </a>
8 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ua.md">
9 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ua.svg">
10 | </a>
11 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_ko.md">
12 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
13 | </a>
14 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_pt-br.md">
15 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/br.svg">
16 | </a>
17 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_by.md">
18 | <img height="20px" src="https://raw.githubusercontent.com/Shpota/goxygen/main/docs/flag-by.svg">
19 | </a>
20 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_fr.md">
21 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
22 | </a>
23 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_es.md">
24 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
25 | </a>
26 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_jp.md">
27 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
28 | </a>
29 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_id.md">
30 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
31 | </a>
32 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_he.md">
33 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/il.svg">
34 | </a>
35 | <a href="https://github.com/Shpota/goxygen/tree/main/docs/README_tr.md">
36 | <img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
37 | </a>
38 | <br>
39 | Goxygen
40 | <a href="https://github.com/Shpota/goxygen/actions?query=workflow%3Abuild">
41 | <img src="https://github.com/Shpota/goxygen/workflows/build/badge.svg">
42 | </a>
43 | <a href="https://github.com/Shpota/goxygen/releases">
44 | <img src="https://img.shields.io/github/v/tag/shpota/goxygen?color=green&label=version">
45 | </a>
46 | <a href="https://gitter.im/goxygen/community">
47 | <img src="https://badges.gitter.im/goxygen/community.svg">
48 | </a>
49 | <a href="https://github.com/Shpota/goxygen/pulls">
50 | <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
51 | </a>
52 | </h1>
53 | <img src="../templates/vue.webapp/src/assets/logo.svg" align="right" width="230px" alt="goxygen logo">
54 |
55 | **分分钟生成一个全栈Web项目(Go,Angular/React/Vue)。**
56 |
57 | Goxygen致力于节省你搭建一个项目的时间。它自动生成一个完全配置好的项目骨架,以方便你可以立即着手实现你的业务逻辑。Goxygen生产后端的Go代码,并将其与前端组件相连,并且为生成的项目提供Dockerfile和docker-compose文件,以便项目在开发环境和生产环境快速运行起来。
58 |
59 | <table>
60 | <thead>
61 | <tr align="center">
62 | <td colspan=4><b>Supported Technologies</b></td>
63 | </tr>
64 | </thead>
65 | <tbody>
66 | <tr align="center">
67 | <td align="center">Front End</td>
68 | <td>Angular</td>
69 | <td>React</td>
70 | <td>Vue</td>
71 | </tr>
72 | <tr align="center">
73 | <td>Back End</td>
74 | <td colspan=3>Go</td>
75 | </tr>
76 | <tr align="center">
77 | <td>Database</td>
78 | <td>MongoDB</td>
79 | <td>MySQL</td>
80 | <td>PostgreSQL</td>
81 | </tr>
82 | </tbody>
83 | </table>
84 |
85 | ## Requirements
86 | 你需要安装Go 1.16或者更新的版本。
87 |
88 | # 如何使用
89 | ```go
90 | go run github.com/shpota/goxygen@latest init my-app
91 | ```
92 | 这会在你的 `my-app` 目录下生成一个项目。
93 |
94 | By default, it will use React and MongoDB. You can select
95 | a different front end framework and a database using
96 | `--frontend` and `--db` flags. For instance, this command
97 | will create a project with Vue and PostgreSQL:
98 |
99 | ```go
100 | go run github.com/shpota/goxygen@latest init --frontend vue --db postgres my-app
101 | ```
102 |
103 | The `--frontend` flag accepts `angular`, `react` and `vue`.
104 | The `--db` flag accepts `mongo`, `mysql` and `postgres`.
105 |
106 |
107 | 这个项目已经可以用`docker-compose`来运行了:
108 | ```sh
109 | cd my-app
110 | docker compose up
111 | ```
112 | build完成之后,就可以在 http://localhost:8080 查看你的Web项目了。
113 |
114 | 你可以在生成的项目里的README里查看更多细节信息。
115 |
116 | 
117 |
118 | ## 生成的项目的结构 (基于React/MongoDB的项目)
119 | my-app
120 | ├── server # Go项目文件
121 | │ ├── db # MongoDB通信
122 | │ ├── model # 领域对象
123 | │ ├── web # REST APIs, web server
124 | │ ├── server.go # 后端入口
125 | │ └── go.mod # 后端依赖
126 | ├── webapp
127 | │ ├── public # icons, static files, 和 index.html
128 | │ ├── src
129 | │ │ ├── App.js # React main组件
130 | │ │ ├── App.css # App组件样式
131 | │ │ ├── index.js # 前端应用入口
132 | │ │ └── index.css # 全局样式
133 | │ ├── package.json # 前端依赖
134 | │ ├── .env.development # 包含开发环境的API endpoint
135 | │ └── .env.production # 包含生产环境的API endpoint
136 | ├── Dockerfile # 前后端build Dockerfile
137 | ├── docker-compose.yml # 生产环境的docker-compose
138 | ├── docker-compose-dev.yml # 开发使用的docker-compose
139 | ├── init-db.js # 创建一个 MongoDB collection,并写入测试数据
140 | ├── .dockerignore # 指明Docker build的时候要忽略的文件
141 | ├── .gitignore
142 | └── README.md # 如何使用生成repo的教程
143 |
144 | 为了简洁性,诸如单测和样例组件的文件没有显示在这里。
145 |
146 | ## 依赖
147 |
148 | Goxygen只是为你生成一个项目的基本框架,但不强迫你使用任何特定的工具。它不会为你的项目添加任何不必要的依赖,仅有的依赖只有后端的database driver和前端的[axios](https://github.com/axios/axios)
149 |
150 | ## 如何贡献
151 |
152 | 如果你发现了bug或者对于如果改进项目有新的想法,[请提交一个issue](https://github.com/Shpota/goxygen/issues),我们会尽快解决。
153 |
154 | 你也可以直接Pull Request来提交你的修改。Fork这个项目,作出修改之后,发起一个Pull Request,我们会很快review它。
155 |
156 | ### 感谢
157 | Goxygen的logo是由[Egon Elbre](https://twitter.com/egonelbre)创作的。
158 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: minima
2 |
3 | twitter_username: sashashpota
4 | github_username: shpota
5 | linkedin_username: shpota
6 | mastodon:
7 | - username: shpota
8 | instance: mastodon.social
9 |
--------------------------------------------------------------------------------
/docs/_includes/footer.html:
--------------------------------------------------------------------------------
1 | <footer class="site-footer h-card">
2 | <data class="u-url" href="{{ "/" | relative_url }}"></data>
3 |
4 | <div class="wrapper">
5 |
6 | <div class="footer-col-wrapper">
7 | <div class="footer-col footer-col-1">
8 | <ul class="contact-list">
9 | <li class="p-name">Goxygen</li>
10 | <li class="p-name">by Sasha Shpota</li>
11 | {%- if site.email -%}
12 | <li><a class="u-email" href="mailto:{{ site.email }}">{{ site.email }}</a></li>
13 | {%- endif -%}
14 | </ul>
15 | </div>
16 |
17 | <div class="footer-col footer-col-2">
18 | {%- include social.html -%}
19 | </div>
20 |
21 | <div class="footer-col footer-col-3">
22 | <p>Web Development Tooling</p>
23 | </div>
24 | </div>
25 |
26 | </div>
27 |
28 | </footer>
29 |
--------------------------------------------------------------------------------
/docs/_includes/head.html:
--------------------------------------------------------------------------------
1 | <head>
2 | <meta charset="utf-8">
3 | <meta http-equiv="X-UA-Compatible" content="IE=edge">
4 | <meta name="viewport" content="width=device-width, initial-scale=1">
5 | <title>Goxygen | Generate a Web project with Go and Angular, React or Vue.</title>
6 | <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
7 | <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
8 | <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
9 | <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
10 | <link rel="android-chrome" sizes="192x192" href="/android-chrome-192x192.png">
11 | <meta property="og:title" content="Goxygen | Generate a Web project with Go and Angular, React or Vue.">
12 | <meta property="og:locale" content="en_US">
13 | <meta name="description" content="Goxygen allows you to generate a modern Web project with Go on the back end side and Angular, React, or Vue on the front end.">
14 | <meta property="og:description"
15 | content="Goxygen allows you to generate a modern Web project with Go on the back end side and Angular, React, or Vue on the front end.">
16 | <link rel="canonical" href="https://goxygen.dev/">
17 | <meta property="og:url" content="https://goxygen.dev/">
18 | <meta property="og:site_name" content="goxygen">
19 | <meta property="og:type" content="website">
20 | <meta name="twitter:card" content="summary">
21 | <meta name="twitter:title" property="og:title" content="Generate a Web project with Go and Angular, React or Vue.">
22 | <meta name="author" content="Sasha Shpota">
23 | <meta name="twitter:site" content="@sashashpota">
24 | <meta name="twitter:creator" content="@sashashpota">
25 | <script type="application/ld+json">
26 | {
27 | "@context": "https://schema.org",
28 | "@type": "WebSite",
29 | "description": "Goxygen allows you to generate a modern Web project with Go on the back end side and Angular, React, or Vue on the front end.",
30 | "headline": "Generate a modern Web project with Go and Angular, React, or Vue in seconds.",
31 | "name": "goxygen",
32 | "url": "https://goxygen.dev/"
33 | }</script>
34 | <link rel="stylesheet" href="/assets/main.css">
35 | <link type="application/atom+xml" rel="alternate" href="https://goxygen.dev/feed.xml" title="goxygen">
36 | </head>
37 |
--------------------------------------------------------------------------------
/docs/_includes/header.html:
--------------------------------------------------------------------------------
1 | <div></div>
--------------------------------------------------------------------------------
/docs/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/docs/android-chrome-192x192.png
--------------------------------------------------------------------------------
/docs/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/docs/apple-touch-icon.png
--------------------------------------------------------------------------------
/docs/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/docs/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/docs/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/flag-by.svg:
--------------------------------------------------------------------------------
1 | <svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-by" viewBox="0 0 640 480">
2 | <g fill-rule="evenodd">
3 | <path fill="#ed2939" d="M640 480H0V0h640z"/>
4 | <path fill="#fff" d="M640 480H0V320h640zm0-319.9H0V.1h640z"/>
5 | </g>
6 | </svg>
--------------------------------------------------------------------------------
/docs/showcase.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/docs/showcase.gif
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/shpota/goxygen
2 |
3 | go 1.21
4 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | //go:generate go run transform/transformer.go
2 |
3 | package main
4 |
5 | import (
6 | "github.com/shpota/goxygen/cli"
7 | "github.com/shpota/goxygen/codegen"
8 | "os"
9 | )
10 |
11 | func main() {
12 | args := os.Args[1:]
13 | cli.Start(os.Stdout, args, codegen.Generate)
14 | }
15 |
--------------------------------------------------------------------------------
/templates/.dockerignore:
--------------------------------------------------------------------------------
1 | webapp/node_modules/
2 | webapp/build/
3 |
--------------------------------------------------------------------------------
/templates/.gitignore:
--------------------------------------------------------------------------------
1 | *.exe
2 | *.exe~
3 | *.dll
4 | *.so
5 | *.dylib
6 | *.test
7 | *.out
8 |
9 | webapp/node_modules
10 | webapp/build
11 | webapp/npm-debug.log*
12 |
--------------------------------------------------------------------------------
/templates/angular.webapp/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/templates/angular.webapp/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # Compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | /bazel-out
8 | /build
9 |
10 | # Node
11 | /node_modules
12 | npm-debug.log
13 | yarn-error.log
14 |
15 | # IDEs and editors
16 | .idea/
17 | .project
18 | .classpath
19 | .c9/
20 | *.launch
21 | .settings/
22 | *.sublime-workspace
23 |
24 | # Visual Studio Code
25 | .vscode/*
26 | !.vscode/settings.json
27 | !.vscode/tasks.json
28 | !.vscode/launch.json
29 | !.vscode/extensions.json
30 | .history/*
31 |
32 | # Miscellaneous
33 | /.angular/cache
34 | .sass-cache/
35 | /connect.lock
36 | /coverage
37 | /libpeerconnection.log
38 | testem.log
39 | /typings
40 |
41 | # System files
42 | .DS_Store
43 | Thumbs.db
44 |
--------------------------------------------------------------------------------
/templates/angular.webapp/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3 | "recommendations": ["angular.ng-template"]
4 | }
5 |
--------------------------------------------------------------------------------
/templates/angular.webapp/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3 | "version": "0.2.0",
4 | "configurations": [
5 | {
6 | "name": "ng serve",
7 | "type": "chrome",
8 | "request": "launch",
9 | "preLaunchTask": "npm: start",
10 | "url": "http://localhost:4200/"
11 | },
12 | {
13 | "name": "ng test",
14 | "type": "chrome",
15 | "request": "launch",
16 | "preLaunchTask": "npm: test",
17 | "url": "http://localhost:9876/debug.html"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/templates/angular.webapp/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
3 | "version": "2.0.0",
4 | "tasks": [
5 | {
6 | "type": "npm",
7 | "script": "start",
8 | "isBackground": true,
9 | "problemMatcher": {
10 | "owner": "typescript",
11 | "pattern": "$tsc",
12 | "background": {
13 | "activeOnStart": true,
14 | "beginsPattern": {
15 | "regexp": "(.*?)"
16 | },
17 | "endsPattern": {
18 | "regexp": "bundle generation complete"
19 | }
20 | }
21 | }
22 | },
23 | {
24 | "type": "npm",
25 | "script": "test",
26 | "isBackground": true,
27 | "problemMatcher": {
28 | "owner": "typescript",
29 | "pattern": "$tsc",
30 | "background": {
31 | "activeOnStart": true,
32 | "beginsPattern": {
33 | "regexp": "(.*?)"
34 | },
35 | "endsPattern": {
36 | "regexp": "bundle generation complete"
37 | }
38 | }
39 | }
40 | }
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/templates/angular.webapp/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "project-name": {
7 | "projectType": "application",
8 | "schematics": {},
9 | "root": "",
10 | "sourceRoot": "src",
11 | "prefix": "app",
12 | "architect": {
13 | "build": {
14 | "builder": "@angular-devkit/build-angular:browser",
15 | "options": {
16 | "outputPath": "build",
17 | "index": "src/index.html",
18 | "main": "src/main.ts",
19 | "polyfills": [
20 | "zone.js"
21 | ],
22 | "tsConfig": "tsconfig.app.json",
23 | "assets": [
24 | "src/favicon.ico",
25 | "src/assets"
26 | ],
27 | "styles": [
28 | "src/styles.css"
29 | ],
30 | "scripts": []
31 | },
32 | "configurations": {
33 | "production": {
34 | "budgets": [
35 | {
36 | "type": "initial",
37 | "maximumWarning": "500kb",
38 | "maximumError": "1mb"
39 | },
40 | {
41 | "type": "anyComponentStyle",
42 | "maximumWarning": "2kb",
43 | "maximumError": "4kb"
44 | }
45 | ],
46 | "outputHashing": "all"
47 | },
48 | "development": {
49 | "buildOptimizer": false,
50 | "optimization": false,
51 | "vendorChunk": true,
52 | "extractLicenses": false,
53 | "sourceMap": true,
54 | "namedChunks": true,
55 | "fileReplacements": [
56 | {
57 | "replace": "src/environments/environment.ts",
58 | "with": "src/environments/environment.development.ts"
59 | }
60 | ]
61 | }
62 | },
63 | "defaultConfiguration": "production"
64 | },
65 | "serve": {
66 | "builder": "@angular-devkit/build-angular:dev-server",
67 | "configurations": {
68 | "production": {
69 | "browserTarget": "project-name:build:production"
70 | },
71 | "development": {
72 | "browserTarget": "project-name:build:development"
73 | }
74 | },
75 | "defaultConfiguration": "development"
76 | },
77 | "extract-i18n": {
78 | "builder": "@angular-devkit/build-angular:extract-i18n",
79 | "options": {
80 | "browserTarget": "project-name:build"
81 | }
82 | },
83 | "test": {
84 | "builder": "@angular-devkit/build-angular:karma",
85 | "options": {
86 | "polyfills": [
87 | "zone.js",
88 | "zone.js/testing"
89 | ],
90 | "tsConfig": "tsconfig.spec.json",
91 | "assets": [
92 | "src/favicon.ico",
93 | "src/assets"
94 | ],
95 | "styles": [
96 | "src/styles.css"
97 | ],
98 | "scripts": []
99 | }
100 | }
101 | }
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/templates/angular.webapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "project-name",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve --port 3000",
7 | "build": "ng build --configuration production",
8 | "watch": "ng build --watch --configuration development"
9 | },
10 | "private": true,
11 | "dependencies": {
12 | "@angular/animations": "^16.0.0",
13 | "@angular/common": "^16.0.0",
14 | "@angular/compiler": "^16.0.0",
15 | "@angular/core": "^16.0.0",
16 | "@angular/forms": "^16.0.0",
17 | "@angular/platform-browser": "^16.0.0",
18 | "@angular/platform-browser-dynamic": "^16.0.0",
19 | "@angular/router": "^16.0.0",
20 | "rxjs": "~7.8.0",
21 | "tslib": "^2.3.0",
22 | "zone.js": "~0.13.0"
23 | },
24 | "devDependencies": {
25 | "@angular-devkit/build-angular": "^16.0.4",
26 | "@angular/cli": "~16.0.4",
27 | "@angular/compiler-cli": "^16.0.0",
28 | "@types/jasmine": "~4.3.0",
29 | "jasmine-core": "~4.6.0",
30 | "karma": "~6.4.0",
31 | "karma-coverage": "~2.2.0",
32 | "karma-jasmine": "~5.1.0",
33 | "karma-jasmine-html-reporter": "~2.0.0",
34 | "typescript": "~5.0.2"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/app.component.css:
--------------------------------------------------------------------------------
1 | code {
2 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
3 | monospace;
4 | background-color: #b3e6ff;
5 | }
6 |
7 | .title {
8 | text-align: center;
9 | }
10 |
11 | .logo {
12 | text-align: center;
13 | }
14 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/app.component.html:
--------------------------------------------------------------------------------
1 | <div class="app">
2 | <h2 class="title">{{title}}</h2>
3 | <div class="logo"><img src="assets/logo.svg" height="150px" alt="logo" /></div>
4 | <div>
5 | This project is generated with <b><a href="https://github.com/shpota/goxygen">goxygen</a></b>.
6 | <p>
7 | The following list of technologies comes from
8 | a REST API call to the Go-based back end. Find
9 | and change the corresponding code in
10 | <code>webapp/src/app/tech/tech.component.ts</code>
11 | and <code>server/web/app.go</code>.
12 | </p>
13 | <app-tech></app-tech>
14 | </div>
15 | </div>
16 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.css']
7 | })
8 | export class AppComponent {
9 | title = 'project-name';
10 | }
11 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 |
4 | import { AppComponent } from './app.component';
5 | import { TechComponent } from './tech/tech.component';
6 | import { HttpClientModule } from '@angular/common/http';
7 |
8 | @NgModule({
9 | declarations: [
10 | AppComponent,
11 | TechComponent
12 | ],
13 | imports: [
14 | BrowserModule,
15 | HttpClientModule
16 | ],
17 | providers: [],
18 | bootstrap: [AppComponent]
19 | })
20 | export class AppModule { }
21 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/tech/tech.component.html:
--------------------------------------------------------------------------------
1 | <ul class="technologies">
2 | <li *ngFor="let tech of technologies">
3 | <b>{{tech.name}}</b>: {{tech.details}}
4 | </li>
5 | </ul>
6 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/tech/tech.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { TechService } from './tech.service';
3 | import { Technology } from './tech.model';
4 |
5 | @Component({
6 | selector: 'app-tech',
7 | templateUrl: './tech.component.html'
8 | })
9 | export class TechComponent implements OnInit {
10 |
11 | technologies: Technology[] = [];
12 |
13 | constructor(private readonly techService: TechService) { }
14 |
15 | ngOnInit() {
16 | this.techService.getTechnologies().subscribe(value => {
17 | this.technologies = value;
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/tech/tech.model.ts:
--------------------------------------------------------------------------------
1 | export interface Technology {
2 | name: string;
3 | details: string;
4 | }
5 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/app/tech/tech.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { Observable } from 'rxjs';
4 | import { Technology } from './tech.model';
5 | import { environment } from '../../environments/environment';
6 |
7 | @Injectable({
8 | providedIn: 'root'
9 | })
10 | export class TechService {
11 |
12 | constructor(private readonly httpClient: HttpClient) { }
13 |
14 | getTechnologies(): Observable<Technology[]> {
15 | return this.httpClient.get<Technology[]>(`${environment.apiUrl}/api/technologies`);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/templates/angular.webapp/src/assets/.gitkeep
--------------------------------------------------------------------------------
/templates/angular.webapp/src/environments/environment.development.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | apiUrl: 'http://localhost:8080'
4 | };
5 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | apiUrl: ''
4 | };
5 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/favico.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/templates/angular.webapp/src/favico.ico
--------------------------------------------------------------------------------
/templates/angular.webapp/src/index.html:
--------------------------------------------------------------------------------
1 | <!doctype html>
2 | <html lang="en">
3 | <head>
4 | <meta charset="utf-8">
5 | <title>project-name</title>
6 | <base href="/">
7 | <meta name="viewport" content="width=device-width, initial-scale=1">
8 | <link rel="icon" type="image/x-icon" href="favicon.ico">
9 | </head>
10 | <body>
11 | <app-root></app-root>
12 | </body>
13 | </html>
14 |
15 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app/app.module';
4 |
5 |
6 | platformBrowserDynamic().bootstrapModule(AppModule)
7 | .catch(err => console.error(err));
8 |
--------------------------------------------------------------------------------
/templates/angular.webapp/src/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 | body {
10 | margin-top: 5%;
11 | padding-right: 5%;
12 | padding-left: 5%;
13 | font-size: larger;
14 | }
15 |
16 | @media screen and (min-width: 800px) {
17 | body {
18 | padding-right: 15%;
19 | padding-left: 15%;
20 | }
21 | }
22 |
23 | @media screen and (min-width: 1600px) {
24 | body {
25 | padding-right: 30%;
26 | padding-left: 30%;
27 | }
28 | }
--------------------------------------------------------------------------------
/templates/angular.webapp/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/app",
6 | "types": []
7 | },
8 | "files": [
9 | "src/main.ts"
10 | ],
11 | "include": [
12 | "src/**/*.d.ts"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/templates/angular.webapp/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitOverride": true,
10 | "noPropertyAccessFromIndexSignature": true,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "sourceMap": true,
14 | "declaration": false,
15 | "downlevelIteration": true,
16 | "experimentalDecorators": true,
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "ES2022",
20 | "module": "ES2022",
21 | "useDefineForClassFields": false,
22 | "lib": [
23 | "ES2022",
24 | "dom"
25 | ]
26 | },
27 | "angularCompilerOptions": {
28 | "enableI18nLegacyMessageIdFormat": false,
29 | "strictInjectionParameters": true,
30 | "strictInputAccessModifiers": true,
31 | "strictTemplates": true
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/templates/angular.webapp/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "include": [
11 | "src/**/*.spec.ts",
12 | "src/**/*.d.ts"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/templates/mongo.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16.20-alpine3.18 AS JS_BUILD
2 | COPY webapp /webapp
3 | WORKDIR /webapp
4 | RUN npm install && npm run build
5 |
6 | FROM golang:1.22.1-alpine3.18 AS GO_BUILD
7 | RUN apk update && apk add build-base
8 | COPY server /server
9 | WORKDIR /server
10 | RUN go build -o /go/bin/server
11 |
12 | FROM alpine:3.18.6
13 | COPY --from=JS_BUILD /webapp/build* ./webapp/
14 | COPY --from=GO_BUILD /go/bin/server ./
15 | CMD ./server
16 |
--------------------------------------------------------------------------------
/templates/mongo.README.md:
--------------------------------------------------------------------------------
1 | # project-name
2 |
3 | ## Environment setup
4 |
5 | You need to have [Go](https://go.dev/),
6 | [Node.js](https://nodejs.org/) and
7 | [Docker](https://www.docker.com/)
8 | installed on your computer.
9 |
10 | Verify the tools by running the following commands:
11 |
12 | ```sh
13 | go version
14 | npm --version
15 | docker --version
16 | ```
17 |
18 | If you are using Windows you will also need
19 | [gcc](https://gcc.gnu.org/). It comes installed
20 | on Mac and almost all Linux distributions.
21 |
22 | ## Start in development mode
23 |
24 | In the project directory run the command (you might
25 | need to prepend it with `sudo` depending on your setup):
26 | ```sh
27 | docker compose -f docker-compose-dev.yml up
28 | ```
29 |
30 | This starts a local MongoDB on `localhost:27017`.
31 | The database will be populated with test records
32 | from the [init-db.js](init-db.js) file.
33 |
34 | Navigate to the `server` folder and start the back end:
35 |
36 | ```sh
37 | cd server
38 | go run server.go
39 | ```
40 | The back end will serve on http://localhost:8080.
41 |
42 | Navigate to the `webapp` folder, install dependencies,
43 | and start the front end development server by running:
44 |
45 | ```sh
46 | cd webapp
47 | npm install
48 | npm start
49 | ```
50 | The application will be available on http://localhost:3000.
51 |
52 | ## Start in production mode
53 |
54 | Perform:
55 | ```sh
56 | docker compose up
57 | ```
58 | This will build the application and start it together with
59 | its database. Access the application on http://localhost:8080.
60 |
--------------------------------------------------------------------------------
/templates/mongo.docker-compose-dev.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | dev_db:
4 | image: mongo:6.0.3
5 | environment:
6 | MONGO_INITDB_DATABASE: tech
7 | ports:
8 | - 27017:27017
9 | volumes:
10 | - ./init-db.js:/docker-entrypoint-initdb.d/init.js
11 |
--------------------------------------------------------------------------------
/templates/mongo.docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | app:
4 | build: .
5 | container_name: app
6 | ports:
7 | - 8080:8080
8 | depends_on:
9 | - db
10 | environment:
11 | profile: prod
12 | db:
13 | image: mongo:6.0.3
14 | container_name: db
15 | environment:
16 | MONGO_INITDB_DATABASE: tech
17 | volumes:
18 | - ./init-db.js:/docker-entrypoint-initdb.d/init.js
19 |
--------------------------------------------------------------------------------
/templates/mongo.init-db.js:
--------------------------------------------------------------------------------
1 | db.tech.insert({
2 | "name": "Go",
3 | "details": "An open source programming language that makes it easy to build simple and efficient software."
4 | });
5 | db.tech.insert({
6 | "name": "JavaScript",
7 | "details": "A lightweight, interpreted, or just-in-time compiled programming language with first-class functions."
8 | });
9 | db.tech.insert({
10 | "name": "MongoDB",
11 | "details": "A general purpose, document-based, distributed database."
12 | });
13 |
--------------------------------------------------------------------------------
/templates/mongo.server/db/db.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import (
4 | "context"
5 | "go.mongodb.org/mongo-driver/bson"
6 | "go.mongodb.org/mongo-driver/mongo"
7 | "log"
8 | "project-name/model"
9 | )
10 |
11 | type DB interface {
12 | GetTechnologies() ([]*model.Technology, error)
13 | }
14 |
15 | type MongoDB struct {
16 | collection *mongo.Collection
17 | }
18 |
19 | func NewMongo(client *mongo.Client) DB {
20 | tech := client.Database("tech").Collection("tech")
21 | return MongoDB{collection: tech}
22 | }
23 |
24 | func (m MongoDB) GetTechnologies() ([]*model.Technology, error) {
25 | res, err := m.collection.Find(context.TODO(), bson.M{})
26 | if err != nil {
27 | log.Println("Error while fetching technologies:", err.Error())
28 | return nil, err
29 | }
30 | var tech []*model.Technology
31 | err = res.All(context.TODO(), &tech)
32 | if err != nil {
33 | log.Println("Error while decoding technologies:", err.Error())
34 | return nil, err
35 | }
36 | return tech, nil
37 | }
38 |
--------------------------------------------------------------------------------
/templates/mongo.server/go.mod:
--------------------------------------------------------------------------------
1 | module project-name
2 |
3 | go 1.22
4 |
5 | require go.mongodb.org/mongo-driver v1.12.0
6 |
7 | require (
8 | github.com/golang/snappy v0.0.1 // indirect
9 | github.com/klauspost/compress v1.13.6 // indirect
10 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
11 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect
12 | github.com/xdg-go/scram v1.1.2 // indirect
13 | github.com/xdg-go/stringprep v1.0.4 // indirect
14 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
15 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
16 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
17 | golang.org/x/text v0.7.0 // indirect
18 | )
19 |
20 |
--------------------------------------------------------------------------------
/templates/mongo.server/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
3 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
4 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5 | github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
6 | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
7 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
8 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
9 | github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
10 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
11 | github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
12 | github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
13 | github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
14 | github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
15 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
16 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
17 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
18 | go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE=
19 | go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0=
20 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
21 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
22 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
23 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
24 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
25 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
26 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
27 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
28 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
29 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
30 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
31 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
32 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
33 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
34 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
35 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
36 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
37 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
38 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
39 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
40 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
41 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
42 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
43 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
44 | golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
45 | golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
46 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
47 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
48 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
49 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
50 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
51 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
52 |
--------------------------------------------------------------------------------
/templates/mongo.server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "go.mongodb.org/mongo-driver/mongo"
6 | "go.mongodb.org/mongo-driver/mongo/options"
7 | "log"
8 | "os"
9 | "project-name/db"
10 | "project-name/web"
11 | )
12 |
13 | func main() {
14 | client, err := mongo.Connect(context.TODO(), clientOptions())
15 | if err != nil {
16 | log.Fatal(err)
17 | }
18 | defer client.Disconnect(context.TODO())
19 | mongoDB := db.NewMongo(client)
20 | // CORS is enabled only in prod profile
21 | cors := os.Getenv("profile") == "prod"
22 | app := web.NewApp(mongoDB, cors)
23 | err = app.Serve()
24 | log.Println("Error", err)
25 | }
26 |
27 | func clientOptions() *options.ClientOptions {
28 | host := "db"
29 | if os.Getenv("profile") != "prod" {
30 | host = "localhost"
31 | }
32 | return options.Client().ApplyURI(
33 | "mongodb://" + host + ":27017",
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/templates/mysql.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16.20-alpine3.18 AS JS_BUILD
2 | COPY webapp /webapp
3 | WORKDIR /webapp
4 | RUN npm install && npm run build
5 |
6 | FROM golang:1.22.1-alpine3.18 AS GO_BUILD
7 | COPY server /server
8 | WORKDIR /server
9 | RUN go build -o /go/bin/server
10 |
11 | FROM alpine:3.18.6
12 | COPY --from=JS_BUILD /webapp/build* ./webapp/
13 | COPY --from=GO_BUILD /go/bin/server ./
14 | CMD ./server
15 |
--------------------------------------------------------------------------------
/templates/mysql.README.md:
--------------------------------------------------------------------------------
1 | # project-name
2 |
3 | ## Environment setup
4 |
5 | You need to have [Go](https://go.dev/),
6 | [Node.js](https://nodejs.org/) and
7 | [Docker](https://www.docker.com/)
8 | installed on your computer.
9 |
10 | Verify the tools by running the following commands:
11 |
12 | ```sh
13 | go version
14 | npm --version
15 | docker --version
16 | ```
17 |
18 | ## Start in development mode
19 |
20 | In the project directory run the command (you might
21 | need to prepend it with `sudo` depending on your setup):
22 | ```sh
23 | docker compose -f docker-compose-dev.yml up
24 | ```
25 |
26 | This starts a local MySQL database on `localhost:3306`.
27 | The database will be populated with test records from
28 | the [init-db.sql](init-db.sql) file.
29 |
30 | Navigate to the `server` folder and start the back end:
31 |
32 | ```sh
33 | cd server
34 | go run server.go
35 | ```
36 | The back end will serve on http://localhost:8080.
37 |
38 | Navigate to the `webapp` folder, install dependencies,
39 | and start the front end development server by running:
40 |
41 | ```sh
42 | cd webapp
43 | npm install
44 | npm start
45 | ```
46 | The application will be available on http://localhost:3000.
47 |
48 | ## Start in production mode
49 |
50 | Perform:
51 | ```sh
52 | docker compose up
53 | ```
54 | This will build the application and start it together with
55 | its database. Access the application on http://localhost:8080.
56 |
--------------------------------------------------------------------------------
/templates/mysql.docker-compose-dev.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | dev_db:
4 | image: mysql:8.0.31
5 | environment:
6 | MYSQL_DATABASE: goxygen
7 | MYSQL_USER: goxygen
8 | MYSQL_PASSWORD: pass
9 | MYSQL_RANDOM_ROOT_PASSWORD: "yes"
10 | ports:
11 | - 3306:3306
12 | volumes:
13 | - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
14 |
--------------------------------------------------------------------------------
/templates/mysql.docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | app:
4 | build: .
5 | container_name: app
6 | ports:
7 | - 8080:8080
8 | depends_on:
9 | - db
10 | environment:
11 | profile: prod
12 | db_pass: pass
13 | db:
14 | image: mysql:8.0.31
15 | container_name: db
16 | environment:
17 | MYSQL_DATABASE: goxygen
18 | MYSQL_USER: goxygen
19 | MYSQL_PASSWORD: pass
20 | MYSQL_RANDOM_ROOT_PASSWORD: "yes"
21 | volumes:
22 | - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
--------------------------------------------------------------------------------
/templates/mysql.init-db.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE technologies (
2 | name VARCHAR(255),
3 | details VARCHAR(255)
4 | );
5 | insert into technologies values (
6 | 'Go', 'An open source programming language that makes it easy to build simple and efficient software.'
7 | );
8 | insert into technologies values (
9 | 'JavaScript', 'A lightweight, interpreted, or just-in-time compiled programming language with first-class functions.'
10 | );
11 | insert into technologies values (
12 | 'MySQL', 'A powerful, open source object-relational database'
13 | );
14 |
--------------------------------------------------------------------------------
/templates/mysql.server/db/db.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import (
4 | "database/sql"
5 | "project-name/model"
6 | )
7 |
8 | type DB interface {
9 | GetTechnologies() ([]*model.Technology, error)
10 | }
11 |
12 | type MySQLDB struct {
13 | db *sql.DB
14 | }
15 |
16 | func NewDB(db *sql.DB) DB {
17 | return MySQLDB{db: db}
18 | }
19 |
20 | func (d MySQLDB) GetTechnologies() ([]*model.Technology, error) {
21 | rows, err := d.db.Query("select name, details from technologies")
22 | if err != nil {
23 | return nil, err
24 | }
25 | defer rows.Close()
26 | var tech []*model.Technology
27 | for rows.Next() {
28 | t := new(model.Technology)
29 | err = rows.Scan(&t.Name, &t.Details)
30 | if err != nil {
31 | return nil, err
32 | }
33 | tech = append(tech, t)
34 | }
35 | return tech, nil
36 | }
37 |
--------------------------------------------------------------------------------
/templates/mysql.server/go.mod:
--------------------------------------------------------------------------------
1 | module project-name
2 |
3 | go 1.22
4 |
5 | require github.com/go-sql-driver/mysql v1.7.1
6 |
--------------------------------------------------------------------------------
/templates/mysql.server/go.sum:
--------------------------------------------------------------------------------
1 | github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
2 | github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
--------------------------------------------------------------------------------
/templates/mysql.server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 | _ "github.com/go-sql-driver/mysql"
6 | "log"
7 | "os"
8 | "project-name/db"
9 | "project-name/web"
10 | )
11 |
12 | func main() {
13 | d, err := sql.Open("mysql", dataSource())
14 | if err != nil {
15 | log.Fatal(err)
16 | }
17 | defer d.Close()
18 | // CORS is enabled only in prod profile
19 | cors := os.Getenv("profile") == "prod"
20 | app := web.NewApp(db.NewDB(d), cors)
21 | err = app.Serve()
22 | log.Println("Error", err)
23 | }
24 |
25 | func dataSource() string {
26 | host := "localhost"
27 | pass := "pass"
28 | if os.Getenv("profile") == "prod" {
29 | host = "db"
30 | pass = os.Getenv("db_pass")
31 | }
32 | return "goxygen:" + pass + "@tcp(" + host + ":3306)/goxygen"
33 | }
34 |
--------------------------------------------------------------------------------
/templates/postgres.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16.20-alpine3.18 AS JS_BUILD
2 | COPY webapp /webapp
3 | WORKDIR /webapp
4 | RUN npm install && npm run build
5 |
6 | FROM golang:1.22.1-alpine3.18 AS GO_BUILD
7 | COPY server /server
8 | WORKDIR /server
9 | RUN go build -o /go/bin/server
10 |
11 | FROM alpine:3.18.6
12 | COPY --from=JS_BUILD /webapp/build* ./webapp/
13 | COPY --from=GO_BUILD /go/bin/server ./
14 | CMD ./server
15 |
--------------------------------------------------------------------------------
/templates/postgres.README.md:
--------------------------------------------------------------------------------
1 | # project-name
2 |
3 | ## Environment setup
4 |
5 | You need to have [Go](https://go.dev/),
6 | [Node.js](https://nodejs.org/) and
7 | [Docker](https://www.docker.com/)
8 | installed on your computer.
9 |
10 | Verify the tools by running the following commands:
11 |
12 | ```sh
13 | go version
14 | npm --version
15 | docker --version
16 | ```
17 |
18 | ## Start in development mode
19 |
20 | In the project directory run the command (you might
21 | need to prepend it with `sudo` depending on your setup):
22 | ```sh
23 | docker compose -f docker-compose-dev.yml up
24 | ```
25 |
26 | This starts a local PostgreSQL database on `localhost:5432`.
27 | The database will be populated with test records from the
28 | [init-db.sql](init-db.sql) file.
29 |
30 | Navigate to the `server` folder and start the back end:
31 |
32 | ```sh
33 | cd server
34 | go run server.go
35 | ```
36 | The back end will serve on http://localhost:8080.
37 |
38 | Navigate to the `webapp` folder, install dependencies,
39 | and start the front end development server by running:
40 |
41 | ```sh
42 | cd webapp
43 | npm install
44 | npm start
45 | ```
46 | The application will be available on http://localhost:3000.
47 |
48 | ## Start in production mode
49 |
50 | Perform:
51 | ```sh
52 | docker compose up
53 | ```
54 | This will build the application and start it together with
55 | its database. Access the application on http://localhost:8080.
56 |
--------------------------------------------------------------------------------
/templates/postgres.docker-compose-dev.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | dev_db:
4 | image: postgres:15.4-alpine3.18
5 | environment:
6 | POSTGRES_PASSWORD: pass
7 | POSTGRES_USER: goxygen
8 | POSTGRES_DB: goxygen
9 | ports:
10 | - 5432:5432
11 | volumes:
12 | - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
13 |
--------------------------------------------------------------------------------
/templates/postgres.docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | app:
4 | build: .
5 | container_name: app
6 | ports:
7 | - 8080:8080
8 | depends_on:
9 | - db
10 | environment:
11 | profile: prod
12 | db_pass: pass
13 | db:
14 | image: postgres:15.4-alpine3.18
15 | environment:
16 | POSTGRES_PASSWORD: pass
17 | POSTGRES_USER: goxygen
18 | POSTGRES_DB: goxygen
19 | volumes:
20 | - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
--------------------------------------------------------------------------------
/templates/postgres.init-db.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE technologies (
2 | name VARCHAR(255),
3 | details VARCHAR(255)
4 | );
5 | insert into technologies values (
6 | 'Go', 'An open source programming language that makes it easy to build simple and efficient software.'
7 | );
8 | insert into technologies values (
9 | 'JavaScript', 'A lightweight, interpreted, or just-in-time compiled programming language with first-class functions.'
10 | );
11 | insert into technologies values (
12 | 'PostgreSQL', 'A powerful, open source object-relational database system'
13 | );
14 |
--------------------------------------------------------------------------------
/templates/postgres.server/db/db.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import (
4 | "project-name/model"
5 | "database/sql"
6 | )
7 |
8 | type DB interface {
9 | GetTechnologies() ([]*model.Technology, error)
10 | }
11 |
12 | type PostgresDB struct {
13 | db *sql.DB
14 | }
15 |
16 | func NewDB(db *sql.DB) DB {
17 | return PostgresDB{db: db}
18 | }
19 |
20 | func (d PostgresDB) GetTechnologies() ([]*model.Technology, error) {
21 | rows, err := d.db.Query("select name, details from technologies")
22 | if err != nil {
23 | return nil, err
24 | }
25 | defer rows.Close()
26 | var tech []*model.Technology
27 | for rows.Next() {
28 | t := new(model.Technology)
29 | err = rows.Scan(&t.Name, &t.Details)
30 | if err != nil {
31 | return nil, err
32 | }
33 | tech = append(tech, t)
34 | }
35 | return tech, nil
36 | }
37 |
--------------------------------------------------------------------------------
/templates/postgres.server/go.mod:
--------------------------------------------------------------------------------
1 | module project-name
2 |
3 | go 1.22
4 |
5 | require github.com/lib/pq v1.10.9
6 |
--------------------------------------------------------------------------------
/templates/postgres.server/go.sum:
--------------------------------------------------------------------------------
1 | github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
2 | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
--------------------------------------------------------------------------------
/templates/postgres.server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "project-name/db"
5 | "project-name/web"
6 | "database/sql"
7 | _ "github.com/lib/pq"
8 | "log"
9 | "os"
10 | )
11 |
12 | func main() {
13 | d, err := sql.Open("postgres", dataSource())
14 | if err != nil {
15 | log.Fatal(err)
16 | }
17 | defer d.Close()
18 | // CORS is enabled only in prod profile
19 | cors := os.Getenv("profile") == "prod"
20 | app := web.NewApp(db.NewDB(d), cors)
21 | err = app.Serve()
22 | log.Println("Error", err)
23 | }
24 |
25 | func dataSource() string {
26 | host := "localhost"
27 | pass := "pass"
28 | if os.Getenv("profile") == "prod" {
29 | host = "db"
30 | pass = os.Getenv("db_pass")
31 | }
32 | return "postgresql://" + host + ":5432/goxygen" +
33 | "?user=goxygen&sslmode=disable&password=" + pass
34 | }
35 |
--------------------------------------------------------------------------------
/templates/react.webapp/.env.development:
--------------------------------------------------------------------------------
1 | REACT_APP_API_URL=http://localhost:8080
--------------------------------------------------------------------------------
/templates/react.webapp/.env.production:
--------------------------------------------------------------------------------
1 | REACT_APP_API_URL=
--------------------------------------------------------------------------------
/templates/react.webapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "project-name",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "axios": "~1.2.1",
7 | "react": "~18.2.0",
8 | "react-dom": "~18.2.0",
9 | "react-scripts": "~5.0.1"
10 | },
11 | "devDependencies": {
12 | "@testing-library/jest-dom": "~5.16.5",
13 | "@testing-library/react": "~13.4.0",
14 | "@testing-library/user-event": "~14.4.3"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "react-scripts test",
20 | "eject": "react-scripts eject"
21 | },
22 | "eslintConfig": {
23 | "extends": "react-app"
24 | },
25 | "browserslist": {
26 | "production": [
27 | ">0.2%",
28 | "not dead",
29 | "not op_mini all"
30 | ],
31 | "development": [
32 | "last 1 chrome version",
33 | "last 1 firefox version",
34 | "last 1 safari version"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/templates/react.webapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/templates/react.webapp/public/favicon.ico
--------------------------------------------------------------------------------
/templates/react.webapp/public/index.html:
--------------------------------------------------------------------------------
1 | <!DOCTYPE html>
2 | <html lang="en">
3 | <head>
4 | <meta charset="utf-8" />
5 | <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6 | <meta name="viewport" content="width=device-width, initial-scale=1" />
7 | <meta name="theme-color" content="#000000" />
8 | <meta
9 | name="description"
10 | content="Web site created using goxygen"
11 | />
12 | <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
13 | <!--
14 | manifest.json provides metadata used when your web app is installed on a
15 | user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
16 | -->
17 | <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
18 | <!--
19 | Notice the use of %PUBLIC_URL% in the tags above.
20 | It will be replaced with the URL of the `public` folder during the build.
21 | Only files inside the `public` folder can be referenced from the HTML.
22 |
23 | Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
24 | work correctly both with client-side routing and a non-root public URL.
25 | Learn how to configure a non-root public URL by running `npm run build`.
26 | -->
27 | <title>project-name</title>
28 | </head>
29 | <body>
30 | <noscript>You need to enable JavaScript to run this app.</noscript>
31 | <div id="root"></div>
32 | <!--
33 | This HTML file is a template.
34 | If you open it directly in the browser, you will see an empty page.
35 |
36 | You can add webfonts, meta tags, or analytics to this file.
37 | The build step will place the bundled scripts into the <body> tag.
38 |
39 | To begin the development, run `npm start`.
40 | To create a production bundle, use `npm run build`.
41 | -->
42 | </body>
43 | </html>
44 |
--------------------------------------------------------------------------------
/templates/react.webapp/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/templates/react.webapp/public/logo192.png
--------------------------------------------------------------------------------
/templates/react.webapp/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/templates/react.webapp/public/logo512.png
--------------------------------------------------------------------------------
/templates/react.webapp/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "project-name",
3 | "name": "project-name",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/templates/react.webapp/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/templates/react.webapp/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin-top: 5%;
3 | padding-right: 5%;
4 | padding-left: 5%;
5 | font-size: larger;
6 | }
7 |
8 | @media screen and (min-width: 800px) {
9 | body {
10 | padding-right: 15%;
11 | padding-left: 15%;
12 | }
13 | }
14 |
15 | @media screen and (min-width: 1600px) {
16 | body {
17 | padding-right: 30%;
18 | padding-left: 30%;
19 | }
20 | }
21 |
22 | code {
23 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
24 | monospace;
25 | background-color: #b3e6ff;
26 | }
27 |
28 | .title {
29 | text-align: center;
30 | }
31 |
32 | .logo {
33 | text-align: center;
34 | }
35 |
--------------------------------------------------------------------------------
/templates/react.webapp/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './App.css';
3 | import Logo from './Logo';
4 | import {Tech} from "./tech/Tech";
5 |
6 | export function App() {
7 | return (
8 | <div className="app">
9 | <h2 className="title">project-name</h2>
10 | <div className="logo"><Logo/></div>
11 | <div>
12 | This project is generated with <b><a
13 | href="https://github.com/shpota/goxygen">goxygen</a></b>.
14 | <p/>The following list of technologies comes from
15 | a REST API call to the Go-based back end. Find
16 | and change the corresponding code
17 | in <code>webapp/src/tech/Tech.js
18 | </code> and <code>server/web/app.go</code>.
19 | <Tech/>
20 | </div>
21 | </div>
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/templates/react.webapp/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {render} from '@testing-library/react';
3 | import {App} from './App';
4 |
5 | test('renders learn react link', () => {
6 | const {getByText} = render(<App/>);
7 | const linkElement = getByText(/goxygen/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/templates/react.webapp/src/Logo.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Logo = () => {
4 | return (
5 | <svg
6 | xmlns="http://www.w3.org/2000/svg"
7 | xmlnsXlink="http://www.w3.org/1999/xlink"
8 | height="150px"
9 | version="1.1"
10 | viewBox="0 0 464.745 338.814"
11 | >
12 | <defs>
13 | <linearGradient id="linearGradient4289">
14 | <stop offset="0" stopColor="#00dce2" stopOpacity="1"></stop>
15 | <stop offset="1" stopColor="#97f0ff" stopOpacity="1"></stop>
16 | </linearGradient>
17 | <linearGradient
18 | id="linearGradient4295"
19 | x1="431.334"
20 | x2="400.666"
21 | y1="531.393"
22 | y2="386.128"
23 | gradientTransform="translate(129.453 193.74)"
24 | gradientUnits="userSpaceOnUse"
25 | xlinkHref="#linearGradient4289"
26 | ></linearGradient>
27 | </defs>
28 | <g display="inline" transform="translate(-111.737 -176.023)">
29 | <path
30 | fill="url(#linearGradient4295)"
31 | fillOpacity="1"
32 | fillRule="evenodd"
33 | stroke="none"
34 | strokeLinecap="butt"
35 | strokeLinejoin="miter"
36 | strokeOpacity="1"
37 | strokeWidth="1"
38 | d="M132.042 433.463c23.84-32.316 103.542-15.624 130.056.606 89.595 44.02 169.113-19.05 186.402-33.707 42.52-37.92 60.763-37.33 75.655-30.124 4.45 2.154 10.795 11.465 14.408 12.5 98.104 111.17-186.007 131.629-317.798 102.342-60.452-13.433-102.376-33.11-88.723-51.617z"
39 | ></path>
40 | </g>
41 | <g display="none" transform="translate(-111.737 -176.023)">
42 | <path
43 | fill="#f3df49"
44 | fillOpacity="1"
45 | fillRule="evenodd"
46 | stroke="none"
47 | strokeLinecap="butt"
48 | strokeLinejoin="miter"
49 | strokeOpacity="1"
50 | strokeWidth="1"
51 | d="M132.042 433.463c23.84-32.316 103.542-15.624 130.056.606 89.595 44.02 169.113-19.05 186.402-33.707 42.52-37.92 60.763-37.33 75.655-30.124 4.45 2.154 10.795 11.465 14.408 12.5 98.104 111.17-186.007 131.629-317.798 102.342-60.452-13.433-102.376-33.11-88.723-51.617z"
52 | ></path>
53 | </g>
54 | <g transform="translate(17.717 17.717)">
55 | <path
56 | fill="#2e2e2c"
57 | fillOpacity="1"
58 | d="M397.824 203.03c-2.159.004-4.045.321-5.6.972-1.554.651-2.778 1.63-3.645 2.857-.866 1.227-1.375 2.699-1.529 4.306-.153 1.607.049 3.349.582 5.126.579 1.93 1.307 3.55 2.192 4.91a13.088 13.088 0 003.107 3.348c1.182.895 2.503 1.59 3.932 2.165 1.428.575 2.962 1.03 4.566 1.444l.553.146.548.15.544.152.54.155c.982.297 1.843.588 2.584.913.74.325 1.364.677 1.87 1.086.506.41.895.875 1.153 1.453.258.577.386 1.265.358 2.152a5.951 5.951 0 01-.47 2.131 6.491 6.491 0 01-1.208 1.864 7.522 7.522 0 01-1.858 1.459 8.952 8.952 0 01-2.42.918c-1.06.24-2.007.293-2.854.183a5.78 5.78 0 01-2.27-.79c-.672-.405-1.267-.943-1.811-1.577-.545-.634-1.037-1.364-1.507-2.154l-1.985 1.807-2.038 1.863-2.09 1.915-2.142 1.96c.653 1.394 1.473 2.66 2.469 3.74a11.564 11.564 0 003.52 2.618c1.353.647 2.886 1.049 4.598 1.16 1.712.11 3.601-.072 5.668-.572 2.113-.512 4.089-1.296 5.865-2.332 1.777-1.035 3.355-2.321 4.663-3.833a16.57 16.57 0 003.055-5.187 17.519 17.519 0 001.046-6.319c-.046-2.03-.392-3.575-.957-4.93-.565-1.354-1.35-2.504-2.325-3.564-.976-1.06-2.123-1.878-3.477-2.66a23.428 23.428 0 00-4.756-2.066l-.546-.168-.554-.16-.56-.157-.57-.14a34.934 34.934 0 01-2.614-.735c-.76-.255-1.408-.529-1.952-.849-.544-.32-.983-.686-1.331-1.128-.348-.441-.605-.957-.792-1.578a3.249 3.249 0 01-.124-1.428c.067-.442.244-.843.525-1.183.281-.34.667-.617 1.15-.817.484-.2 1.065-.32 1.733-.354a8.835 8.835 0 011.843.09 7.096 7.096 0 011.677.485 7.75 7.75 0 011.552.897c.503.37 1 .815 1.513 1.346l1.164-1.306 1.08-1.395 1.126-1.449 1.302-1.465c-.991-1.037-1.863-1.841-2.77-2.497-.906-.656-1.868-1.17-3.04-1.614a20.581 20.581 0 00-3.912-1.033c-1.382-.225-2.43-.278-4.371-.33 0 0 1.894-.003 0 0zm-35.9 4.18l2.956 8.923 2.485 8.916 1.614 9.051.648 9.272a9.355 9.355 0 01-.439 3.521c-.309.977-.768 1.768-1.352 2.408-.584.64-1.294 1.13-2.115 1.507-.82.376-1.752.64-2.78.827-1.073.196-1.992.196-2.801.044a5.873 5.873 0 01-2.145-.869c-.636-.412-1.207-.934-1.756-1.523-.549-.59-1.077-1.246-1.625-1.93l-2.483 1.763-2.427 1.737-2.357 1.71-2.276 1.68c-1.22.901 1.792 2.467 2.93 3.515a15.408 15.408 0 003.934 2.65c1.492.697 3.171 1.185 5.068 1.395 1.897.21 4.013.141 6.381-.281 2.622-.468 5.04-1.253 7.208-2.352 2.168-1.098 4.086-2.511 5.705-4.232a19.5 19.5 0 003.883-6.069c.94-2.32 1.683-4.968 1.511-7.8l-.473-9.292-1.59-8.98-2.622-8.769-3.26-8.728-2.891.48-2.94.48-2.98.476z"
59 | display="inline"
60 | ></path>
61 | </g>
62 | <g
63 | strokeDasharray="none"
64 | strokeLinejoin="round"
65 | strokeMiterlimit="4"
66 | strokeOpacity="1"
67 | strokeWidth="2"
68 | transform="translate(-111.737 -176.023)"
69 | >
70 | <path
71 | fill="#388e3c"
72 | fillOpacity="1"
73 | fillRule="evenodd"
74 | stroke="#000"
75 | strokeLinecap="butt"
76 | d="M198.79 380.429c.258-2.631 4.098-13.37 31.374-.952 87.587 39.873 172.374 28.761 238.086 1.513-35.446 31.74-105.09 70.96-151.5 82.622-33.173-.25-69.22-8.332-91.922-33.79-10.377-11.637-27.083-38.739-26.038-49.393z"
77 | display="inline"
78 | ></path>
79 | <ellipse
80 | cx="280.876"
81 | cy="474.384"
82 | fill="#1b5e2f"
83 | fillOpacity="0.941"
84 | stroke="none"
85 | strokeDashoffset="0"
86 | strokeLinecap="round"
87 | opacity="1"
88 | rx="83.288"
89 | ry="22.62"
90 | transform="matrix(.9852 -.1714 .13103 .99138 0 0)"
91 | ></ellipse>
92 | </g>
93 | <g
94 | stroke="#000"
95 | strokeOpacity="1"
96 | transform="translate(-111.737 -176.023)"
97 | >
98 | <path
99 | fill="#8ed4fe"
100 | fillOpacity="1"
101 | fillRule="evenodd"
102 | strokeDasharray="none"
103 | strokeLinecap="round"
104 | strokeLinejoin="miter"
105 | strokeMiterlimit="4"
106 | strokeWidth="2.367"
107 | d="M369.51 223.971c8.7-7.655 16.286-10.658 23.079-7.257 4.975 2.49 3.88 9.206.186 14.35-4.404 6.131-8.49 9.32-8.744 9.31"
108 | display="inline"
109 | opacity="1"
110 | ></path>
111 | <path
112 | fill="#000"
113 | fillOpacity="1"
114 | fillRule="evenodd"
115 | strokeLinecap="butt"
116 | strokeLinejoin="miter"
117 | strokeWidth="0.395"
118 | d="M377.176 235.834c.04.824 4.25 3.422 5.457 3.096 1.767-.477 8.642-9.057 8.6-10.83-.114-4.972-14.082 7.2-14.057 7.734z"
119 | display="inline"
120 | opacity="1"
121 | ></path>
122 | <path
123 | fill="#8ed4fd"
124 | fillOpacity="1"
125 | strokeDasharray="none"
126 | strokeDashoffset="0"
127 | strokeLinecap="round"
128 | strokeLinejoin="bevel"
129 | strokeMiterlimit="4"
130 | strokeWidth="2"
131 | d="M388.092 315.25c1.496-1.405 4.867-1.942 7.212-3.04 4.645-2.175 7.611-5.532 6.625-7.496-.985-1.965-5.55-1.794-10.195.382-2.244 1.052-4.386 1.93-6.409 2.138"
132 | display="inline"
133 | opacity="1"
134 | ></path>
135 | <path
136 | fill="#8ed4fd"
137 | fillOpacity="1"
138 | fillRule="evenodd"
139 | strokeDasharray="none"
140 | strokeLinecap="butt"
141 | strokeLinejoin="miter"
142 | strokeMiterlimit="4"
143 | strokeWidth="4"
144 | d="M298.548 433.973c-13.22-2.143-19.679-12.58-26.607-23.445-39.8-62.416-31.281-150.252-11.383-173.744 28.95-34.182 95.759-33.51 125.692 5.328 23.506 26.833-1.187 59.973-.604 88.64 42.218 17.603 36.354 74.36 36.354 74.36s-29.164-3.515-46.414.485c-13.469 3.124-29.732 10.114-48.81 19.564-9.17 4.542-16.54 10.707-28.228 8.812z"
145 | ></path>
146 | <path
147 | fill="#8ed4fd"
148 | fillOpacity="1"
149 | strokeDasharray="none"
150 | strokeDashoffset="0"
151 | strokeLinecap="round"
152 | strokeLinejoin="bevel"
153 | strokeMiterlimit="4"
154 | strokeWidth="4"
155 | d="M250.55 329.788c-2.015 1.902-6.565 2.64-9.73 4.129-6.264 2.955-10.258 7.499-8.92 10.148 1.339 2.65 7.503 2.403 13.769-.553 3.025-1.428 5.915-2.621 8.646-2.91"
156 | display="inline"
157 | opacity="1"
158 | ></path>
159 | <path
160 | fill="none"
161 | fillRule="evenodd"
162 | strokeLinecap="butt"
163 | strokeLinejoin="miter"
164 | strokeWidth="1"
165 | d="M391.384 334.295c-9.823-5.145-22.274-2.475-22.274-2.475"
166 | ></path>
167 | <path
168 | fill="#8ed4fd"
169 | fillOpacity="1"
170 | strokeDasharray="none"
171 | strokeDashoffset="0"
172 | strokeLinecap="round"
173 | strokeLinejoin="bevel"
174 | strokeMiterlimit="4"
175 | strokeWidth="4"
176 | d="M286.83 422.587c6.996 10.92 1.841 23.67 8.24 25.193 5.237 1.246 10.83-11.015 16.597-20.235"
177 | display="inline"
178 | opacity="1"
179 | ></path>
180 | <circle
181 | cx="312.057"
182 | cy="259.305"
183 | r="33.415"
184 | fill="#fff"
185 | fillOpacity="1"
186 | strokeDasharray="none"
187 | strokeDashoffset="0"
188 | strokeLinecap="round"
189 | strokeLinejoin="round"
190 | strokeMiterlimit="4"
191 | strokeWidth="3"
192 | opacity="1"
193 | ></circle>
194 | <ellipse
195 | cx="383.257"
196 | cy="275.775"
197 | fill="#fff"
198 | fillOpacity="1"
199 | strokeDasharray="none"
200 | strokeDashoffset="0"
201 | strokeLinecap="round"
202 | strokeLinejoin="round"
203 | strokeMiterlimit="4"
204 | strokeWidth="2.806"
205 | opacity="1"
206 | rx="23.077"
207 | ry="24.17"
208 | ></ellipse>
209 | <g
210 | fillOpacity="1"
211 | strokeDasharray="none"
212 | strokeMiterlimit="4"
213 | transform="translate(4.328 .457)"
214 | >
215 | <path
216 | fill="#fff"
217 | fillRule="evenodd"
218 | strokeLinecap="butt"
219 | strokeLinejoin="miter"
220 | strokeWidth="2.564"
221 | d="M335.728 298.82c-1.108 3.632-.698 12.213-.698 12.213l10.475 3.152s4.853-5.714 5.444-7.781c.592-2.068.338-3.207.338-3.207z"
222 | display="inline"
223 | opacity="1"
224 | ></path>
225 | <path
226 | fill="#d3b78d"
227 | fillRule="evenodd"
228 | strokeLinecap="butt"
229 | strokeLinejoin="miter"
230 | strokeWidth="2.564"
231 | d="M327.716 292.849c-7.616 7.896 4.591 8.084 14.163 10.196 7.577 1.67 16.83 10.159 19.098 2.508 3.92-13.223-23.494-22.831-33.261-12.704z"
232 | display="inline"
233 | opacity="1"
234 | ></path>
235 | <ellipse
236 | cx="420.17"
237 | cy="-167.764"
238 | fill="#000"
239 | strokeDashoffset="0"
240 | strokeLinecap="round"
241 | strokeLinejoin="bevel"
242 | strokeWidth="1.923"
243 | display="inline"
244 | opacity="1"
245 | rx="11.351"
246 | ry="6.498"
247 | transform="scale(1 -1) rotate(-18.249)"
248 | ></ellipse>
249 | </g>
250 | <circle
251 | cx="324.338"
252 | cy="267.016"
253 | r="8.853"
254 | fill="#000"
255 | fillOpacity="1"
256 | strokeDasharray="none"
257 | strokeDashoffset="0"
258 | strokeLinecap="round"
259 | strokeLinejoin="round"
260 | strokeMiterlimit="4"
261 | strokeWidth="2.285"
262 | opacity="1"
263 | ></circle>
264 | <circle
265 | cx="392.334"
266 | cy="283.759"
267 | r="6.781"
268 | fill="#000"
269 | fillOpacity="1"
270 | strokeDasharray="none"
271 | strokeDashoffset="0"
272 | strokeLinecap="round"
273 | strokeLinejoin="round"
274 | strokeMiterlimit="4"
275 | strokeWidth="1.75"
276 | opacity="1"
277 | ></circle>
278 | <path
279 | fill="#8ed4fe"
280 | fillOpacity="1"
281 | fillRule="evenodd"
282 | strokeDasharray="none"
283 | strokeLinecap="round"
284 | strokeLinejoin="miter"
285 | strokeMiterlimit="4"
286 | strokeWidth="2.913"
287 | d="M278.198 228.795c-3.902-10.61-2.26-20.229 2.508-28.163 3.346-5.568 7.803-6.188 11.596-4.822 6.332 2.281 9.116 9.465 12.68 20.664"
288 | display="inline"
289 | opacity="1"
290 | ></path>
291 | <path
292 | fill="#000"
293 | fillOpacity="1"
294 | fillRule="evenodd"
295 | strokeLinecap="butt"
296 | strokeLinejoin="miter"
297 | strokeWidth="0.486"
298 | d="M288.665 223.718c.788.64 5.95-1.759 7.315-2.47 2.72-1.417.131-13.619-2.11-15.238-4.96-3.583-5.716 17.294-5.205 17.708z"
299 | display="inline"
300 | opacity="1"
301 | ></path>
302 | </g>
303 | <g display="inline" transform="translate(-111.737 -176.023)">
304 | <path
305 | fill="#4caf50"
306 | fillOpacity="1"
307 | fillRule="evenodd"
308 | stroke="#000"
309 | strokeDasharray="none"
310 | strokeLinecap="butt"
311 | strokeLinejoin="round"
312 | strokeMiterlimit="4"
313 | strokeOpacity="1"
314 | strokeWidth="2"
315 | d="M199.505 378.716c-3.003 5.856-4.34 9.43-3.462 28.282 21.667 47.77 122.45 97.485 235.386 8.578 16.785-13.214 43.013-41.156 70.714-46.428 20.44-3.89 35.552 12.637 35.552 12.637l-9.17-19.116c-10.613-21.217-55.799-16.392-82.11 2.943-35.088 25.784-70.3 86.105-142.844 83.536-79.713-2.823-108.82-63.392-104.066-70.432z"
316 | ></path>
317 | </g>
318 | </svg>
319 | );
320 | };
321 |
322 | export default Logo;
--------------------------------------------------------------------------------
/templates/react.webapp/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
--------------------------------------------------------------------------------
/templates/react.webapp/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import {App} from './App';
5 |
6 | ReactDOM.render(<App/>, document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/templates/react.webapp/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
--------------------------------------------------------------------------------
/templates/react.webapp/src/tech/Tech.css:
--------------------------------------------------------------------------------
1 | .technologies {
2 | margin-top: 5px;
3 | }
4 |
--------------------------------------------------------------------------------
/templates/react.webapp/src/tech/Tech.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import axios from "axios";
3 | import "./Tech.css"
4 |
5 | export class Tech extends Component {
6 | state = {
7 | technologies: []
8 | };
9 |
10 | componentDidMount() {
11 | axios.get(`${process.env.REACT_APP_API_URL}/api/technologies`)
12 | .then(resp => this.setState({
13 | technologies: resp.data
14 | }));
15 | }
16 |
17 | render() {
18 | const technologies = this.state.technologies.map((technology, i) =>
19 | <li key={i}>
20 | <b>{technology.name}</b>: {technology.details}
21 | </li>
22 | );
23 | return (
24 | <ul className="technologies">
25 | {technologies}
26 | </ul>
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/templates/server/model/technology.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type Technology struct {
4 | Name string `json:"name"`
5 | Details string `json:"details"`
6 | }
7 |
--------------------------------------------------------------------------------
/templates/server/web/app.go:
--------------------------------------------------------------------------------
1 | package web
2 |
3 | import (
4 | "encoding/json"
5 | "log"
6 | "net/http"
7 | "project-name/db"
8 | )
9 |
10 | type App struct {
11 | d db.DB
12 | handlers map[string]http.HandlerFunc
13 | }
14 |
15 | func NewApp(d db.DB, cors bool) App {
16 | app := App{
17 | d: d,
18 | handlers: make(map[string]http.HandlerFunc),
19 | }
20 | techHandler := app.GetTechnologies
21 | if !cors {
22 | techHandler = disableCors(techHandler)
23 | }
24 | app.handlers["/api/technologies"] = techHandler
25 | app.handlers["/"] = http.FileServer(http.Dir("/webapp")).ServeHTTP
26 | return app
27 | }
28 |
29 | func (a *App) Serve() error {
30 | for path, handler := range a.handlers {
31 | http.Handle(path, handler)
32 | }
33 | log.Println("Web server is available on port 8080")
34 | return http.ListenAndServe(":8080", nil)
35 | }
36 |
37 | func (a *App) GetTechnologies(w http.ResponseWriter, r *http.Request) {
38 | w.Header().Set("Content-Type", "application/json")
39 | technologies, err := a.d.GetTechnologies()
40 | if err != nil {
41 | sendErr(w, http.StatusInternalServerError, err.Error())
42 | return
43 | }
44 | err = json.NewEncoder(w).Encode(technologies)
45 | if err != nil {
46 | sendErr(w, http.StatusInternalServerError, err.Error())
47 | }
48 | }
49 |
50 | func sendErr(w http.ResponseWriter, code int, message string) {
51 | resp, _ := json.Marshal(map[string]string{"error": message})
52 | http.Error(w, string(resp), code)
53 | }
54 |
55 | // Needed in order to disable CORS for local development
56 | func disableCors(h http.HandlerFunc) http.HandlerFunc {
57 | return func(w http.ResponseWriter, r *http.Request) {
58 | w.Header().Set("Access-Control-Allow-Origin", "*")
59 | w.Header().Set("Access-Control-Allow-Methods", "*")
60 | w.Header().Set("Access-Control-Allow-Headers", "*")
61 | h(w, r)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/templates/server/web/app_test.go:
--------------------------------------------------------------------------------
1 | package web
2 |
3 | import (
4 | "errors"
5 | "net/http"
6 | "net/http/httptest"
7 | "project-name/model"
8 | "testing"
9 | )
10 |
11 | type MockDb struct {
12 | tech []*model.Technology
13 | err error
14 | }
15 |
16 | func (m *MockDb) GetTechnologies() ([]*model.Technology, error) {
17 | return m.tech, m.err
18 | }
19 |
20 | func TestApp_GetTechnologies(t *testing.T) {
21 | app := App{d: &MockDb{
22 | tech: []*model.Technology{
23 | {"Tech1", "Details1"},
24 | {"Tech2", "Details2"},
25 | },
26 | }}
27 |
28 | r, _ := http.NewRequest("GET", "/api/technologies", nil)
29 | w := httptest.NewRecorder()
30 |
31 | app.GetTechnologies(w, r)
32 |
33 | if w.Code != http.StatusOK {
34 | t.Errorf("handler returned wrong status code: got %v want %v", w.Code, http.StatusOK)
35 | }
36 |
37 | want := `[{"name":"Tech1","details":"Details1"},{"name":"Tech2","details":"Details2"}]` + "\n"
38 | if got := w.Body.String(); got != want {
39 | t.Errorf("handler returned unexpected body: got %v want %v", got, want)
40 | }
41 | }
42 |
43 | func TestApp_GetTechnologies_WithDBError(t *testing.T) {
44 | app := App{d: &MockDb{
45 | tech: nil,
46 | err: errors.New("unknown error"),
47 | }}
48 |
49 | r, _ := http.NewRequest("GET", "/api/technologies", nil)
50 | w := httptest.NewRecorder()
51 |
52 | app.GetTechnologies(w, r)
53 |
54 | if w.Code != http.StatusInternalServerError {
55 | t.Errorf("handler returned wrong status code: got %v want %v", w.Code, http.StatusOK)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/templates/vue.webapp/.env.local:
--------------------------------------------------------------------------------
1 | NODE_ENV=local
2 | VITE_API_URL=http://localhost:8080
--------------------------------------------------------------------------------
/templates/vue.webapp/.env.production:
--------------------------------------------------------------------------------
1 | VITE_API_URL=
--------------------------------------------------------------------------------
/templates/vue.webapp/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | module.exports = {
3 | root: true,
4 | 'extends': [
5 | 'plugin:vue/vue3-essential',
6 | 'eslint:recommended'
7 | ],
8 | parserOptions: {
9 | ecmaVersion: 'latest'
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/templates/vue.webapp/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
3 | }
4 |
--------------------------------------------------------------------------------
/templates/vue.webapp/index.html:
--------------------------------------------------------------------------------
1 | <!DOCTYPE html>
2 | <html lang="en">
3 | <head>
4 | <meta charset="UTF-8">
5 | <link rel="icon" href="/favicon.ico">
6 | <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 | <title>project-name</title>
8 | </head>
9 | <body>
10 | <div id="app"></div>
11 | <script type="module" src="/src/main.js"></script>
12 | </body>
13 | </html>
14 |
--------------------------------------------------------------------------------
/templates/vue.webapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "project-name",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "vite --port 3000",
7 | "build": "vite build",
8 | "preview": "vite preview",
9 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
10 | },
11 | "dependencies": {
12 | "axios": "^1.4.0",
13 | "vue": "^3.3.2"
14 | },
15 | "devDependencies": {
16 | "@vitejs/plugin-vue": "^4.2.3",
17 | "eslint": "^8.39.0",
18 | "eslint-plugin-vue": "^9.11.0",
19 | "vite": "^4.3.5"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/templates/vue.webapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpota/goxygen/47ce691cfac7ecde991afb8c1eabe9a9206c3434/templates/vue.webapp/public/favicon.ico
--------------------------------------------------------------------------------
/templates/vue.webapp/src/App.vue:
--------------------------------------------------------------------------------
1 | <script setup>
2 | import TechItems from './components/TechItems.vue'
3 | import logoSVG from '@/assets/logo.svg';
4 | </script>
5 |
6 | <template>
7 | <main id="app">
8 | <h2 class="title">project-name</h2>
9 | <div class="logo">
10 | <img :src="logoSVG" height="150" alt="logo" />
11 | </div>
12 | <div>
13 | This project is generated with
14 | <b>
15 | <a href="https://github.com/shpota/goxygen">goxygen</a>
16 | </b>.
17 | <p />The following list of technologies comes from
18 | a REST API call to the Go-based back end. Find
19 | and change the corresponding code in
20 | <code>webapp/src/components/TechItems.vue</code>
21 | and <code>server/web/app.go</code>.
22 | <TechItems />
23 | </div>
24 | </main>
25 | </template>
26 |
27 | <style>
28 | body {
29 | margin-top: 5%;
30 | padding-right: 5%;
31 | padding-left: 5%;
32 | font-size: larger;
33 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
34 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
35 | sans-serif;
36 | -webkit-font-smoothing: antialiased;
37 | -moz-osx-font-smoothing: grayscale;
38 | }
39 |
40 | @media screen and (min-width: 800px) {
41 | body {
42 | padding-right: 15%;
43 | padding-left: 15%;
44 | }
45 | }
46 |
47 | @media screen and (min-width: 1600px) {
48 | body {
49 | padding-right: 30%;
50 | padding-left: 30%;
51 | }
52 | }
53 |
54 | code {
55 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
56 | monospace;
57 | background-color: #b3e6ff;
58 | }
59 |
60 | .title {
61 | text-align: center;
62 | }
63 |
64 | .logo {
65 | text-align: center;
66 | }
67 | </style>
68 |
--------------------------------------------------------------------------------
/templates/vue.webapp/src/components/TechItems.vue:
--------------------------------------------------------------------------------
1 | <template>
2 | <ul class="technologies">
3 | <li v-for="technology in technologies" v-bind:key="technology.name">
4 | <b>{{technology.name}}</b>: {{technology.details}}
5 | </li>
6 | </ul>
7 | </template>
8 |
9 | <script>
10 | import axios from 'axios'
11 |
12 | export default {
13 | name: 'TechItems',
14 | data() {
15 | return {
16 | technologies: []
17 | };
18 | },
19 | mounted() {
20 | axios
21 | .get(`${import.meta.env.VITE_API_URL}/api/technologies`)
22 | .then(response => (this.technologies = response.data));
23 | }
24 | };
25 | </script>
26 |
27 | <style scoped>
28 | .technologies {
29 | margin-top: 5px;
30 | }
31 | </style>
32 |
--------------------------------------------------------------------------------
/templates/vue.webapp/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 |
4 | createApp(App).mount('#app')
5 |
--------------------------------------------------------------------------------
/templates/vue.webapp/vite.config.js:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 |
3 | import { defineConfig } from 'vite'
4 | import vue from '@vitejs/plugin-vue'
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [vue()],
9 | resolve: {
10 | alias: {
11 | '@': fileURLToPath(new URL('./src', import.meta.url))
12 | }
13 | },
14 | build: {
15 | outDir: 'build',
16 | },
17 | })
18 |
--------------------------------------------------------------------------------
/transform/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/shpota/goxygen/transform
2 |
3 | go 1.21
4 |
--------------------------------------------------------------------------------
/transform/transformer.go:
--------------------------------------------------------------------------------
1 | // Transforms static content form the 'templates' folder
2 | // in the root of the repository to Go code in order to
3 | // distribute it as a part of the module.
4 | package main
5 |
6 | import (
7 | "bytes"
8 | "log"
9 | "os"
10 | "path/filepath"
11 | "runtime"
12 | "sort"
13 | "strconv"
14 | "strings"
15 | )
16 |
17 | func main() {
18 | _, filename, _, _ := runtime.Caller(0)
19 | projectRoot := filepath.Join(filepath.Dir(filename), "..")
20 |
21 | var buffer bytes.Buffer
22 | buffer.WriteString(prefix)
23 | textFiles, images := contentFromFiles(filepath.Join(projectRoot, "templates"))
24 | for _, path := range sortedFilePaths(textFiles) {
25 | writeTextFile(path, textFiles[path], &buffer)
26 | }
27 | buffer.WriteString(middle)
28 | for _, path := range sortedImagePaths(images) {
29 | writeImage(path, images[path], &buffer)
30 | }
31 | buffer.WriteString(suffix)
32 | createSourceFile(filepath.Join(projectRoot, "static", "generated.go"), buffer.Bytes())
33 | log.Println("Completed.")
34 | }
35 |
36 | func createSourceFile(path string, content []byte) {
37 | pkgDir := filepath.Dir(path)
38 | _ = os.MkdirAll(pkgDir, os.ModePerm)
39 | err := os.WriteFile(path, content, 0644)
40 | if err != nil {
41 | log.Fatalln(err)
42 | }
43 | }
44 |
45 | func contentFromFiles(root string) (map[string]string, map[string][]byte) {
46 | textFiles := make(map[string]string)
47 | images := make(map[string][]byte)
48 | for _, originalPath := range filePaths(root) {
49 | path := originalPath[len(root)+1:]
50 | sep := string(os.PathSeparator)
51 | if sep != "/" {
52 | path = strings.Replace(path, sep, "/", -1)
53 | }
54 | ext := filepath.Ext(originalPath)
55 | content, err := os.ReadFile(originalPath)
56 | if err != nil {
57 | log.Fatalln(err)
58 | }
59 | if ext == ".png" || ext == ".ico" {
60 | images[path] = content
61 | } else {
62 | textFiles[path] = string(content)
63 | }
64 | }
65 | return textFiles, images
66 | }
67 |
68 | func writeImage(path string, imgBinary []byte, buffer *bytes.Buffer) {
69 | buffer.WriteString(` "` + path + `": {`)
70 | for _, b := range imgBinary {
71 | buffer.WriteString(strconv.Itoa(int(b)) + ", ")
72 | }
73 | buffer.WriteString("}" + lineSeparator)
74 | }
75 |
76 | func writeTextFile(path string, content string, buffer *bytes.Buffer) {
77 | buffer.WriteString(` "` + path + `": ` + "`")
78 | for _, c := range content {
79 | if string(c) == "`" {
80 | buffer.WriteString("` + " + `"` + "`" + `" + ` + "`")
81 | } else {
82 | buffer.WriteString(string(c))
83 | }
84 | }
85 | buffer.WriteString("`" + lineSeparator)
86 | }
87 |
88 | func filePaths(dir string) []string {
89 | templates := []string{}
90 | err := filepath.Walk(dir,
91 | func(path string, info os.FileInfo, err error) error {
92 | if err != nil {
93 | return err
94 | }
95 | if !info.IsDir() {
96 | templates = append(templates, path)
97 | }
98 | return nil
99 | })
100 | if err != nil {
101 | log.Fatalln(err)
102 | }
103 | return templates
104 | }
105 |
106 | func sortedFilePaths(sources map[string]string) []string {
107 | var paths []string
108 | for path := range sources {
109 | paths = append(paths, path)
110 | }
111 | sort.Strings(paths)
112 | return paths
113 | }
114 |
115 | func sortedImagePaths(images map[string][]byte) []string {
116 | var paths []string
117 | for path := range images {
118 | paths = append(paths, path)
119 | }
120 | sort.Strings(paths)
121 | return paths
122 | }
123 |
124 | // Standard header defined at https://golang.org/s/generatedcode
125 | const prefix = `// Code generated from transform/transformer.go; DO NOT EDIT.
126 |
127 | // Package 'static' contains static assets such as
128 | // source code, text files or images generated form
129 | // the 'templates' folder in the root of the repository.
130 | // If a change is made in templates regenerate this file
131 | // by running 'transform/transformer.go'.
132 | package static
133 |
134 | func Sources() map[string]string {
135 | return map[string]string{
136 | `
137 | const lineSeparator = `,
138 | `
139 | const middle = ` }
140 | }
141 |
142 | func Images() map[string][]byte {
143 | return map[string][]byte{
144 | `
145 |
146 | const suffix = ` }
147 | }`
148 |
--------------------------------------------------------------------------------
/transform/transformer_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestSortedImagePaths(t *testing.T) {
8 | images := map[string][]byte{
9 | "/path2": {2},
10 | "/path3": {2},
11 | "/path1": {1},
12 | }
13 |
14 | paths := sortedImagePaths(images)
15 |
16 | if paths[0] != "/path1" || paths[2] != "/path3" {
17 | t.Error("paths are not sorted")
18 | }
19 | }
20 |
21 | func TestSortedFilePaths(t *testing.T) {
22 | sources := map[string]string{
23 | "/path2": "src",
24 | "/path3": "src",
25 | "/path1": "src",
26 | }
27 |
28 | paths := sortedFilePaths(sources)
29 |
30 | if paths[0] != "/path1" || paths[2] != "/path3" {
31 | t.Error("paths are not sorted")
32 | }
33 | }
34 |
--------------------------------------------------------------------------------