From f6b6a5c84c24a8336c31794b4a8bebd9c77102eb Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Fri, 21 Feb 2025 00:37:46 +0530 Subject: [PATCH 01/41] modifying ci/cd --- go-build.yml => workflows/go-build.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename go-build.yml => workflows/go-build.yml (100%) diff --git a/go-build.yml b/workflows/go-build.yml similarity index 100% rename from go-build.yml rename to workflows/go-build.yml From 65a99bdeb67de22ccbfdeebd30aee140bf02d1b5 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Fri, 21 Feb 2025 00:39:35 +0530 Subject: [PATCH 02/41] moving into .github --- {workflows => .github/workflows}/go-build.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {workflows => .github/workflows}/go-build.yml (100%) diff --git a/workflows/go-build.yml b/.github/workflows/go-build.yml similarity index 100% rename from workflows/go-build.yml rename to .github/workflows/go-build.yml From 0b0f20ff6aae0b94e61ad283cc5b8f765dc03617 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sun, 23 Feb 2025 19:30:45 +0530 Subject: [PATCH 03/41] test cases added --- models/user_test.go | 138 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 models/user_test.go diff --git a/models/user_test.go b/models/user_test.go new file mode 100644 index 0000000..8d53db9 --- /dev/null +++ b/models/user_test.go @@ -0,0 +1,138 @@ +package models + +import ( + "database/sql" + "testing" + + "user_crud/config" + + _ "github.com/lib/pq" // PostgreSQL driver +) + +func setupTestDB() { + // Initialize the test database connection + var err error + config.DB, err = sql.Open("postgres", "host=127.0.0.1 port=5432 user=mx dbname=crud_db sslmode=disable") + if err != nil { + panic(err) + } + + // Create a test table (optional) + _, err = config.DB.Exec(` + CREATE TABLE IF NOT EXISTS users ( + id SERIAL PRIMARY KEY, + name VARCHAR(100), + email VARCHAR(100) UNIQUE, + age INT + ); + `) + if err != nil { + panic(err) + } +} + +func teardownTestDB() { + // Drop test data after each test + config.DB.Exec("DELETE FROM users") + config.DB.Close() +} + +func TestCreateUser(t *testing.T) { + setupTestDB() + defer teardownTestDB() + + user := User{Name: "Alice", Email: "alice@example.com", Age: 28} + err := CreateUser(user) + if err != nil { + t.Errorf("Failed to create user: %v", err) + } + + var count int + err = config.DB.QueryRow("SELECT COUNT(*) FROM users WHERE email = $1", user.Email).Scan(&count) + if err != nil || count != 1 { + t.Errorf("User was not inserted into the database") + } +} + +func TestGetAllUsers(t *testing.T) { + setupTestDB() + defer teardownTestDB() + + // Insert test users + config.DB.Exec("INSERT INTO users (name, email, age) VALUES ('Bob', 'bob@example.com', 25), ('Charlie', 'charlie@example.com', 29)") + + users, err := GetAllUsers() + if err != nil { + t.Errorf("Failed to fetch users: %v", err) + } + + if len(users) < 2 { + t.Errorf("Expected at least 2 users, got %d", len(users)) + } +} + +func TestGetUserByID(t *testing.T) { + setupTestDB() + defer teardownTestDB() + + // Insert a test user + var id int + config.DB.QueryRow("INSERT INTO users (name, email, age) VALUES ('David', 'david@example.com', 40) RETURNING id").Scan(&id) + + user, err := GetUserByID(id) + if err != nil { + t.Errorf("Failed to get user by ID: %v", err) + } + + if user.Email != "david@example.com" { + t.Errorf("Expected email 'david@example.com', got %s", user.Email) + } +} + +func TestUpdateUser(t *testing.T) { + setupTestDB() + defer teardownTestDB() + + // Insert test user + var id int + config.DB.QueryRow("INSERT INTO users (name, email, age) VALUES ('Eve', 'eve@example.com', 22) RETURNING id").Scan(&id) + + // Update the user + updatedUser := User{ID: id, Name: "Eve Adams", Email: "eve@example.com", Age: 30} + err := UpdateUser(updatedUser) + if err != nil { + t.Errorf("Failed to update user: %v", err) + } + + // Verify update + var name string + var age int + config.DB.QueryRow("SELECT name, age FROM users WHERE id = $1", id).Scan(&name, &age) + + if name != "Eve Adams" || age != 30 { + t.Errorf("User was not updated correctly: got name=%s, age=%d", name, age) + } +} + +func TestDeleteUser(t *testing.T) { + setupTestDB() + defer teardownTestDB() + + // Insert test user + var id int + config.DB.QueryRow("INSERT INTO users (name, email, age) VALUES ('Frank', 'frank@example.com', 45) RETURNING id").Scan(&id) + + // Delete user + err := DeleteUser(id) + if err != nil { + t.Errorf("Failed to delete user: %v", err) + } + + // Verify deletion + var count int + config.DB.QueryRow("SELECT COUNT(*) FROM users WHERE id = $1", id).Scan(&count) + + if count != 0 { + t.Errorf("User was not deleted") + } +} From c33df47ae6a0fa7cd267de7d3f1068a0070e95d8 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:00:57 +0530 Subject: [PATCH 04/41] run test cases for user and also go build is working properly or not --- go-build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/go-build.yml b/go-build.yml index ebfd0dc..3216612 100644 --- a/go-build.yml +++ b/go-build.yml @@ -21,10 +21,13 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.4 # Adjust the version as needed + go-version: 1.23.4 - name: Install Dependencies run: go mod tidy - name: Build Project run: go build -v ./... + + - name: Run All Tests + run: go test -v ./... From 753a73295e06240d3f01e007dd5a7976e069e79e Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:06:50 +0530 Subject: [PATCH 05/41] added db connection --- go-build.yml | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 go-build.yml diff --git a/go-build.yml b/go-build.yml new file mode 100644 index 0000000..8f54924 --- /dev/null +++ b/go-build.yml @@ -0,0 +1,54 @@ +name: Go Build and Test with Database + +on: + push: + branches: + - "master" + - "develop" + pull_request: + branches: + - "master" + - "develop" + +jobs: + test: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:15 + env: + POSTGRES_USER: testuser + POSTGRES_PASSWORD: testpassword + POSTGRES_DB: testdb + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U testuser" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.23.4 + + - name: Install Dependencies + run: go mod tidy + + - name: Wait for Database + run: | + echo "Waiting for PostgreSQL to be ready..." + until pg_isready -h localhost -U testuser; do + sleep 2 + done + echo "PostgreSQL is ready!" + + - name: Run All Tests + env: + DATABASE_URL: postgres://testuser:testpassword@localhost:5432/testdb?sslmode=disable + run: go test -v ./... From f4be62612e8eb01854fe5ac5cda9503a745e0d28 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:10:00 +0530 Subject: [PATCH 06/41] added postgresql status --- go-build.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go-build.yml b/go-build.yml index 8f54924..46efa70 100644 --- a/go-build.yml +++ b/go-build.yml @@ -35,11 +35,17 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.4 + go-version: 1.23.4 # Adjust the version as needed - name: Install Dependencies run: go mod tidy + - name: Check PostgreSQL Status + run: | + echo "Checking if PostgreSQL is running..." + docker ps + pg_isready -h localhost -U testuser + - name: Wait for Database run: | echo "Waiting for PostgreSQL to be ready..." From c83ed404650f28522f8bc0d6511ec12840c88bd7 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:19:02 +0530 Subject: [PATCH 07/41] workflow file not using latest version --- .../workflows/{go-build.yml => workflow.yml} | 0 go-build.yml | 60 ------------------- 2 files changed, 60 deletions(-) rename .github/workflows/{go-build.yml => workflow.yml} (100%) delete mode 100644 go-build.yml diff --git a/.github/workflows/go-build.yml b/.github/workflows/workflow.yml similarity index 100% rename from .github/workflows/go-build.yml rename to .github/workflows/workflow.yml diff --git a/go-build.yml b/go-build.yml deleted file mode 100644 index 46efa70..0000000 --- a/go-build.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Go Build and Test with Database - -on: - push: - branches: - - "master" - - "develop" - pull_request: - branches: - - "master" - - "develop" - -jobs: - test: - runs-on: ubuntu-latest - services: - postgres: - image: postgres:15 - env: - POSTGRES_USER: testuser - POSTGRES_PASSWORD: testpassword - POSTGRES_DB: testdb - ports: - - 5432:5432 - options: >- - --health-cmd "pg_isready -U testuser" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: 1.23.4 # Adjust the version as needed - - - name: Install Dependencies - run: go mod tidy - - - name: Check PostgreSQL Status - run: | - echo "Checking if PostgreSQL is running..." - docker ps - pg_isready -h localhost -U testuser - - - name: Wait for Database - run: | - echo "Waiting for PostgreSQL to be ready..." - until pg_isready -h localhost -U testuser; do - sleep 2 - done - echo "PostgreSQL is ready!" - - - name: Run All Tests - env: - DATABASE_URL: postgres://testuser:testpassword@localhost:5432/testdb?sslmode=disable - run: go test -v ./... From 2bbafedfe69df0c23347ce260f5cf2248eb1beef Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:29:15 +0530 Subject: [PATCH 08/41] modification for db connect --- .github/workflows/workflow.yml | 37 +++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 3216612..46efa70 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -1,4 +1,4 @@ -name: Go Build Check +name: Go Build and Test with Database on: push: @@ -11,8 +11,22 @@ on: - "develop" jobs: - build: + test: runs-on: ubuntu-latest + services: + postgres: + image: postgres:15 + env: + POSTGRES_USER: testuser + POSTGRES_PASSWORD: testpassword + POSTGRES_DB: testdb + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U testuser" + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - name: Checkout Code @@ -21,13 +35,26 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.4 + go-version: 1.23.4 # Adjust the version as needed - name: Install Dependencies run: go mod tidy - - name: Build Project - run: go build -v ./... + - name: Check PostgreSQL Status + run: | + echo "Checking if PostgreSQL is running..." + docker ps + pg_isready -h localhost -U testuser + + - name: Wait for Database + run: | + echo "Waiting for PostgreSQL to be ready..." + until pg_isready -h localhost -U testuser; do + sleep 2 + done + echo "PostgreSQL is ready!" - name: Run All Tests + env: + DATABASE_URL: postgres://testuser:testpassword@localhost:5432/testdb?sslmode=disable run: go test -v ./... From 2b898704d0f7b2cdbed7c3c5b526ed14184a86d1 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:37:35 +0530 Subject: [PATCH 09/41] read db creds from .env/env vars --- models/user_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/models/user_test.go b/models/user_test.go index 8d53db9..776c7f6 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -2,6 +2,9 @@ package models import ( "database/sql" + "fmt" + "log" + "os" "testing" "user_crud/config" @@ -11,10 +14,19 @@ import ( func setupTestDB() { // Initialize the test database connection + // Database connection string + dbURL := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", + os.Getenv("DB_HOST"), + os.Getenv("DB_PORT"), + os.Getenv("DB_USER"), + os.Getenv("DB_PASS"), + os.Getenv("DB_NAME")) + + // Open connection var err error - config.DB, err = sql.Open("postgres", "host=127.0.0.1 port=5432 user=mx dbname=crud_db sslmode=disable") + config.DB, err = sql.Open("postgres", dbURL) if err != nil { - panic(err) + log.Fatal("Failed to connect to database:", err) } // Create a test table (optional) From 880ead38a00475d5a4042da9f06d80444f89d4e7 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:39:14 +0530 Subject: [PATCH 10/41] workflow modified to use creds from config --- .github/workflows/workflow.yml | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 46efa70..690f037 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -17,14 +17,14 @@ jobs: postgres: image: postgres:15 env: - POSTGRES_USER: testuser - POSTGRES_PASSWORD: testpassword - POSTGRES_DB: testdb + POSTGRES_USER: ${{ secrets.DB_USER }} + POSTGRES_PASSWORD: ${{ secrets.DB_PASSWORD }} + POSTGRES_DB: ${{ secrets.DB_NAME }} ports: - 5432:5432 options: >- - --health-cmd "pg_isready -U testuser" - --health-interval 10s + --health-cmd "pg_isready -U ${{ secrets.DB_USER }} -d ${{ secrets.DB_NAME }}" + --health-interval 5s --health-timeout 5s --health-retries 5 @@ -35,26 +35,12 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.4 # Adjust the version as needed + go-version: 1.23.4 - name: Install Dependencies run: go mod tidy - - name: Check PostgreSQL Status - run: | - echo "Checking if PostgreSQL is running..." - docker ps - pg_isready -h localhost -U testuser - - - name: Wait for Database - run: | - echo "Waiting for PostgreSQL to be ready..." - until pg_isready -h localhost -U testuser; do - sleep 2 - done - echo "PostgreSQL is ready!" - - - name: Run All Tests + - name: Run Tests with Database env: - DATABASE_URL: postgres://testuser:testpassword@localhost:5432/testdb?sslmode=disable - run: go test -v ./... + DATABASE_URL: postgres://${{ secrets.DB_USER }}:${{ secrets.DB_PASSWORD }}@localhost:${{ secrets.DB_PORT }}/${{ secrets.DB_NAME }}?sslmode=disable + run: go test -v ./... \ No newline at end of file From 2b551d3b15ee1cb120ff4eb8685a942c025d7160 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:46:14 +0530 Subject: [PATCH 11/41] Test Actions From e0c6ce9662636a185dccd84115a480652e3b8b9e Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:50:56 +0530 Subject: [PATCH 12/41] valid yml --- .github/workflows/workflow.yml | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 690f037..3fd4ad2 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -1,15 +1,3 @@ -name: Go Build and Test with Database - -on: - push: - branches: - - "master" - - "develop" - pull_request: - branches: - - "master" - - "develop" - jobs: test: runs-on: ubuntu-latest @@ -17,13 +5,13 @@ jobs: postgres: image: postgres:15 env: - POSTGRES_USER: ${{ secrets.DB_USER }} - POSTGRES_PASSWORD: ${{ secrets.DB_PASSWORD }} - POSTGRES_DB: ${{ secrets.DB_NAME }} + POSTGRES_USER: defaultuser + POSTGRES_PASSWORD: defaultpassword + POSTGRES_DB: defaultdb ports: - 5432:5432 options: >- - --health-cmd "pg_isready -U ${{ secrets.DB_USER }} -d ${{ secrets.DB_NAME }}" + --health-cmd "pg_isready -U defaultuser -d defaultdb" --health-interval 5s --health-timeout 5s --health-retries 5 @@ -40,7 +28,22 @@ jobs: - name: Install Dependencies run: go mod tidy + - name: Wait for PostgreSQL to Start + run: sleep 10 # Wait for PostgreSQL to be fully ready + + - name: Update PostgreSQL Credentials Securely + run: | + PGPASSWORD=defaultpassword psql -U defaultuser -d defaultdb -h localhost -p 5432 < Date: Mon, 24 Feb 2025 23:51:50 +0530 Subject: [PATCH 13/41] triggers --- .github/workflows/workflow.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 3fd4ad2..6efa5a6 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -1,3 +1,15 @@ +name: Go Build and Test with Database + +on: + push: + branches: + - "master" + - "develop" + pull_request: + branches: + - "master" + - "develop" + jobs: test: runs-on: ubuntu-latest From 2119fa66e1d97b6f59e7c4867316cf91497953f4 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:55:38 +0530 Subject: [PATCH 14/41] run with default credentials --- .github/workflows/workflow.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 6efa5a6..113e8bc 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -17,13 +17,13 @@ jobs: postgres: image: postgres:15 env: - POSTGRES_USER: defaultuser - POSTGRES_PASSWORD: defaultpassword - POSTGRES_DB: defaultdb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: testdb ports: - 5432:5432 options: >- - --health-cmd "pg_isready -U defaultuser -d defaultdb" + --health-cmd "pg_isready -U postgres -d testdb" --health-interval 5s --health-timeout 5s --health-retries 5 @@ -41,14 +41,14 @@ jobs: run: go mod tidy - name: Wait for PostgreSQL to Start - run: sleep 10 # Wait for PostgreSQL to be fully ready + run: sleep 10 # Ensure PostgreSQL is fully initialized - - name: Update PostgreSQL Credentials Securely + - name: Secure PostgreSQL Credentials run: | - PGPASSWORD=defaultpassword psql -U defaultuser -d defaultdb -h localhost -p 5432 < Date: Mon, 24 Feb 2025 23:59:01 +0530 Subject: [PATCH 15/41] remove unnecessary db create --- .github/workflows/workflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 113e8bc..d7ab0fb 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -47,7 +47,6 @@ jobs: run: | PGPASSWORD=postgres psql -U postgres -d testdb -h localhost -p 5432 < Date: Tue, 25 Feb 2025 00:03:19 +0530 Subject: [PATCH 16/41] setUpto use creds properly --- models/user_test.go | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/models/user_test.go b/models/user_test.go index 776c7f6..c05ca45 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -3,7 +3,6 @@ package models import ( "database/sql" "fmt" - "log" "os" "testing" @@ -13,31 +12,17 @@ import ( ) func setupTestDB() { - // Initialize the test database connection - // Database connection string - dbURL := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", - os.Getenv("DB_HOST"), - os.Getenv("DB_PORT"), - os.Getenv("DB_USER"), - os.Getenv("DB_PASS"), - os.Getenv("DB_NAME")) - - // Open connection - var err error - config.DB, err = sql.Open("postgres", dbURL) - if err != nil { - log.Fatal("Failed to connect to database:", err) - } + dbUser := os.Getenv("DB_USER") + dbPassword := os.Getenv("DB_PASSWORD") + dbName := os.Getenv("DB_NAME") + dbHost := os.Getenv("DB_HOST") + dbPort := os.Getenv("DB_PORT") - // Create a test table (optional) - _, err = config.DB.Exec(` - CREATE TABLE IF NOT EXISTS users ( - id SERIAL PRIMARY KEY, - name VARCHAR(100), - email VARCHAR(100) UNIQUE, - age INT - ); - `) + dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", + dbHost, dbPort, dbUser, dbPassword, dbName) + + var err error + config.DB, err = sql.Open("postgres", dsn) if err != nil { panic(err) } From e7c394db3e106604e7487c41b8337962afd4d99a Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Tue, 25 Feb 2025 00:08:51 +0530 Subject: [PATCH 17/41] Create table if not exists --- models/user_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/models/user_test.go b/models/user_test.go index c05ca45..9e6ccd5 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -26,6 +26,16 @@ func setupTestDB() { if err != nil { panic(err) } + + // Create a test table (optional) + _, err = config.DB.Exec(` + CREATE TABLE IF NOT EXISTS users ( + id SERIAL PRIMARY KEY, + name VARCHAR(100), + email VARCHAR(100) UNIQUE, + age INT + ); + `) } func teardownTestDB() { From fdbbf07427bbf14e392af57842f328480b644614 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Tue, 25 Feb 2025 00:13:55 +0530 Subject: [PATCH 18/41] setTestDB refactor --- models/user_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/models/user_test.go b/models/user_test.go index 9e6ccd5..221cff1 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -28,7 +28,7 @@ func setupTestDB() { } // Create a test table (optional) - _, err = config.DB.Exec(` + r, err := config.DB.Exec(` CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100), @@ -36,6 +36,10 @@ func setupTestDB() { age INT ); `) + fmt.Println(r.RowsAffected()) + if err != nil { + panic(err) + } } func teardownTestDB() { From a2024230efe712e03a42a55e8a0f965400a61f06 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:00:59 +0530 Subject: [PATCH 19/41] .env modified --- .env | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.env b/.env index e69de29..734e151 100644 --- a/.env +++ b/.env @@ -0,0 +1,4 @@ +DB_USER=mx +DB_NAME=crud_db +DB_HOST=localhost +DB_PORT=5432 \ No newline at end of file From 2d8cdc9a6e97ca3dc7ca6b16c3f49fa77c0d737e Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:04:59 +0530 Subject: [PATCH 20/41] fixed test case db connection issues --- models/user_test.go | 51 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/models/user_test.go b/models/user_test.go index 221cff1..b3294c4 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -3,32 +3,44 @@ package models import ( "database/sql" "fmt" + "log" "os" + "strings" "testing" "user_crud/config" + "github.com/joho/godotenv" _ "github.com/lib/pq" // PostgreSQL driver ) func setupTestDB() { + currentDir, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + dir := strings.Replace(currentDir, "/models", "", 1) + + // Load environment variables + err = godotenv.Load(dir + "/.env") + if err != nil { + log.Fatal("Error loading .env file: ", err) + } dbUser := os.Getenv("DB_USER") - dbPassword := os.Getenv("DB_PASSWORD") dbName := os.Getenv("DB_NAME") dbHost := os.Getenv("DB_HOST") dbPort := os.Getenv("DB_PORT") - dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", - dbHost, dbPort, dbUser, dbPassword, dbName) - - var err error + dsn := fmt.Sprintf("host=%s port=%s user=%s dbname=%s sslmode=disable", + dbHost, dbPort, dbUser, dbName) + fmt.Printf("%+v", dsn) config.DB, err = sql.Open("postgres", dsn) if err != nil { panic(err) } // Create a test table (optional) - r, err := config.DB.Exec(` + _, err = config.DB.Exec(` CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100), @@ -36,7 +48,7 @@ func setupTestDB() { age INT ); `) - fmt.Println(r.RowsAffected()) + // fmt.Println(r.RowsAffected()) if err != nil { panic(err) } @@ -63,6 +75,12 @@ func TestCreateUser(t *testing.T) { if err != nil || count != 1 { t.Errorf("User was not inserted into the database") } + + // Delete user + err = DeleteUser(user.ID) + if err != nil { + t.Errorf("Failed to delete user: %v", err) + } } func TestGetAllUsers(t *testing.T) { @@ -80,6 +98,14 @@ func TestGetAllUsers(t *testing.T) { if len(users) < 2 { t.Errorf("Expected at least 2 users, got %d", len(users)) } + + for _, user := range users { + // Delete user + err = DeleteUser(user.ID) + if err != nil { + t.Errorf("Failed to delete user: %v", err) + } + } } func TestGetUserByID(t *testing.T) { @@ -98,6 +124,11 @@ func TestGetUserByID(t *testing.T) { if user.Email != "david@example.com" { t.Errorf("Expected email 'david@example.com', got %s", user.Email) } + // Delete user + err = DeleteUser(id) + if err != nil { + t.Errorf("Failed to delete user: %v", err) + } } func TestUpdateUser(t *testing.T) { @@ -123,6 +154,12 @@ func TestUpdateUser(t *testing.T) { if name != "Eve Adams" || age != 30 { t.Errorf("User was not updated correctly: got name=%s, age=%d", name, age) } + + // Delete user + err = DeleteUser(id) + if err != nil { + t.Errorf("Failed to delete user: %v", err) + } } func TestDeleteUser(t *testing.T) { From 9e8313479a9a34ad1ea2dc65ddc43f84edf0bcc1 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:05:50 +0530 Subject: [PATCH 21/41] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file From 34ee1fa5a25b747a7d740595ad89d46144aafa83 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Thu, 27 Feb 2025 00:18:40 +0530 Subject: [PATCH 22/41] test case fixes --- models/user_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/models/user_test.go b/models/user_test.go index b3294c4..5d15fc4 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -28,11 +28,12 @@ func setupTestDB() { } dbUser := os.Getenv("DB_USER") dbName := os.Getenv("DB_NAME") + dbPassword := os.Getenv("DB_PASSWORD") dbHost := os.Getenv("DB_HOST") dbPort := os.Getenv("DB_PORT") - dsn := fmt.Sprintf("host=%s port=%s user=%s dbname=%s sslmode=disable", - dbHost, dbPort, dbUser, dbName) + dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", + dbHost, dbPort, dbUser, dbPassword, dbName) fmt.Printf("%+v", dsn) config.DB, err = sql.Open("postgres", dsn) if err != nil { From 9f1b77eca6b40de30c35bab7fec5f4441a513c02 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Thu, 27 Feb 2025 00:18:51 +0530 Subject: [PATCH 23/41] improvements in yml --- .github/workflows/workflow.yml | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index d7ab0fb..0f99312 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -27,34 +27,29 @@ jobs: --health-interval 5s --health-timeout 5s --health-retries 5 - + steps: - name: Checkout Code uses: actions/checkout@v4 - + - name: Set up Go uses: actions/setup-go@v5 with: go-version: 1.23.4 - + - name: Install Dependencies run: go mod tidy - + - name: Wait for PostgreSQL to Start run: sleep 10 # Ensure PostgreSQL is fully initialized - - - name: Secure PostgreSQL Credentials + + - name: Create .env file for testing run: | - PGPASSWORD=postgres psql -U postgres -d testdb -h localhost -p 5432 < .env + echo "DB_PASSWORD=postgres" >> .env + echo "DB_NAME=testdb" >> .env + echo "DB_HOST=localhost" >> .env + echo "DB_PORT=5432" >> .env + - name: Run Tests with Database - env: - DB_USER: ${{ secrets.DB_USER }} - DB_PASSWORD: ${{ secrets.DB_PASSWORD }} - DB_NAME: ${{ secrets.DB_NAME }} - DB_HOST: localhost - DB_PORT: "5432" - run: go test -v ./... + run: go test -v ./... \ No newline at end of file From 05f84900838de7dff8d16dfe613b3f5d5a640252 Mon Sep 17 00:00:00 2001 From: Moksh Solanki <46241527+mx-gp@users.noreply.github.com> Date: Thu, 27 Feb 2025 00:22:21 +0530 Subject: [PATCH 24/41] adding test cases badge for develop branch --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..eece0dd --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +[![Go Build and Test with Database](https://github.com/mx-gp/user_crud/actions/workflows/workflow.yml/badge.svg?branch=develop)](https://github.com/mx-gp/user_crud/actions/workflows/workflow.yml) From 8361ef3d36f5b914fafe43f7efb4a8e8a594f325 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 19:59:42 +0530 Subject: [PATCH 25/41] modifying main.go and moving to seperate folder --- main.go => cmd/main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename main.go => cmd/main.go (78%) diff --git a/main.go b/cmd/main.go similarity index 78% rename from main.go rename to cmd/main.go index a3aeac5..d3be97e 100644 --- a/main.go +++ b/cmd/main.go @@ -1,7 +1,8 @@ -package main +package cmd import ( "user_crud/config" + "user_crud/routes" "github.com/gin-gonic/gin" ) @@ -13,7 +14,7 @@ func main() { config.ConnectDB() // Register Routes - UserRoutes(r) + routes.UserRoutes(r) // Start Server r.Run(":8080") From 2ddb80699c1f86ba7dfe5abe2c78ba69df529bb6 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 19:59:59 +0530 Subject: [PATCH 26/41] moving routes.go --- routes.go => routes/routes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename routes.go => routes/routes.go (96%) diff --git a/routes.go b/routes/routes.go similarity index 96% rename from routes.go rename to routes/routes.go index eb94245..4a151da 100644 --- a/routes.go +++ b/routes/routes.go @@ -1,4 +1,4 @@ -package main +package routes import ( "user_crud/controllers" From a02d448ef270ba1c1082d0e3303cd632729f1cc5 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:00:35 +0530 Subject: [PATCH 27/41] refactor and moving: user_test.go --- {models => tests}/user_test.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) rename {models => tests}/user_test.go (87%) diff --git a/models/user_test.go b/tests/user_test.go similarity index 87% rename from models/user_test.go rename to tests/user_test.go index 5d15fc4..2385f70 100644 --- a/models/user_test.go +++ b/tests/user_test.go @@ -1,4 +1,4 @@ -package models +package tests import ( "database/sql" @@ -9,6 +9,8 @@ import ( "testing" "user_crud/config" + "user_crud/models" + "user_crud/repository" "github.com/joho/godotenv" _ "github.com/lib/pq" // PostgreSQL driver @@ -65,8 +67,8 @@ func TestCreateUser(t *testing.T) { setupTestDB() defer teardownTestDB() - user := User{Name: "Alice", Email: "alice@example.com", Age: 28} - err := CreateUser(user) + user := models.User{Name: "Alice", Email: "alice@example.com", Age: 28} + err := repository.CreateUser(user) if err != nil { t.Errorf("Failed to create user: %v", err) } @@ -78,7 +80,7 @@ func TestCreateUser(t *testing.T) { } // Delete user - err = DeleteUser(user.ID) + err = repository.DeleteUser(user.ID) if err != nil { t.Errorf("Failed to delete user: %v", err) } @@ -91,7 +93,7 @@ func TestGetAllUsers(t *testing.T) { // Insert test users config.DB.Exec("INSERT INTO users (name, email, age) VALUES ('Bob', 'bob@example.com', 25), ('Charlie', 'charlie@example.com', 29)") - users, err := GetAllUsers() + users, err := repository.GetAllUsers() if err != nil { t.Errorf("Failed to fetch users: %v", err) } @@ -102,7 +104,7 @@ func TestGetAllUsers(t *testing.T) { for _, user := range users { // Delete user - err = DeleteUser(user.ID) + err = repository.DeleteUser(user.ID) if err != nil { t.Errorf("Failed to delete user: %v", err) } @@ -117,7 +119,7 @@ func TestGetUserByID(t *testing.T) { var id int config.DB.QueryRow("INSERT INTO users (name, email, age) VALUES ('David', 'david@example.com', 40) RETURNING id").Scan(&id) - user, err := GetUserByID(id) + user, err := repository.GetUserByID(id) if err != nil { t.Errorf("Failed to get user by ID: %v", err) } @@ -126,7 +128,7 @@ func TestGetUserByID(t *testing.T) { t.Errorf("Expected email 'david@example.com', got %s", user.Email) } // Delete user - err = DeleteUser(id) + err = repository.DeleteUser(id) if err != nil { t.Errorf("Failed to delete user: %v", err) } @@ -141,8 +143,8 @@ func TestUpdateUser(t *testing.T) { config.DB.QueryRow("INSERT INTO users (name, email, age) VALUES ('Eve', 'eve@example.com', 22) RETURNING id").Scan(&id) // Update the user - updatedUser := User{ID: id, Name: "Eve Adams", Email: "eve@example.com", Age: 30} - err := UpdateUser(updatedUser) + updatedUser := models.User{ID: id, Name: "Eve Adams", Email: "eve@example.com", Age: 30} + err := repository.UpdateUser(updatedUser) if err != nil { t.Errorf("Failed to update user: %v", err) } @@ -157,7 +159,7 @@ func TestUpdateUser(t *testing.T) { } // Delete user - err = DeleteUser(id) + err = repository.DeleteUser(id) if err != nil { t.Errorf("Failed to delete user: %v", err) } @@ -172,7 +174,7 @@ func TestDeleteUser(t *testing.T) { config.DB.QueryRow("INSERT INTO users (name, email, age) VALUES ('Frank', 'frank@example.com', 45) RETURNING id").Scan(&id) // Delete user - err := DeleteUser(id) + err := repository.DeleteUser(id) if err != nil { t.Errorf("Failed to delete user: %v", err) } From 63db4096ac3f703b5c3dc242c48a246a2956b2ff Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:01:19 +0530 Subject: [PATCH 28/41] Repository added for seperatin db queries logic --- repository/user_repository.go | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 repository/user_repository.go diff --git a/repository/user_repository.go b/repository/user_repository.go new file mode 100644 index 0000000..044c119 --- /dev/null +++ b/repository/user_repository.go @@ -0,0 +1,52 @@ +package repository + +import ( + "user_crud/config" + "user_crud/models" +) + +// Create User +func CreateUser(user models.User) error { + _, err := config.DB.Exec("INSERT INTO users (name, email, age) VALUES ($1, $2, $3)", user.Name, user.Email, user.Age) + return err +} + +// Get All Users +func GetAllUsers() ([]models.User, error) { + rows, err := config.DB.Query("SELECT id, name, email, age FROM users") + if err != nil { + return nil, err + } + defer rows.Close() + + var users []models.User + for rows.Next() { + var user models.User + err := rows.Scan(&user.ID, &user.Name, &user.Email, &user.Age) + if err != nil { + return nil, err + } + users = append(users, user) + } + + return users, nil +} + +// Get User by ID +func GetUserByID(id int) (models.User, error) { + var user models.User + err := config.DB.QueryRow("SELECT id, name, email, age FROM users WHERE id = $1", id).Scan(&user.ID, &user.Name, &user.Email, &user.Age) + return user, err +} + +// Update User +func UpdateUser(user models.User) error { + _, err := config.DB.Exec("UPDATE users SET name=$1, email=$2, age=$3 WHERE id=$4", user.Name, user.Email, user.Age, user.ID) + return err +} + +// Delete User +func DeleteUser(id int) error { + _, err := config.DB.Exec("DELETE FROM users WHERE id = $1", id) + return err +} From 28473075e7f3d0751b46fd5338a5ae0c95c25e1e Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 19:59:42 +0530 Subject: [PATCH 29/41] adding dockerfile and docker-compose for setting up dependencies --- Dockerfile | 13 +++++++++++++ docker-compose.yml | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6b9c819 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM golang:1.21 + +WORKDIR /app + +COPY go.mod ./ +COPY go.sum ./ +RUN go mod tidy + +COPY . . + +RUN go build -o main ./cmd/main.go + +CMD ["./main"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9f2330a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +version: "3.8" + +services: + user-service: + build: . + ports: + - "8080:8080" + depends_on: + - db + env_file: + - .env + + db: + image: postgres:15 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: userdb + ports: + - "5432:5432" From a3686d3cbd4e9c6c71340d477bce62b8385d2475 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:09:06 +0530 Subject: [PATCH 30/41] refactor user controller --- controllers/user.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/controllers/user.go b/controllers/user.go index 3561acc..4b58440 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -4,6 +4,7 @@ import ( "net/http" "strconv" "user_crud/models" + "user_crud/repository" "user_crud/utils" "github.com/gin-gonic/gin" @@ -17,7 +18,7 @@ func CreateUser(c *gin.Context) { return } - err := models.CreateUser(user) + err := repository.CreateUser(user) if err != nil { utils.SendErrorResponse(c, http.StatusInternalServerError, "Failed to create user") return @@ -28,7 +29,7 @@ func CreateUser(c *gin.Context) { // Get All Users func GetAllUsers(c *gin.Context) { - users, err := models.GetAllUsers() + users, err := repository.GetAllUsers() if err != nil { utils.SendErrorResponse(c, http.StatusInternalServerError, "Failed to fetch users") return @@ -39,7 +40,7 @@ func GetAllUsers(c *gin.Context) { // Get User by ID func GetUserByID(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) - user, err := models.GetUserByID(id) + user, err := repository.GetUserByID(id) if err != nil { utils.SendErrorResponse(c, http.StatusNotFound, "User not found") return @@ -55,7 +56,7 @@ func UpdateUser(c *gin.Context) { return } - err := models.UpdateUser(user) + err := repository.UpdateUser(user) if err != nil { utils.SendErrorResponse(c, http.StatusInternalServerError, "Failed to update user") return @@ -68,7 +69,7 @@ func UpdateUser(c *gin.Context) { func DeleteUser(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) - err := models.DeleteUser(id) + err := repository.DeleteUser(id) if err != nil { utils.SendErrorResponse(c, http.StatusInternalServerError, "Failed to delete user") return From 95520930e6db31e75daf52feb33be25b736d8698 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:09:26 +0530 Subject: [PATCH 31/41] adding auth middleware which uses jwt --- middleware/auth.go | 21 +++++++++++++++++++++ utils/jwt.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 middleware/auth.go create mode 100644 utils/jwt.go diff --git a/middleware/auth.go b/middleware/auth.go new file mode 100644 index 0000000..7e8cc65 --- /dev/null +++ b/middleware/auth.go @@ -0,0 +1,21 @@ +package middleware + +import ( + "net/http" + "user_crud/utils" + + "github.com/gin-gonic/gin" +) + +// AuthMiddleware - Protect routes with JWT authentication +func AuthMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + token := c.GetHeader("Authorization") + if token == "" || !utils.ValidateJWT(token) { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) + c.Abort() + return + } + c.Next() + } +} diff --git a/utils/jwt.go b/utils/jwt.go new file mode 100644 index 0000000..8c8989e --- /dev/null +++ b/utils/jwt.go @@ -0,0 +1,39 @@ +package utils + +import ( + "errors" + "os" + "time" + + "github.com/dgrijalva/jwt-go" +) + +// Secret key (Use environment variables in production) +var jwtSecret = []byte(os.Getenv("JWT_SECRET")) + +// Claims structure +type Claims struct { + UserID uint `json:"user_id"` + jwt.StandardClaims +} + +// ValidateJWT verifies and parses the token +func ValidateJWT(tokenString string) bool { + token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, errors.New("unexpected signing method") + } + return jwtSecret, nil + }) + + if err != nil { + return false + } + + // Check if token is valid and not expired + if claims, ok := token.Claims.(*Claims); ok && token.Valid { + return claims.ExpiresAt > time.Now().Unix() + } + + return false +} From 80441d1cab111d449e6d4a05205687d0027e8481 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:09:40 +0530 Subject: [PATCH 32/41] adding middleware for ratelimit implementation --- middleware/ratelimit.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 middleware/ratelimit.go diff --git a/middleware/ratelimit.go b/middleware/ratelimit.go new file mode 100644 index 0000000..baea2a0 --- /dev/null +++ b/middleware/ratelimit.go @@ -0,0 +1,18 @@ +package middleware + +import ( + "github.com/gin-gonic/gin" + "golang.org/x/time/rate" +) + +var limiter = rate.NewLimiter(1, 5) // 1 request per second, burst up to 5 + +func RateLimit() gin.HandlerFunc { + return func(c *gin.Context) { + if !limiter.Allow() { + c.AbortWithStatusJSON(429, gin.H{"error": "Too many requests"}) + return + } + c.Next() + } +} From ad7556c063651e44539a6e45cf55b9b52e9a196d Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:09:51 +0530 Subject: [PATCH 33/41] refactor: user models --- models/user.go | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/models/user.go b/models/user.go index 7bb6639..010ae0c 100644 --- a/models/user.go +++ b/models/user.go @@ -1,56 +1,8 @@ package models -import "user_crud/config" - type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` Age int `json:"age"` } - -// Create User -func CreateUser(user User) error { - _, err := config.DB.Exec("INSERT INTO users (name, email, age) VALUES ($1, $2, $3)", user.Name, user.Email, user.Age) - return err -} - -// Get All Users -func GetAllUsers() ([]User, error) { - rows, err := config.DB.Query("SELECT id, name, email, age FROM users") - if err != nil { - return nil, err - } - defer rows.Close() - - var users []User - for rows.Next() { - var user User - err := rows.Scan(&user.ID, &user.Name, &user.Email, &user.Age) - if err != nil { - return nil, err - } - users = append(users, user) - } - - return users, nil -} - -// Get User by ID -func GetUserByID(id int) (User, error) { - var user User - err := config.DB.QueryRow("SELECT id, name, email, age FROM users WHERE id = $1", id).Scan(&user.ID, &user.Name, &user.Email, &user.Age) - return user, err -} - -// Update User -func UpdateUser(user User) error { - _, err := config.DB.Exec("UPDATE users SET name=$1, email=$2, age=$3 WHERE id=$4", user.Name, user.Email, user.Age, user.ID) - return err -} - -// Delete User -func DeleteUser(id int) error { - _, err := config.DB.Exec("DELETE FROM users WHERE id = $1", id) - return err -} From 7f38b1d61ded3ffb63788e187119614891bb13a8 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:10:09 +0530 Subject: [PATCH 34/41] updating workflow.yml according to latest changes in logic --- .github/workflows/workflow.yml | 55 ++++++++++++++++------------------ 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 0f99312..b6fb6fe 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -1,55 +1,52 @@ -name: Go Build and Test with Database +name: User Service CI on: push: branches: - - "master" - - "develop" + - master + - develop pull_request: branches: - - "master" - - "develop" - + - master + - develop + jobs: test: runs-on: ubuntu-latest + services: postgres: image: postgres:15 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres - POSTGRES_DB: testdb + POSTGRES_DB: userdb ports: - 5432:5432 options: >- - --health-cmd "pg_isready -U postgres -d testdb" - --health-interval 5s + --health-cmd pg_isready + --health-interval 10s --health-timeout 5s --health-retries 5 - + steps: - - name: Checkout Code + - name: Checkout Repository uses: actions/checkout@v4 - + - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v4 with: - go-version: 1.23.4 - + go-version: 1.21 + - name: Install Dependencies run: go mod tidy - - - name: Wait for PostgreSQL to Start - run: sleep 10 # Ensure PostgreSQL is fully initialized - - - name: Create .env file for testing - run: | - echo "DB_USER=postgres" > .env - echo "DB_PASSWORD=postgres" >> .env - echo "DB_NAME=testdb" >> .env - echo "DB_HOST=localhost" >> .env - echo "DB_PORT=5432" >> .env - - - name: Run Tests with Database - run: go test -v ./... \ No newline at end of file + + - name: Run Tests + env: + JWT_SECRET: testsecret + DB_HOST: localhost + DB_PORT: 5432 + DB_USER: postgres + DB_PASS: postgres + DB_NAME: userdb + run: go test ./tests/ -v From 9ba1c9b91800aa8a1931440690e403cd116a4877 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:10:21 +0530 Subject: [PATCH 35/41] updating go mod files --- go.mod | 2 ++ go.sum | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/go.mod b/go.mod index 354061c..7da45ba 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,11 @@ module user_crud go 1.23.4 require ( + github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-gonic/gin v1.10.0 github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 + golang.org/x/time v0.10.0 ) require ( diff --git a/go.sum b/go.sum index e9d3e92..2ec116a 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -80,6 +82,8 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= From 27706da280477b47cf66eae81f26083600fc5bab Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:14:05 +0530 Subject: [PATCH 36/41] create .env in workflow --- .github/workflows/workflow.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index b6fb6fe..3d5d13f 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -41,6 +41,15 @@ jobs: - name: Install Dependencies run: go mod tidy + - name: Create .env file for Testing # 🔹 Added step to create .env + run: | + echo "JWT_SECRET=testsecret" > .env + echo "DB_HOST=localhost" >> .env + echo "DB_PORT=5432" >> .env + echo "DB_USER=postgres" >> .env + echo "DB_PASS=postgres" >> .env + echo "DB_NAME=userdb" >> .env + - name: Run Tests env: JWT_SECRET: testsecret From e17eded9a23690c3d16808ca4645b5fb612daee9 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:17:47 +0530 Subject: [PATCH 37/41] test path --- tests/user_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/user_test.go b/tests/user_test.go index 2385f70..da1b4de 100644 --- a/tests/user_test.go +++ b/tests/user_test.go @@ -22,7 +22,7 @@ func setupTestDB() { log.Fatal(err) } dir := strings.Replace(currentDir, "/models", "", 1) - + fmt.Println("PRint: ", dir) // Load environment variables err = godotenv.Load(dir + "/.env") if err != nil { From 7a58ef9c74d806d8fb3d8cb379151c02a9ba5792 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:21:34 +0530 Subject: [PATCH 38/41] testcases path fix --- tests/user_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/user_test.go b/tests/user_test.go index da1b4de..30afa5e 100644 --- a/tests/user_test.go +++ b/tests/user_test.go @@ -21,7 +21,7 @@ func setupTestDB() { if err != nil { log.Fatal(err) } - dir := strings.Replace(currentDir, "/models", "", 1) + dir := strings.Replace(currentDir, "/tests", "", 1) fmt.Println("PRint: ", dir) // Load environment variables err = godotenv.Load(dir + "/.env") From 0f18a183e63b49e78ca0cd67b7d4814895293420 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:23:50 +0530 Subject: [PATCH 39/41] keyword fix for yml --- .github/workflows/workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 3d5d13f..01e6de0 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -47,7 +47,7 @@ jobs: echo "DB_HOST=localhost" >> .env echo "DB_PORT=5432" >> .env echo "DB_USER=postgres" >> .env - echo "DB_PASS=postgres" >> .env + echo "DB_PASSWORD=postgres" >> .env echo "DB_NAME=userdb" >> .env - name: Run Tests @@ -56,6 +56,6 @@ jobs: DB_HOST: localhost DB_PORT: 5432 DB_USER: postgres - DB_PASS: postgres + DB_PASSWORD: postgres DB_NAME: userdb run: go test ./tests/ -v From 34a3f2a64477ebae454ab50f202a3b71a279a677 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:27:26 +0530 Subject: [PATCH 40/41] removing unnecessary comments --- .github/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 01e6de0..9a17644 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -41,7 +41,7 @@ jobs: - name: Install Dependencies run: go mod tidy - - name: Create .env file for Testing # 🔹 Added step to create .env + - name: Create .env file for Testing run: | echo "JWT_SECRET=testsecret" > .env echo "DB_HOST=localhost" >> .env From bf3e82f5781eab3deea01e04a0748d18fc3c7dd2 Mon Sep 17 00:00:00 2001 From: moksh-solankipy <46241527+moksh-solankipy@users.noreply.github.com> Date: Sat, 8 Nov 2025 12:52:06 +0530 Subject: [PATCH 41/41] upgrade to 1.24 --- .gitignore | 5 ++++- go.mod | 14 ++++++++++++-- go.sum | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2eea525..65c62aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -.env \ No newline at end of file +.env +.galus.toml +go.mod +go.sum \ No newline at end of file diff --git a/go.mod b/go.mod index 7da45ba..0793674 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module user_crud -go 1.23.4 +go 1.24.4 + +toolchain go1.24.5 require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible @@ -11,29 +13,37 @@ require ( ) require ( + github.com/BurntSushi/toml v1.5.0 // indirect + github.com/aliftech/galus v0.0.0-20250726090607-302d48f29cd0 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/spf13/cobra v1.9.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.23.0 // indirect golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.20.0 // indirect + golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.15.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 2ec116a..a30cf6f 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/aliftech/galus v0.0.0-20250726090607-302d48f29cd0 h1:C8DDNoVqUMxoB+fdQVuIgRd3u8WC47VSG/Bovv3XbCU= +github.com/aliftech/galus v0.0.0-20250726090607-302d48f29cd0/go.mod h1:nElRcG5JIPLyaZOYuKKa3xCp5JErL3kqY3bdixdm74c= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= @@ -6,11 +10,16 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -30,6 +39,8 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -42,6 +53,9 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -53,6 +67,11 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6 github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -76,10 +95,13 @@ golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=