root.go 5.72 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*Package mediawiki is used to interact with MediaWiki

Copyright © 2020 Addshore

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package mediawiki

import (
21
	"fmt"
22
	"io/ioutil"
23
	"log"
24
	"os"
Addshore's avatar
Addshore committed
25
	osexec "os/exec"
26
27
	"strings"

28
29
30
	"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/exec"
)

31
32
/*MediaWiki representation of a MediaWiki install directory*/
type MediaWiki string
33

34
35
36
37
/*NotMediaWikiDirectory error when a directory appears to not contain MediaWiki code*/
type NotMediaWikiDirectory struct {
	directory string
}
Addshore's avatar
Addshore committed
38

39
40
func (e *NotMediaWikiDirectory) Error() string {
	return e.directory + " doesn't look like a MediaWiki directory"
41
42
}

43
/*ForDirectory returns a MediaWiki for the current working directory*/
Addshore's avatar
Addshore committed
44
func ForDirectory(directory string) (MediaWiki, error) {
45
46
47
	return MediaWiki(directory), errorIfDirectoryDoesNotLookLikeCore(directory)
}

48
49
/*ForCurrentWorkingDirectory returns a MediaWiki for the current working directory*/
func ForCurrentWorkingDirectory() (MediaWiki, error) {
50
	currentWorkingDirectory, _ := os.Getwd()
51
	return ForDirectory(currentWorkingDirectory)
52
53
}

54
55
/*CheckIfInCoreDirectory checks that the current working directory looks like a MediaWiki directory*/
func CheckIfInCoreDirectory() {
56
57
	_, err := ForCurrentWorkingDirectory()
	if err != nil {
58
59
60
61
		log.Fatal("❌ Please run this command within the root of the MediaWiki core repository.")
	}
}

62
func errorIfDirectoryMissingGitReviewForProject(directory string, expectedProject string) error {
63
	b, err := ioutil.ReadFile(directory + string(os.PathSeparator) + ".gitreview")
64
	if err != nil || !strings.Contains(string(b), "project="+expectedProject) {
65
		return &NotMediaWikiDirectory{directory}
66
	}
67
	return nil
68
69
}

70
func errorIfDirectoryDoesNotLookLikeCore(directory string) error {
Addshore's avatar
Addshore committed
71
	return errorIfDirectoryMissingGitReviewForProject(directory, "mediawiki/core")
72
73
74
}

func errorIfDirectoryDoesNotLookLikeVector(directory string) error {
Addshore's avatar
Addshore committed
75
	return errorIfDirectoryMissingGitReviewForProject(directory, "mediawiki/skins/Vector")
76
77
}

78
79
80
/*Directory the directory containing MediaWiki*/
func (m MediaWiki) Directory() string {
	return string(m)
81
82
}

83
84
/*Path within the MediaWiki directory*/
func (m MediaWiki) Path(subPath string) string {
85
86
87
	return m.Directory() + string(os.PathSeparator) + subPath
}

88
89
/*MediaWikiIsPresent ...*/
func (m MediaWiki) MediaWikiIsPresent() bool {
90
91
92
93
94
95
	return errorIfDirectoryDoesNotLookLikeCore(m.Directory()) == nil
}

/*VectorIsPresent ...*/
func (m MediaWiki) VectorIsPresent() bool {
	return errorIfDirectoryDoesNotLookLikeVector(m.Path("skins/Vector")) == nil
96
97
}

Addshore's avatar
Addshore committed
98
99
100
101
102
103
104
105
func exitIfNoGit() {
	_, err := osexec.LookPath("git")
	if err != nil {
		fmt.Println("You must have git installed on your system.")
		os.Exit(1)
	}
}

106
/*CloneSetupOpts for use with GithubCloneMediaWiki*/
Addshore's avatar
Addshore committed
107
108
109
110
111
type CloneSetupOpts = struct {
	GetMediaWiki          bool
	GetVector             bool
	UseGithub             bool
	UseShallow            bool
112
	GerritInteractionType string
Addshore's avatar
Addshore committed
113
114
	GerritUsername        string
	Options               exec.HandlerOptions
115
116
117
118
}

/*CloneSetup provides a packages initial setup method for MediaWiki and Vector with some speedy features*/
func (m MediaWiki) CloneSetup(options CloneSetupOpts) {
Addshore's avatar
Addshore committed
119
120
	exitIfNoGit()

121
122
	startRemoteCore := "https://gerrit.wikimedia.org/r/mediawiki/core"
	startRemoteVector := "https://gerrit.wikimedia.org/r/mediawiki/skins/Vector"
Addshore's avatar
Addshore committed
123
	if options.UseGithub {
124
125
126
		startRemoteCore = "https://github.com/wikimedia/mediawiki.git"
		startRemoteVector = "https://github.com/wikimedia/Vector.git"
	}
127

Addshore's avatar
Addshore committed
128
129
130
	endRemoteCore := ""
	endRemoteVector := ""
	if options.GerritInteractionType == "http" {
131
132
		endRemoteCore = "https://gerrit.wikimedia.org/r/mediawiki/core"
		endRemoteVector = "https://gerrit.wikimedia.org/r/mediawiki/skins/Vector"
Addshore's avatar
Addshore committed
133
	} else if options.GerritInteractionType == "ssh" {
134
135
136
		endRemoteCore = "ssh://" + options.GerritUsername + "@gerrit.wikimedia.org:29418/mediawiki/core"
		endRemoteVector = "ssh://" + options.GerritUsername + "@gerrit.wikimedia.org:29418/mediawiki/skins/Vector"
	} else {
Addshore's avatar
Addshore committed
137
138
		fmt.Println("Unknown GerritInteractionType")
		os.Exit(1)
139
	}
140

141
	shallowOptions := ""
Addshore's avatar
Addshore committed
142
	if options.UseShallow {
143
144
145
		shallowOptions = "--depth=1"
	}

Addshore's avatar
Addshore committed
146
	if options.GetMediaWiki {
147
		exec.RunTTYCommand(options.Options, exec.Command(
148
149
150
151
152
			"git",
			"clone",
			shallowOptions,
			startRemoteCore,
			m.Path("")))
Addshore's avatar
Addshore committed
153
		if startRemoteCore != endRemoteCore {
154
			exec.RunTTYCommand(options.Options, exec.Command(
155
156
157
158
159
160
161
162
				"git",
				"-C", m.Path(""),
				"remote",
				"set-url",
				"origin",
				endRemoteCore))
		}
	}
Addshore's avatar
Addshore committed
163
	if options.GetVector {
164
		exec.RunTTYCommand(options.Options, exec.Command(
165
166
167
168
169
			"git",
			"clone",
			shallowOptions,
			startRemoteVector,
			m.Path("skins/Vector")))
Addshore's avatar
Addshore committed
170
171
172
173
174
175
176
177
178
		if startRemoteCore != endRemoteCore {
			exec.RunTTYCommand(options.Options, exec.Command(
				"git",
				"-C", m.Path("skins/Vector"),
				"remote",
				"set-url",
				"origin",
				endRemoteVector))
		}
179
180
181
	}
}

182
183
/*LocalSettingsIsPresent ...*/
func (m MediaWiki) LocalSettingsIsPresent() bool {
184
	info, err := os.Stat(m.Path("LocalSettings.php"))
185
186
187
188
189
190
	if os.IsNotExist(err) {
		return false
	}
	return !info.IsDir()
}

191
/*LocalSettingsContains ...*/
Addshore's avatar
Addshore committed
192
193
194
195
196
197
func (m MediaWiki) LocalSettingsContains(text string) bool {
	b, err := ioutil.ReadFile(m.Path("LocalSettings.php"))
	if err != nil {
		panic(err)
	}
	s := string(b)
198
199
200
	return strings.Contains(s, text)

}