Skip to content

Commit

Permalink
🗑️ Add delete-app command (#24)
Browse files Browse the repository at this point in the history
#### Summary
This PR introduces a new command `delete-app` to the
[`boneless`](command:_github.copilot.openSymbolFromReferences?%5B%22%22%2C%5B%7B%22uri%22%3A%7B%22scheme%22%3A%22file%22%2C%22authority%22%3A%22%22%2C%22path%22%3A%22%2FUsers%2Fdavidgaspar%2FProjects%2Fgo%2Fboneless%2Fdata%2Ftest.patch%22%2C%22query%22%3A%22%22%2C%22fragment%22%3A%22%22%7D%2C%22pos%22%3A%7B%22line%22%3A0%2C%22character%22%3A17%7D%7D%5D%2C%2296d72e6a-b414-40fb-bff7-8c09cf3044eb%22%5D
"Go to definition") CLI tool, allowing users to delete an existing app.
The command ensures that critical components like
[`app`](command:_github.copilot.openSymbolFromReferences?%5B%22%22%2C%5B%7B%22uri%22%3A%7B%22scheme%22%3A%22file%22%2C%22authority%22%3A%22%22%2C%22path%22%3A%22%2FUsers%2Fdavidgaspar%2FProjects%2Fgo%2Fboneless%2Fdata%2Ftest.patch%22%2C%22query%22%3A%22%22%2C%22fragment%22%3A%22%22%7D%2C%22pos%22%3A%7B%22line%22%3A5%2C%22character%22%3A12%7D%7D%5D%2C%2296d72e6a-b414-40fb-bff7-8c09cf3044eb%22%5D
"Go to definition") and
[`bff`](command:_github.copilot.openSymbolFromReferences?%5B%22%22%2C%5B%7B%22uri%22%3A%7B%22scheme%22%3A%22file%22%2C%22authority%22%3A%22%22%2C%22path%22%3A%22%2FUsers%2Fdavidgaspar%2FProjects%2Fgo%2Fboneless%2Fdata%2Ftest.patch%22%2C%22query%22%3A%22%22%2C%22fragment%22%3A%22%22%7D%2C%22pos%22%3A%7B%22line%22%3A72%2C%22character%22%3A17%7D%7D%5D%2C%2296d72e6a-b414-40fb-bff7-8c09cf3044eb%22%5D
"Go to definition") cannot be deleted.

#### Changes
1. **Command Addition in `main.go`:**
   - Added `delete-app` to the list of available commands.
   - Updated the help text to include the new `delete-app` command.
- Implemented the `delete-app` command logic in the
[`main`](command:_github.copilot.openSymbolFromReferences?%5B%22%22%2C%5B%7B%22uri%22%3A%7B%22scheme%22%3A%22file%22%2C%22authority%22%3A%22%22%2C%22path%22%3A%22%2FUsers%2Fdavidgaspar%2FProjects%2Fgo%2Fboneless%2Fdata%2Ftest.patch%22%2C%22query%22%3A%22%22%2C%22fragment%22%3A%22%22%7D%2C%22pos%22%3A%7B%22line%22%3A0%2C%22character%22%3A26%7D%7D%5D%2C%2296d72e6a-b414-40fb-bff7-8c09cf3044eb%22%5D
"Go to definition") function.

2. **New File `delete.go`:**
   - Created a new file `delete.go` in the `internal` package.
- Implemented the [`DeleteApp`] function to handle the deletion of app
folders.
   - Added helper functions:
- [`validateAppName`]: Ensures critical components cannot be deleted.
- [`checkIfAppFolderExists`]: Checks if the app folder exists before
attempting deletion.
- [`getAppFolderPath`]: Constructs the path to the app folder based on
the app name.

#### Usage
- **Command:** `boneless delete-app <app-name>`
- **Example:** `boneless delete-app my-app`

This command will delete the specified app folder if it exists and is
not a critical component.

#### Testing
- Verified that the `delete-app` command correctly deletes existing app
folders.
- Ensured that attempting to delete [`app`] or [`bff`] results in an
appropriate error message and no deletion occurs.
- Checked that non-existent app folders produce a "not found" error
message.

#### Notes
- This feature enhances the usability of the [`boneless`] CLI by
providing a straightforward way to remove apps that are no longer
needed.
- Future improvements could include additional validation or
confirmation prompts before deletion.
  • Loading branch information
renanbastos93 authored Oct 25, 2024
2 parents 981cf07 + dddfb1c commit c519eb2
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Go

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: '^1.20'

- name: Install dependencies
run: go mod tidy

- name: Run tests for delete command
run: go test ./internal/delete* -v
5 changes: 5 additions & 0 deletions cmd/boneless/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Targets:
migrate <app-name> <up|down> Run migrations for an app
create-app <app-name> Create a new app based on a template
build-app <app-name> Build an app using Weaver and SQLC
delete-app <app-name> Delete an app created
run Run the project using Weaver
Parameters:
Expand All @@ -37,6 +38,7 @@ Examples:
boneless migrate my-app up
boneless create-app my-app
boneless build-app my-app
boneless delete-app my-app
boneless run
`
Expand All @@ -51,6 +53,7 @@ const (
cmdMigrate = "migrate"
cmdCreateApp = "create-app"
cmdBuildApp = "build-app"
cmdDeleteApp = "delete-app"
cmdRun = "run"

DefaultComponentName = "app"
Expand Down Expand Up @@ -83,6 +86,8 @@ func main() {
internal.Build(flag.Arg(1), internal.KindComponent, "")
internal.SqlcGenerate(flag.Arg(1))
internal.WeaverGenerate()
case cmdDeleteApp:
internal.DeleteApp(flag.Arg(1))
case cmdBuild:
internal.SqlcGenerate()
internal.WeaverGenerate()
Expand Down
54 changes: 54 additions & 0 deletions internal/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package internal

import (
"fmt"
"os"
)

func DeleteApp(appName string) {
if isValid := isAppNameValid(appName); !isValid {
return
}

appFolderPath := getAppFolderPath(appName)
if exists := folderExists(appFolderPath); !exists {
return
}

// Delete the app folder
if err := os.RemoveAll(appFolderPath); err != nil {
panic("Error deleting app folder: " + err.Error())
}

fmt.Printf("App deleted successfully: %s\n", appName)
}

func isAppNameValid(appName string) bool {
if appName == "app" {
fmt.Println("You can't delete the app folder: it's the example component")
return false
}

if appName == "bff" {
fmt.Println("You can't delete the bff folder: it's required to run the application")
return false
}

return true
}

func folderExists(pathToDelete string) bool {
if _, err := os.Stat(pathToDelete); err != nil {
if os.IsNotExist(err) {
fmt.Println("App folder not found")
return false
}

panic("Error checking app folder: " + err.Error())
}
return true
}

func getAppFolderPath(appName string) string {
return fmt.Sprintf("internal/%s", appName)
}
83 changes: 83 additions & 0 deletions internal/delete_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package internal

import (
"bytes"
"io"
"os"
"path/filepath"
"testing"
)

func TestDeleteApp(t *testing.T) {
tmpDir := t.TempDir()
appName := "test-app"
appFolderPath := filepath.Join(tmpDir, "internal", appName)

t.Log("tmpDir: ", tmpDir)

// Create a temporary app folder
if err := os.MkdirAll(appFolderPath, 0755); err != nil {
t.Fatalf("Failed to create app folder: %v", err)
}

// Change the working directory to the temporary directory
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("Failed to change directory: %v", err)
}

// Call DeleteApp
DeleteApp(appName)

// Verify the app folder has been deleted
if _, err := os.Stat(appFolderPath); !os.IsNotExist(err) {
t.Fatalf("App folder was not deleted")
}
}

func TestDeleteApp_NotFound(t *testing.T) {
tmpDir := t.TempDir()
appName := "test-app"

// Change the working directory to the temporary directory
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("Failed to change directory: %v", err)
}

// Save the current stdout
originalStdout := os.Stdout

// Create a buffer to capture the output
r, w, _ := os.Pipe()
os.Stdout = w

DeleteApp(appName)

// Restore the original stdout and close the writer
w.Close()
os.Stdout = originalStdout

// Read the captured output
var buf bytes.Buffer
io.Copy(&buf, r)

if buf.String() != "App folder not found\n" {
t.Fatalf("Unexpected output: %s", buf.String())
}
}

func TestDeleteApp_ErrorDeleting(t *testing.T) {
tmpDir := t.TempDir()

// Change the working directory to the temporary directory
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("Failed to change directory: %v", err)
}

// Call DeleteApp and expect a panic
defer func() {
if r := recover(); r == nil {
t.Fatalf("Expected panic but did not occur")
}
}()
DeleteApp("\x00")
}

0 comments on commit c519eb2

Please sign in to comment.