Skip to content

Commit

Permalink
Structural refactor as I work on better mocks for the site package
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisWiegman committed Jun 15, 2024
1 parent dc59c55 commit ab8dec0
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 145 deletions.
11 changes: 11 additions & 0 deletions internal/site/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,17 @@ func (s *Site) getDatabaseContainer(databaseDir string, appContainers []docker.C
return appContainers
}

func (s *Site) getDatabaseDirectory() (databaseDirectory string, err error) {
databaseDirectory = filepath.Join(s.Settings.SiteDirectory, "database")

err = os.MkdirAll(databaseDirectory, os.FileMode(defaultDirPermissions))
if err != nil {
return "", err
}

return databaseDirectory, err
}

// getDatabasePort returns the public port for the database attached to the current site.
func (s *Site) getDatabasePort() string {
containers, _ := s.dockerClient.ContainerList(s.Settings.Name)
Expand Down
68 changes: 0 additions & 68 deletions internal/site/detect.go

This file was deleted.

41 changes: 41 additions & 0 deletions internal/site/helpers.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package site

import (
"context"
"crypto/tls"
"fmt"
"io"
"net/http"
"os"
"strings"

Expand All @@ -20,6 +23,43 @@ func arrayContains(array []string, name string) bool {
return false
}

// checkStatusCode returns true on 200 or false.
func checkStatusCode(checkURL string) (bool, error) {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, checkURL, http.NoBody)
if err != nil {
return false, err
}

// Ignore SSL check as we're using our self-signed cert for development
clientTransport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //nolint:gosec
}

client := &http.Client{
Transport: clientTransport,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}

resp, err := client.Do(req)
if err != nil {
return false, err
}

defer func() {
if err := resp.Body.Close(); err != nil {
panic(err)
}
}()

if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusFound {
return true, nil
}

return false, nil
}

// copyFile Copies a file on the user's host from one place to another.
func copyFile(src, dest string) error {
srcStat, err := os.Stat(src)
Expand Down Expand Up @@ -57,6 +97,7 @@ func copyFile(src, dest string) error {
return err
}

// handleImageError Handles errors related to image detection and provides more helpful error messages.
func (s *Site) handleImageError(container *docker.ContainerConfig, err error) error {
if strings.Contains(err.Error(), "manifest unknown") {
switch container.Labels["kana.type"] {
Expand Down
116 changes: 83 additions & 33 deletions internal/site/site.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package site

import (
"context"
"crypto/tls"
"bufio"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"net/http"
"io"
"net/url"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"time"

"github.com/ChrisWiegman/kana/internal/console"
"github.com/ChrisWiegman/kana/internal/docker"
"github.com/ChrisWiegman/kana/internal/helpers"
"github.com/ChrisWiegman/kana/internal/settings"

"github.com/pkg/browser"
Expand All @@ -35,10 +36,67 @@ type SiteInfo struct {
Running bool
}

var maxVerificationRetries = 30
const DefaultType = "site"

var maxVerificationRetries = 30
var execCommand = exec.Command

// DetectType determines the type of site in the working directory.
func (s *Site) DetectType() (string, error) {
var err error
var isSite bool

isSite, err = helpers.PathExists(filepath.Join(s.Settings.WorkingDirectory, "wp-includes", "version.php"))
if err != nil {
return "", err
}

if isSite {
return DefaultType, err
}

items, _ := os.ReadDir(s.Settings.WorkingDirectory)

for _, item := range items {
if item.IsDir() {
continue
}

if item.Name() == "style.css" || filepath.Ext(item.Name()) == ".php" {
var f *os.File
var line string

f, err = os.Open(filepath.Join(s.Settings.WorkingDirectory, item.Name()))
if err != nil {
return "", err
}

reader := bufio.NewReader(f)
line, err = helpers.ReadLine(reader)

for err == nil {
exp := regexp.MustCompile(`(Plugin|Theme) Name: .*`)

for _, match := range exp.FindAllStringSubmatch(line, -1) {
if match[1] == "Theme" {
return "theme", err //nolint
} else {
return "plugin", err //nolint
}
}
line, err = helpers.ReadLine(reader)
}
}
}

// We don't care if it is an empty folder.
if err == io.EOF {
err = nil
}

return DefaultType, err
}

// EnsureDocker Ensures Docker is available for commands that need it.
func (s *Site) EnsureDocker(consoleOutput *console.Console) error {
// Add a docker client to the site
Expand Down Expand Up @@ -382,41 +440,19 @@ func (s *Site) StopSite() error {
return s.maybeStopTraefik()
}

// checkStatusCode returns true on 200 or false.
func checkStatusCode(checkURL string) (bool, error) {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, checkURL, http.NoBody)
// getDirectories Returns the correct appDir and databaseDir for the current site.
func (s *Site) getDirectories() (wordPressDirectory, databaseDir string, err error) {
wordPressDirectory, err = s.getWordPressDirectory()
if err != nil {
return false, err
return "", "", err
}

// Ignore SSL check as we're using our self-signed cert for development
clientTransport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //nolint:gosec
}

client := &http.Client{
Transport: clientTransport,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}

resp, err := client.Do(req)
databaseDir, err = s.getDatabaseDirectory()
if err != nil {
return false, err
return "", "", err
}

defer func() {
if err := resp.Body.Close(); err != nil {
panic(err)
}
}()

if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusFound {
return true, nil
}

return false, nil
return wordPressDirectory, databaseDir, err
}

// getRunningConfig gets various options that were used to start the site.
Expand Down Expand Up @@ -548,6 +584,20 @@ func (s *Site) runCli(command string, restart, root bool) (docker.ExecResult, er
return output, nil
}

// startContainer Starts a given container configuration.
func (s *Site) startContainer(container *docker.ContainerConfig, randomPorts, localUser bool, consoleOutput *console.Console) error {
err := s.dockerClient.EnsureImage(container.Image, s.Settings.ImageUpdateDays, consoleOutput)
if err != nil {
err = s.handleImageError(container, err)
if err != nil {
return err
}
}
_, err = s.dockerClient.ContainerRun(container, randomPorts, localUser)

return err
}

// verifySite verifies if a site is up and running without error.
func (s *Site) verifySite(siteURL string) error {
// Setup other options generated from config items
Expand Down
Loading

0 comments on commit ab8dec0

Please sign in to comment.