tpl

package
v1.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 22, 2023 License: MIT Imports: 0 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CMD_ROOTGO_TPL = Template{
	FilePath: "cmd/root.go",
	Render:   true,
	Content: `package cmd

import (
	"fmt"
	"os"
	"runtime/debug"
	"strings"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string
var SemVer = "development"

func displaySemverInfo() {
	if SemVer != "development" {
		fmt.Printf("v%s", SemVer)
		return
	}
	version, ok := debug.ReadBuildInfo()
	if ok && version.Main.Version != "(devel)" && version.Main.Version != "" {
		SemVer = version.Main.Version
	}
	fmt.Printf("v%s", SemVer)
}

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "{{ .AppName }}",
	Short: "{{ .AppName }} is an stk project.",
	Long:  "{{ .AppName }} is generated using stk cli.",
	Run: func(cmd *cobra.Command, args []string) {
		if cmd.Flag("version").Value.String() == "true" {
			displaySemverInfo()
		} else {
			cmd.Help()
		}
	},
}

func Execute() {
	err := rootCmd.Execute()
	if err != nil {
		os.Exit(1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)
	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", ".stk.yaml", "config file.")
	rootCmd.Flags().BoolP("version", "v", false, "display {{ .AppName }} version")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" {
		// Use config file from the flag.
		viper.SetConfigFile(cfgFile)
	}

	viper.AutomaticEnv()

	// Set the key replacer for env variables.
	replacer := strings.NewReplacer(".", "_")
	viper.SetEnvKeyReplacer(replacer)

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
	}

}
`,
}
View Source
var CMD_SERVEGO_TPL = Template{
	FilePath: "cmd/serve.go",
	Render:   true,
	Content: `package cmd

import (
	"sync"

	"{{ .PkgName }}/server"
	"github.com/spf13/cobra"
)

var startingPort string

// serveCmd represents the serve command
var serveCmd = &cobra.Command{
	Use:   "serve",
	Short: "Start the server",
	Run: func(cmd *cobra.Command, args []string) {
		var wg sync.WaitGroup

		wg.Add(1)

		startAddr := "0.0.0.0:"

		go func() {
			defer wg.Done()
			_, done := server.StartHttpServer(startAddr + startingPort)
			// blocks the routine until done is closed
			<-done
		}()

		wg.Wait()
	},
}

func init() {
	serveCmd.Flags().StringVarP(&startingPort, "port", "p", "8080", "Port to start the server on")

	rootCmd.AddCommand(serveCmd)
}
`,
}
View Source
var DOCKERCOMPOSEYAML_TPL = Template{
	FilePath: "docker-compose.yaml",
	Render:   true,
	Content: `services:
  {{ .AppName }}:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    networks:
      - {{ .AppName }}-network

networks:
  {{ .AppName }}-network:
    driver: bridge
`,
}
View Source
var DOCKERFILE_TPL = Template{
	FilePath: "Dockerfile",
	Render:   true,
	Content: `# Start from the official Golang image to build our application.
FROM golang:1.21 AS build

# Set the working directory inside the container.
WORKDIR /app

# Copy go.mod and go.sum to download all dependencies.
COPY go.mod go.sum ./
RUN go mod download

# Copy the rest of the source code.
COPY . .

# Build the application. 
# This produces a statically linked executable by disabling cgo which 
# is not needed in a scratch container.
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o {{ .AppName }} .

# Now, start from a new stage with a minimal base image for a smaller final image.
FROM alpine:latest

# Copy the statically linked executable from the build stage to the current stage.
COPY --from=build /app/{{ .AppName }} .

# Expose the port the application listens on.
EXPOSE 8080

# Command to run the executable.
CMD ["./{{ .AppName }}"]
`,
}
View Source
var GITHOOKS_PREPUSH_TPL = Template{
	FilePath: ".githooks/pre-push",
	Render:   true,
	Content: `#!/bin/sh
make testci`,
}
View Source
var GITHUB_WORKFLOWS_GOBUILDTESTYML_TPL = Template{
	FilePath: ".github/workflows/go-build-test.yml",
	Render:   false,
	Content: `# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go Build and Test

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:

  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Build
      run: "make build"

    - name: Test
      run: "make testci"
`,
}
View Source
var GITHUB_WORKFLOWS_GORELEASEYML_TPL = Template{
	FilePath: ".github/workflows/go-release.yml",
	Render:   false,
	Content: `name: Go Release Workflow

on:
  push:
    # Sequence of patterns matched against refs/tags
    tags:
      - "v*.*.*" # Push events to matching v*, i.e. v1.0, v20.15.10

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - run: git fetch --force --tags # Ensures go releaser picks us previous tags.
      - uses: actions/setup-go@v4
        with:
          go-version: '1.21' # The Go version to download (if necessary) and use.
     
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v5
        with:
          distribution: goreleaser
          version: latest
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`,
}
View Source
var GITIGNORE_TPL = Template{
	FilePath: ".gitignore",
	Render:   true,
	Content: `# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
dist

*.db
.stk.yaml`,
}
View Source
var GORELEASERYAML_TPL = Template{
	FilePath: ".goreleaser.yaml",
	Render:   true,
	Content: `project_name: {{ .AppName }}

before:
  hooks:
    # You may remove this if you don't use go modules.
    - go mod tidy

builds:
  - main: ./main.go
    binary: {{ .AppName }}
    ldflags:
      - -s -w -X "{{ .PkgName }}/cmd.SemVer={{"{{ .Tag }}"}}"
    env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin
    goarch:
      - amd64
      - arm64

archives:
  - format: tar.gz
    format_overrides:
      - goos: windows
        format: zip
    
    # this name template makes the OS and Arch compatible with the results of uname.
    name_template: "{{"{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"}}"

changelog:
  sort: asc
  use: github
  filters:
    exclude:
      - '^docs:'
      - '^test:'
    include:
      - "^feat:"
      - "^fix:"
      - "^refactor:"
      - "^chore:"
      - "^perf:"


`,
}
View Source
var INTERNALS_PING_API_HANDLER_PINGGO_MOD_TPL = Template{
	FilePath: "internals/ping/api/handler/ping.go",
	Render:   true,
	Content: `package handler

import (
	"net/http"

	"{{ .PkgName }}/internals/{{ .ModName }}/domain"

	"github.com/adharshmk96/stk/gsk"
)

type {{ .ModName }}Handler struct {
	service domain.{{ .ExportedName }}Service
}

func New{{ .ExportedName }}Handler(service domain.{{ .ExportedName }}Service) domain.{{ .ExportedName }}Handlers {
	return &{{ .ModName }}Handler{
		service: service,
	}
}

/*
{{ .ExportedName }}Handler returns {{ .ModName }} 200 response
Response:
- 200: OK
- 500: Internal Server Error
*/
func (h *{{ .ModName }}Handler) {{ .ExportedName }}Handler(gc *gsk.Context) {

	message, err := h.service.{{ .ExportedName }}Service()
	if err != nil {
		gc.Status(http.StatusInternalServerError).JSONResponse(gsk.Map{
			"error": err.Error(),
		})
		return
	}

	gc.Status(http.StatusOK).JSONResponse(gsk.Map{
		"message": message,
	})
}
`,
}
View Source
var INTERNALS_PING_API_HANDLER_PING_TESTGO_MOD_TPL = Template{
	FilePath: "internals/ping/api/handler/ping_test.go",
	Render:   true,
	Content: `package handler_test

// run the following command to generate mocks for {{ .ExportedName }} interfaces
//
// mockery --dir=internals/{{ .ModName }}/{{ .ModName }} --name=^{{ .ExportedName }}.*

import (
	"net/http"
	"testing"

	"{{ .PkgName }}/internals/{{ .ModName }}/api/handler"

	"github.com/adharshmk96/stk/gsk"
	"{{ .PkgName }}/mocks"
	"github.com/stretchr/testify/assert"
)

func Test{{ .ExportedName }}Handler(t *testing.T) {
	t.Run("{{ .ExportedName }} Handler returns 200", func(t *testing.T) {

		// Arrange
		s := gsk.New()
		service := mocks.New{{ .ExportedName }}Service(t)
		service.On("{{ .ExportedName }}Service").Return("pong", nil)

		{{ .ModName }}Handler := handler.New{{ .ExportedName }}Handler(service)

		s.Get("/{{ .ModName }}", {{ .ModName }}Handler.{{ .ExportedName }}Handler)

		// Act
		w, _ := s.Test("GET", "/{{ .ModName }}", nil)

		// Assert
		assert.Equal(t, http.StatusOK, w.Code)
	})
}
`,
}
View Source
var INTERNALS_PING_API_TRANSPORT_PINGGO_MOD_TPL = Template{
	FilePath: "internals/ping/api/transport/ping.go",
	Render:   true,
	Content: `package transport
`,
}
View Source
var INTERNALS_PING_DOMAIN_HANDLERGO_MOD_TPL = Template{
	FilePath: "internals/ping/domain/handler.go",
	Render:   true,
	Content: `package domain

import "github.com/adharshmk96/stk/gsk"

// Handler
type {{ .ExportedName }}Handlers interface {
	{{ .ExportedName }}Handler(gc *gsk.Context)
}
`,
}
View Source
var INTERNALS_PING_DOMAIN_PINGGO_MOD_TPL = Template{
	FilePath: "internals/ping/domain/ping.go",
	Render:   true,
	Content: `package domain

// Domain
type {{ .ExportedName }}Data struct {
	{{ .ModName }} string
}
`,
}
View Source
var INTERNALS_PING_DOMAIN_SERVICEGO_MOD_TPL = Template{
	FilePath: "internals/ping/domain/service.go",
	Render:   true,
	Content: `package domain

// Service
type {{ .ExportedName }}Service interface {
	{{ .ExportedName }}Service() (string, error)
}
`,
}
View Source
var INTERNALS_PING_DOMAIN_STORAGEGO_MOD_TPL = Template{
	FilePath: "internals/ping/domain/storage.go",
	Render:   true,
	Content: `package domain

// Storage
type {{ .ExportedName }}Storage interface {
	{{ .ExportedName }}() error
}
`,
}
View Source
var INTERNALS_PING_ROUTESGO_MOD_TPL = Template{
	FilePath: "internals/ping/routes.go",
	Render:   true,
	Content: `package {{ .ModName }}

import (
	"github.com/adharshmk96/stk/gsk"
	"{{ .PkgName }}/internals/{{ .ModName }}/api/handler"
	"{{ .PkgName }}/internals/{{ .ModName }}/domain"
	"{{ .PkgName }}/internals/{{ .ModName }}/service"
	"{{ .PkgName }}/internals/{{ .ModName }}/storage"
	"{{ .PkgName }}/internals/{{ .ModName }}/web"
	"{{ .PkgName }}/server/infra/db"
)

func initialize{{ .ExportedName }}Handler() domain.{{ .ExportedName }}Handlers {
	conn := db.GetSqliteConnection()

	{{ .ModName }}Storage := storage.NewSqliteRepo(conn)
	{{ .ModName }}Service := service.New{{ .ExportedName }}Service({{ .ModName }}Storage)
	{{ .ModName }}Handler := handler.New{{ .ExportedName }}Handler({{ .ModName }}Service)

	return {{ .ModName }}Handler
}

func SetupApiRoutes(rg *gsk.RouteGroup) {
	{{ .ModName }}Handler := initialize{{ .ExportedName }}Handler()

	{{ .ModName }}Routes := rg.RouteGroup("/{{ .ModName }}")

	{{ .ModName }}Routes.Get("/", {{ .ModName }}Handler.{{ .ExportedName }}Handler)
}

func SetupWebRoutes(rg *gsk.RouteGroup) {
	rg.Get("/{{ .ModName }}", web.HomeHandler)
}
`,
}
View Source
var INTERNALS_PING_SERR_PINGGO_MOD_TPL = Template{
	FilePath: "internals/ping/serr/ping.go",
	Render:   true,
	Content: `package serr

import "errors"

var (
	Err{{ .ExportedName }}Failed = errors.New("{{ .ModName }} failed")
)
`,
}
View Source
var INTERNALS_PING_SERVICE_PINGGO_MOD_TPL = Template{
	FilePath: "internals/ping/service/ping.go",
	Render:   true,
	Content: `package service

import (
	"{{ .PkgName }}/internals/{{ .ModName }}/domain"
)

type {{ .ModName }}Service struct {
	storage domain.{{ .ExportedName }}Storage
}

func New{{ .ExportedName }}Service(storage domain.{{ .ExportedName }}Storage) domain.{{ .ExportedName }}Service {
	return &{{ .ModName }}Service{
		storage: storage,
	}
}

func (s *{{ .ModName }}Service) {{ .ExportedName }}Service() (string, error) {
	err := s.storage.{{ .ExportedName }}()
	if err != nil {
		return "", err
	}
	return "pong", nil
}
`,
}
View Source
var INTERNALS_PING_SERVICE_PING_TESTGO_MOD_TPL = Template{
	FilePath: "internals/ping/service/ping_test.go",
	Render:   true,
	Content: `package service_test

// run the following command to generate mocks for {{ .ExportedName }}Storage and {{ .ExportedName }} interfaces
//
// mockery --dir=internals/{{ .ModName }}/{{ .ModName }} --name=^{{ .ExportedName }}.*

import (
	"testing"

	"{{ .PkgName }}/internals/{{ .ModName }}/service"
	"{{ .PkgName }}/mocks"
	"github.com/stretchr/testify/assert"
)

func Test{{ .ExportedName }}Service(t *testing.T) {
	t.Run("{{ .ExportedName }}Service returns pong", func(t *testing.T) {

		// Arrange
		storage := mocks.New{{ .ExportedName }}Storage(t)
		storage.On("{{ .ExportedName }}").Return(nil)

		svc := service.New{{ .ExportedName }}Service(storage)

		// Act
		msg, err := svc.{{ .ExportedName }}Service()

		// Assert
		assert.NoError(t, err)
		assert.Equal(t, "pong", msg)
	})
}
`,
}
View Source
var INTERNALS_PING_STORAGE_PINGGO_MOD_TPL = Template{
	FilePath: "internals/ping/storage/ping.go",
	Render:   true,
	Content: `package storage

import (
	"database/sql"
	"fmt"

	"{{ .PkgName }}/internals/{{ .ModName }}/domain"
	"{{ .PkgName }}/internals/{{ .ModName }}/serr"
	"{{ .PkgName }}/server/infra"
)

type sqliteRepo struct {
	conn *sql.DB
}

func NewSqliteRepo(conn *sql.DB) domain.{{ .ExportedName }}Storage {
	return &sqliteRepo{
		conn: conn,
	}
}

func (s *sqliteRepo) {{ .ExportedName }}() error {
	logger := infra.GetLogger()
	rows, err := s.conn.Query(SELECT_ONE_TEST)
	if err != nil {
		return serr.Err{{ .ExportedName }}Failed
	}
	defer func(rows *sql.Rows) {
		err := rows.Close()
		if err != nil {
			logger.Error("connection close failed.")
		}
	}(rows)

	var result int

	if rows.Next() {
		err = rows.Scan(&result)
		if err != nil {
			return serr.Err{{ .ExportedName }}Failed
		}
	} else {
		return serr.Err{{ .ExportedName }}Failed
	}

	logger.Info(fmt.Sprintf("connection result: %d", result))
	return nil
}
`,
}
View Source
var INTERNALS_PING_STORAGE_PINGQUERIESGO_MOD_TPL = Template{
	FilePath: "internals/ping/storage/pingQueries.go",
	Render:   true,
	Content: `package storage

const (
	SELECT_ONE_TEST = "SELECT 1"
)
`,
}
View Source
var INTERNALS_PING_WEB_PINGGO_MOD_TPL = Template{
	FilePath: "internals/ping/web/ping.go",
	Render:   true,
	Content: `package web

import (
	"github.com/adharshmk96/stk/gsk"
)

func HomeHandler(gc *gsk.Context) {

	gc.TemplateResponse(&gsk.Tpl{
		TemplatePath: "public/templates/index.html",
		Variables: gsk.Map{
			"Title":   "{{ .ExportedName }}",
			"Content": "Welcome to the {{ .ModName }} page!",
		},
	})

}
`,
}
View Source
var MAINGO_TPL = Template{
	FilePath: "main.go",
	Render:   true,
	Content: `package main

import "{{ .PkgName }}/cmd"

func main() {
	cmd.Execute()
}
`,
}
View Source
var MAKEFILE_TPL = Template{
	FilePath: "makefile",
	Render:   true,
	Content: `publish:
	@git push && semver push


##########################
### Build Commands
##########################

BINARY_NAME={{ .AppName }}

build:
	@go build -o ./out/$(BINARY_NAME) -v

run: 
	@go run . serve -p 8080

test:
	@go test ./...

coverage:
	@go test -v ./... -coverprofile=coverage.out 
	@go tool cover -html=coverage.out

testci:
	@go test ./... -coverprofile=coverage.out

clean:
	@go clean
	@rm -f ./out/$(BINARY_NAME)
	@rm -f coverage.out

deps:
	@go mod download

tidy:
	@go mod tidy

lint:
	@golangci-lint run --enable-all

vet:
	@go vet

clean-branch:
	@git branch | egrep -v "(^\*|main|master)" | xargs git branch -D
	@git tag -d $(shell git tag -l)

	
##########################
### Setup Commands
##########################

init: 
	@go mod tidy
# Install tools
	@go install github.com/adharshmk96/semver@latest
	@go install github.com/vektra/mockery/v2@latest
# Setup Git hooks
	@git config core.hooksPath .githooks

# mockgen:
	@rm -rf ./mocks
	@mockery --all	

	@echo "Project initialized."
`,
}
View Source
var MOCKS_PINGHANDLERSGO_MOD_TPL = Template{
	FilePath: "mocks/PingHandlers.go",
	Render:   true,
	Content: `// Code generated by mockery v2.20.0. DO NOT EDIT.

package mocks

import (
	gsk "github.com/adharshmk96/stk/gsk"
	mock "github.com/stretchr/testify/mock"
)

// {{ .ExportedName }}Handlers is an autogenerated mock type for the {{ .ExportedName }}Handlers type
type {{ .ExportedName }}Handlers struct {
	mock.Mock
}

// {{ .ExportedName }}Handler provides a mock function with given fields: gc
func (_m *{{ .ExportedName }}Handlers) {{ .ExportedName }}Handler(gc *gsk.Context) {
	_m.Called(gc)
}

type mockConstructorTestingTNew{{ .ExportedName }}Handlers interface {
	mock.TestingT
	Cleanup(func())
}

// New{{ .ExportedName }}Handlers creates a new instance of {{ .ExportedName }}Handlers. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func New{{ .ExportedName }}Handlers(t mockConstructorTestingTNew{{ .ExportedName }}Handlers) *{{ .ExportedName }}Handlers {
	mock := &{{ .ExportedName }}Handlers{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
`,
}
View Source
var MOCKS_PINGSERVICEGO_MOD_TPL = Template{
	FilePath: "mocks/PingService.go",
	Render:   true,
	Content: `// Code generated by mockery v2.20.0. DO NOT EDIT.

package mocks

import mock "github.com/stretchr/testify/mock"

// {{ .ExportedName }}Service is an autogenerated mock type for the {{ .ExportedName }}Service type
type {{ .ExportedName }}Service struct {
	mock.Mock
}

// {{ .ExportedName }}Service provides a mock function with given fields:
func (_m *{{ .ExportedName }}Service) {{ .ExportedName }}Service() (string, error) {
	ret := _m.Called()

	var r0 string
	var r1 error
	if rf, ok := ret.Get(0).(func() (string, error)); ok {
		return rf()
	}
	if rf, ok := ret.Get(0).(func() string); ok {
		r0 = rf()
	} else {
		r0 = ret.Get(0).(string)
	}

	if rf, ok := ret.Get(1).(func() error); ok {
		r1 = rf()
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

type mockConstructorTestingTNew{{ .ExportedName }}Service interface {
	mock.TestingT
	Cleanup(func())
}

// New{{ .ExportedName }}Service creates a new instance of {{ .ExportedName }}Service. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func New{{ .ExportedName }}Service(t mockConstructorTestingTNew{{ .ExportedName }}Service) *{{ .ExportedName }}Service {
	mock := &{{ .ExportedName }}Service{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
`,
}
View Source
var MOCKS_PINGSTORAGEGO_MOD_TPL = Template{
	FilePath: "mocks/PingStorage.go",
	Render:   true,
	Content: `// Code generated by mockery v2.20.0. DO NOT EDIT.

package mocks

import mock "github.com/stretchr/testify/mock"

// {{ .ExportedName }}Storage is an autogenerated mock type for the {{ .ExportedName }}Storage type
type {{ .ExportedName }}Storage struct {
	mock.Mock
}

// {{ .ExportedName }} provides a mock function with given fields:
func (_m *{{ .ExportedName }}Storage) {{ .ExportedName }}() error {
	ret := _m.Called()

	var r0 error
	if rf, ok := ret.Get(0).(func() error); ok {
		r0 = rf()
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

type mockConstructorTestingTNew{{ .ExportedName }}Storage interface {
	mock.TestingT
	Cleanup(func())
}

// New{{ .ExportedName }}Storage creates a new instance of {{ .ExportedName }}Storage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func New{{ .ExportedName }}Storage(t mockConstructorTestingTNew{{ .ExportedName }}Storage) *{{ .ExportedName }}Storage {
	mock := &{{ .ExportedName }}Storage{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
`,
}
View Source
var PUBLIC_ASSETS_SCRIPTJS_TPL = Template{
	FilePath: "public/assets/script.js",
	Render:   true,
	Content:  ``,
}
View Source
var PUBLIC_ASSETS_STYLESCSS_TPL = Template{
	FilePath: "public/assets/styles.css",
	Render:   true,
	Content:  ``,
}
View Source
var PUBLIC_TEMPLATES_INDEXHTML_TPL = Template{
	FilePath: "public/templates/index.html",
	Render:   false,
	Content: `<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>{{ .Var.Title }}</title>
    <link rel="stylesheet" href="{{ .Config.Static }}/style.css">
</head>
<body>
    <h1>{{ .Var.Title }}</h1>
    <p>{{ .Var.Content }}</p>

    <script src="{{ .Config.Static }}/script.js"></script>
</body>
</html>
`,
}
View Source
var READMEMD_TPL = Template{
	FilePath: "README.md",
	Render:   true,
	Content: `# {{ .AppName }}

Run

go run main.go serve -p 8080

- or -

make run


## Project Structure Documentation

This is the project structure generated by "stk init" command.

read more about project structure [here](https://stk-docs.netlify.app/getting-started/project-structure)`,
}
View Source
var SERVER_INFRA_CONFIGGO_TPL = Template{
	FilePath: "server/infra/config.go",
	Render:   true,
	Content: `package infra

import "github.com/spf13/viper"

// Configurations are loaded from the environment variables using viper.
// callin this function will reLoad the config. (useful for testing)
// WARN: this will reload all the config.
func LoadDefaultConfig() {
	viper.SetDefault(ENV_SQLITE_FILEPATH, "database.db")

	viper.AutomaticEnv()
}
`,
}
View Source
var SERVER_INFRA_CONSTANTSGO_TPL = Template{
	FilePath: "server/infra/constants.go",
	Render:   true,
	Content: `package infra

// Environment Variable Names
const (
	ENV_SQLITE_FILEPATH = "SQLITE_FILEPATH"
)
`,
}
View Source
var SERVER_INFRA_DB_SQLITEGO_TPL = Template{
	FilePath: "server/infra/db/sqlite.go",
	Render:   true,
	Content: `package db

import (
	"database/sql"
	"sync"

	"{{ .PkgName }}/server/infra"
	_ "github.com/mattn/go-sqlite3"
	"github.com/spf13/viper"
)

var (
	sqliteInstance *sql.DB
	sqliteOnce     sync.Once
)

// GetSqliteConnection returns a singleton database connection
func GetSqliteConnection() *sql.DB {
	filepath := viper.GetString(infra.ENV_SQLITE_FILEPATH)
	sqliteOnce.Do(func() {
		db, err := sql.Open("sqlite3", filepath)
		if err != nil {
			panic(err)
		}
		sqliteInstance = db
	})
	return sqliteInstance
}

// ResetSqliteConnection resets the singleton database connection
func ResetSqliteConnection() {
	sqliteInstance = nil
	sqliteOnce = sync.Once{}
}
`,
}
View Source
var SERVER_INFRA_LOGGERGO_TPL = Template{
	FilePath: "server/infra/logger.go",
	Render:   true,
	Content: `package infra

import (
	"log/slog"
	"os"
)

var logger *slog.Logger

func init() {
	logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))
}

func GetLogger() *slog.Logger {
	return logger
}
`,
}
View Source
var SERVER_MIDDLEWARE_RATELIMITERGO_TPL = Template{
	FilePath: "server/middleware/rateLimiter.go",
	Render:   true,
	Content: `package middleware

import (
	"time"

	"github.com/adharshmk96/stk/gsk"
	gskmw "github.com/adharshmk96/stk/pkg/middleware"
)

func RateLimiter() gsk.Middleware {
	rlConfig := gskmw.RateLimiterConfig{
		RequestsPerInterval: 10,
		Interval:            60 * time.Second,
	}
	rateLimiter := gskmw.NewRateLimiter(rlConfig)
	return rateLimiter.Middleware
}
`,
}
View Source
var SERVER_ROUTING_PINGGO_MOD_TPL = Template{
	FilePath: "server/routing/ping.go",
	Render:   true,
	Content: `package routing

import "{{ .PkgName }}/internals/{{ .ModName }}"

func init() {
	RegisterApiRoutes({{ .ModName }}.SetupApiRoutes)
	RegisterWebRoutes({{ .ModName }}.SetupWebRoutes)
}
`,
}
View Source
var SERVER_ROUTING_SETUPROUTESGO_TPL = Template{
	FilePath: "server/routing/setupRoutes.go",
	Render:   true,
	Content: `package routing

import (
	"github.com/adharshmk96/stk/gsk"
)

var webRouteGroups = []func(*gsk.RouteGroup){}
var apiRouteGroups = []func(*gsk.RouteGroup){}

func RegisterApiRoutes(routeGroup func(*gsk.RouteGroup)) {
	apiRouteGroups = append(apiRouteGroups, routeGroup)
}

func RegisterWebRoutes(routeGroup func(*gsk.RouteGroup)) {
	webRouteGroups = append(webRouteGroups, routeGroup)
}

func SetupApiRoutes(server *gsk.Server) {
	apiRoutes := server.RouteGroup("/api")

	for _, routeGroup := range apiRouteGroups {
		routeGroup(apiRoutes)
	}
}

func SetupTemplateRoutes(server *gsk.Server) {
	templateRoutes := server.RouteGroup("/")

	for _, routeGroup := range webRouteGroups {
		routeGroup(templateRoutes)
	}

}
`,
}
View Source
var SERVER_SETUPGO_TPL = Template{
	FilePath: "server/setup.go",
	Render:   true,
	Content: `package server

import (
	"os"
	"os/signal"
	"syscall"

	"github.com/adharshmk96/stk/gsk"
	"github.com/adharshmk96/stk/pkg/middleware"
	"{{ .PkgName }}/server/infra"
	svrmw "{{ .PkgName }}/server/middleware"
	"{{ .PkgName }}/server/routing"
)

func StartHttpServer(port string) (*gsk.Server, chan bool) {

	logger := infra.GetLogger()

	serverConfig := &gsk.ServerConfig{
		Port:   port,
		Logger: logger,
	}

	server := gsk.New(serverConfig)

	rateLimiter := svrmw.RateLimiter()
	server.Use(rateLimiter)
	server.Use(middleware.RequestLogger)
	server.Use(middleware.CORS(middleware.CORSConfig{
		AllowAll: true,
	}))

	infra.LoadDefaultConfig()

	routing.SetupTemplateRoutes(server)
	routing.SetupApiRoutes(server)

	server.Start()

	// graceful shutdown
	done := make(chan bool)

	// A go routine that listens for os signals
	// it will block until it receives a signal
	// once it receives a signal, it will shut down close the done channel
	go func() {
		sigint := make(chan os.Signal, 1)
		signal.Notify(sigint, os.Interrupt, syscall.SIGTERM)
		<-sigint

		if err := server.Shutdown(); err != nil {
			logger.Error(err.Error())
		}

		close(done)
	}()

	return server, done
}
`,
}
View Source
var VSCODE_LAUNCHJSON_TPL = Template{
	FilePath: ".vscode/launch.json",
	Render:   true,
	Content: `{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "serve in port 8080",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}/main.go",
            "args": ["serve", "-p", "8080"]
          }
    ]
}`,
}

Functions

This section is empty.

Types

type Template added in v0.6.2

type Template struct {
	FilePath string
	Content  string
	Render   bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL