-
-
Notifications
You must be signed in to change notification settings - Fork 585
/
craftcms.go
178 lines (152 loc) · 5.58 KB
/
craftcms.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package ddevapp
import (
"fmt"
"os"
"path/filepath"
"regexp"
"github.com/ddev/ddev/pkg/archive"
"github.com/ddev/ddev/pkg/fileutil"
"github.com/ddev/ddev/pkg/nodeps"
"github.com/ddev/ddev/pkg/util"
)
// isCraftCmsApp returns true if the app is of type craftcms
func isCraftCmsApp(app *DdevApp) bool {
return fileutil.FileExists(filepath.Join(app.AppRoot, app.ComposerRoot, "craft"))
}
// craftCmsImportFilesAction defines the workflow for importing project files.
func craftCmsImportFilesAction(app *DdevApp, uploadDir, importPath, extPath string) error {
destPath := app.calculateHostUploadDirFullPath(uploadDir)
// parent of destination dir should exist
if !fileutil.FileExists(filepath.Dir(destPath)) {
return fmt.Errorf("unable to import to %s: parent directory does not exist", destPath)
}
// parent of destination dir should be writable.
if err := os.Chmod(filepath.Dir(destPath), 0755); err != nil {
return err
}
// If the destination path exists, remove it as was warned
if fileutil.FileExists(destPath) {
if err := os.RemoveAll(destPath); err != nil {
return fmt.Errorf("failed to cleanup %s before import: %v", destPath, err)
}
}
if isTar(importPath) {
if err := archive.Untar(importPath, destPath, extPath); err != nil {
return fmt.Errorf("failed to extract provided archive: %v", err)
}
return nil
}
if isZip(importPath) {
if err := archive.Unzip(importPath, destPath, extPath); err != nil {
return fmt.Errorf("failed to extract provided archive: %v", err)
}
return nil
}
//nolint: revive
if err := fileutil.CopyDir(importPath, destPath); err != nil {
return err
}
return nil
}
// Set up the .env file for ddev
func craftCmsPostStartAction(app *DdevApp) error {
// If settings management is disabled, do nothing
if app.DisableSettingsManagement {
return nil
}
// Check version is v4 or higher or warn user about app type mismatch.
if !isCraftCms4orHigher(app) {
util.Warning("It looks like the installed Craft CMS is lower than version 4 where it's recommended to use project type `php` or disable settings management with `ddev config --disable-settings-management`")
if !util.Confirm("Would you like to stop here, not do the automatic configuration and change project type?") {
return nil
}
}
// If the .env file doesn't exist, try to create it by copying .env.example to .env
envFilePath := filepath.Join(app.AppRoot, app.ComposerRoot, ".env")
if !fileutil.FileExists(envFilePath) {
var exampleEnvFilePaths = []string{".env.example", ".env.example.dev"}
for _, envFileName := range exampleEnvFilePaths {
exampleEnvFilePath := filepath.Join(app.AppRoot, app.ComposerRoot, envFileName)
if fileutil.FileExists(exampleEnvFilePath) {
util.Success(fmt.Sprintf("Copied %s to .env", envFileName))
err := fileutil.CopyFile(exampleEnvFilePath, envFilePath)
if err != nil {
util.Error(fmt.Sprintf("Error copying %s to .env", exampleEnvFilePath))
return err
}
}
}
}
// If the .env file *still* doesn't exist, return early
if !fileutil.FileExists(envFilePath) {
return nil
}
// Read in the .env file
envMap, envText, err := ReadProjectEnvFile(envFilePath)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("unable to read .env file: %v", err)
}
port := "3306"
driver := "mysql"
if app.Database.Type == nodeps.Postgres {
driver = "pgsql"
port = "5432"
}
// If they have older version of .env with DB_DRIVER, DB_SERVER etc, use those
if _, ok := envMap["DB_SERVER"]; ok {
// TODO: Remove, was never an official standard of Craft CMS.
envMap = map[string]string{
"DB_DRIVER": driver,
"DB_SERVER": "db",
"DB_PORT": port,
"DB_DATABASE": "db",
"DB_USER": "db",
"DB_PASSWORD": "db",
"MAILPIT_SMTP_HOSTNAME": "127.0.0.1",
"MAILPIT_SMTP_PORT": "1025",
"PRIMARY_SITE_URL": app.GetPrimaryURL(),
}
} else {
// Otherwise use the current CRAFT_DB_SERVER etc.
envMap = map[string]string{
"CRAFT_DB_DRIVER": driver,
"CRAFT_DB_SERVER": "db",
"CRAFT_DB_PORT": port,
"CRAFT_DB_DATABASE": "db",
"CRAFT_DB_USER": "db",
"CRAFT_DB_PASSWORD": "db",
"CRAFT_WEB_ROOT": app.GetAbsDocroot(true),
"MAILPIT_SMTP_HOSTNAME": "127.0.0.1",
"MAILPIT_SMTP_PORT": "1025",
"PRIMARY_SITE_URL": app.GetPrimaryURL(),
}
}
err = WriteProjectEnvFile(envFilePath, envMap, envText)
if err != nil {
return err
}
return nil
}
func craftCmsConfigOverrideAction(app *DdevApp) error {
app.Database = DatabaseDesc{nodeps.MySQL, nodeps.MySQL80}
return nil
}
// isCraftCms4orHigher returns true if the Craft CMS version is 4 or higher. The
// proper detection will fail if the vendor folder location is changed in the
// composer.json.
// The detection is based on a change starting with 4.0.0-RC1 where deprecated
// constants were removed in src/Craft.php see
// https://github.com/craftcms/cms/commit/1660ff90a3a69cec425271d47ade66523a4bd44e#diff-21e22a30e7c48265a4dcedc1b1c8b9372eca5d3fdeff6d72c7d9c6b671365c56
func isCraftCms4orHigher(app *DdevApp) bool {
craftFilePath := filepath.Join(app.GetComposerRoot(false, false), "vendor", "craftcms", "cms", "src", "Craft.php")
if !fileutil.FileExists(craftFilePath) {
// Sources are not installed, assuming v4 or higher.
return true
}
craftFileContent, err := fileutil.ReadFileIntoString(craftFilePath)
if err != nil {
util.Warning("unable to read file `%s` in project `%s`: %v", craftFilePath, app.Name, err)
return true
}
return !regexp.MustCompile(`const\s+Personal\s*=\s*0`).MatchString(craftFileContent)
}