Skip to content

Commit

Permalink
chore: adding init setup
Browse files Browse the repository at this point in the history
  • Loading branch information
faizahmedfarooqui committed Sep 24, 2024
0 parents commit 2b9a755
Show file tree
Hide file tree
Showing 30 changed files with 1,289 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# Available modes: debug, release or test
GIN_MODE=debug

# The port that the application will run on
APP_PORT=3000

# Database configuration
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=goldtree9
DB_NAME=postgres
DB_SSLMODE=disable
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
*.bin

# Output from Air (temporary binary and logs)
tmp/
air.log

# Go environment settings
.env

# Dependency directories
vendor/
Godeps/

# Logs and temporary files
*.log
*.out
*.tmp
*.swp
*.swo
*.bak

# MacOS-specific files
.DS_Store

# Ignore Go modules (if you're vendoring dependencies, this is not needed)
go.sum

# IDE/Editor-specific files (optional, based on your IDE)
.idea/
.vscode/
*.sublime-workspace
*.sublime-project

# Generated code (like auto-generated validators)
validators/auto_generated.go

# Go build output
*.o
*.a
*.out
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
generate:
go generate ./validators

migrate-up:
go run cmd/migrate/main.go -up

migrate-down:
go run cmd/migrate/main.go -down

build:
go build -o ./tmp/main .

run:
go run main.go

develop:
air
133 changes: 133 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Go-Gin API Server

This project is a simple API server built with [Go](https://golang.org/) using the [Gin Web Framework](https://github.com/gin-gonic/gin). The project supports live reloading during development using **Air** and has an integrated migration system.

## Table of Contents
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Development](#development)
- [Database Migrations](#database-migrations)
- [Apply Migrations](#apply-migrations)
- [Rollback Migrations](#rollback-migrations)
- [Configuration](#configuration)
- [Contributing](#contributing)
- [License](#license)

---

## Prerequisites

Before setting up the project, ensure you have the following installed:

- [Go 1.17+](https://golang.org/dl/)
- [PostgreSQL](https://www.postgresql.org/) (or your preferred database)
- [Air](https://github.com/air-verse/air) for live-reloading (installed as a dependency)

## Installation

1. **Clone the repository**:
```bash
git clone https://github.com/yourusername/go-gin-api-server.git
cd go-gin-api-server
```

2. **Install dependencies**: Ensure all Go dependencies and tools (including **Air**) are installed.
```bash
go mod tidy
go install github.com/air-verse/air@latest
```

3. **Setup environment variables**: Create a `.env` file with your database and other environment variables.
```bash
cp .env.example .env
```

Example `.env` file:
```ini
# Available modes: debug, release or test
GIN_MODE=debug

# The port that the application will run on
APP_PORT=3000

# Database configuration
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=goldtree9
DB_NAME=postgres
DB_SSLMODE=disable
```

## Development

To start the server in development mode with live-reloading (using **Air**):

```bash
make develop
```

## Database Migrations

The project includes a migration system for managing database schema changes:

### Apply Migrations

To apply all pending migrations, run:

```bash
make migrate-up
```

### Rollback Migrations

To rollback the last migration, run:

```bash
make migrate-down
```

Migration files are located in the `database/migrations/` directory.
- **Up Migration**: Files ending in `.up.sql` are used for applying changes.
- **Down Migration**: Files ending in `.down.sql` are used for rolling back changes.

## Configuration

### air.toml (Development Mode)

The `air.toml` file is used for configuring the **Air** live-reloading tool. It watches specific directories and file types, such as `.go` and `.html`, to automatically rebuild and restart the server during development.

You can modify `air.toml` to suit your development workflow, for example:

```toml
[build]
cmd = "go build -o ./tmp/main ."
bin = "./tmp/main"
delay = 1000
tmp_dir = "tmp"

[watch]
includes = ["./controllers", "./routes", "./services", "./validators", "./config"]
include_ext = ["go", "html", "tmpl", "tpl"]
exclude_dir = ["vendor", "tmp", "database/migrations"]

[log]
level = "info"
```

## Contributing

If you would like to contribute to the project:

1. Fork the repository.
2. Create a new branch (git checkout -b feature-branch).
3. Commit your changes (git commit -am 'Add new feature').
4. Push to the branch (git push origin feature-branch).
5. Create a new Pull Request.

All contributions are welcome!

## License

This project is open-source and available under the [MIT License](LICENSE).

44 changes: 44 additions & 0 deletions air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# air.toml
[build]
# Command to build the app (default: "go build -o ./tmp/main .")
cmd = "go build -o ./tmp/main ."

# Binary that will be built and run (default: "./tmp/main")
bin = "./tmp/main"

# Delay before restarting the app after a change is detected (in milliseconds)
delay = 1000 # 1 second delay

# Specify directories for the temporary binary files (default: "tmp")
tmp_dir = "tmp"

[log]
# Log level (default: "info")
level = "info"

[watch]
# Directories or files to include in watch (default: current directory)
# You can add specific folders you want to watch.
includes = [
"./cmd",
"./config",
"./controllers",
"./database",
"./middlewares",
"./models",
"./repositories",
"./routes",
"./services",
"./utils",
"./validators"
]

# File extensions to watch (default: ["go"])
include_ext = ["go", "html", "tmpl", "tpl", "sql"]

# Exclude certain directories from being watched
exclude_dir = ["vendor", "tmp", "database/migrations"]

[ignore]
# List directories or files to be ignored from watching
dirs = ["tmp", "vendor"]
98 changes: 98 additions & 0 deletions cmd/generate_validators/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package main

import (
"go/ast"
"go/parser"
"go/token"
"html/template"
"log"
"os"
"path/filepath"
)

// Template for the auto-generated registration code
const tpl = `// Code generated by go generate; DO NOT EDIT.
package validators
import "reflect"
func init() {
{{- range .Structs }}
RegisterValidator(reflect.TypeOf({{ . }}{}).Name(), {{ . }}{})
{{- end }}
}
`

func main() {
// Get the current working directory
wd, err := os.Getwd()
if err != nil {
log.Fatalf("Failed to get working directory: %v", err)
}

// Resolve the absolute path to the validators directory
validatorsPath, err := filepath.Abs(filepath.Join(wd, "..", "validators"))
if err != nil {
log.Fatalf("Failed to resolve absolute path: %v", err)
}

log.Printf("Current working directory: %s", wd)
log.Printf("Parsing validators directory at: %s", validatorsPath)

// Parse the validators directory using the absolute path
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, validatorsPath, nil, parser.AllErrors)
if err != nil {
log.Fatalf("Failed to parse package at %s: %v", validatorsPath, err)
}

// Collect all struct names
structs := []string{}
for _, pkg := range pkgs {
for _, file := range pkg.Files {
for _, decl := range file.Decls {
gen, ok := decl.(*ast.GenDecl)
if !ok || gen.Tok != token.TYPE {
continue
}

for _, spec := range gen.Specs {
typeSpec, ok := spec.(*ast.TypeSpec)
if !ok {
continue
}

// Check if the type is a struct
if _, ok := typeSpec.Type.(*ast.StructType); ok {
structs = append(structs, typeSpec.Name.Name)
}
}
}
}
}

// Generate the output file using the absolute path
outputFilePath := filepath.Join(validatorsPath, "auto_generated.go")
file, err := os.Create(outputFilePath)
if err != nil {
log.Fatalf("Failed to create output file: %v", err)
}
defer file.Close()

// Use the template to generate the file
tmpl, err := template.New("validators").Parse(tpl)
if err != nil {
log.Fatalf("Failed to parse template: %v", err)
}

err = tmpl.Execute(file, struct {
Structs []string
}{
Structs: structs,
})
if err != nil {
log.Fatalf("Failed to execute template: %v", err)
}

log.Printf("Auto-generated validator registration completed at: %s", outputFilePath)
}
Loading

0 comments on commit 2b9a755

Please sign in to comment.