🚧 This instance is under construction; expect occasional downtime. Runners available in /repos. Questions? Ask in #wikimedia-gitlab on libera.chat, or under GitLab on Phabricator.

Commit 18545f5c authored by Addshore's avatar Addshore 🏄
Browse files

Refactor mwdd mw dir selection

parent d43d6712
......@@ -22,7 +22,6 @@ import (
"os"
"os/signal"
"os/user"
"path/filepath"
"strings"
"syscall"
"time"
......@@ -30,6 +29,7 @@ import (
"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/exec"
"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/mediawiki"
"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/mwdd"
"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/util/paths"
"github.com/briandowns/spinner"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
......@@ -49,43 +49,15 @@ var mwddMediawikiCmd = &cobra.Command{
usrDir := usr.HomeDir
if mwdd.Env().Missing("MEDIAWIKI_VOLUMES_CODE") {
// Try to autodetect if we are in a MediaWiki directory at all
suggestedMwDir, err := os.Getwd()
if err != nil {
panic(err)
}
for {
_, checkError := mediawiki.ForDirectory(suggestedMwDir)
if checkError == nil {
break
}
suggestedMwDir = filepath.Dir(suggestedMwDir)
if suggestedMwDir == "/" {
suggestedMwDir = "~/dev/git/gerrit/mediawiki/core"
break
}
}
// Prompt the user for a directory or confirmation
dirPrompt := promptui.Prompt{
Label: "What directory would you like to store MediaWiki source code in?",
Default: suggestedMwDir,
Default: mediawiki.GuessMediaWikiDirectoryBasedOnContext(),
}
value, err := dirPrompt.Run()
// Deal with people entering ~/ paths and them not be handled
if value == "~" {
// In case of "~", which won't be caught by the "else if"
value = usrDir
} else if strings.HasPrefix(value, "~/") {
// Use strings.HasPrefix so we don't match paths like
// "/something/~/something/"
value = filepath.Join(usrDir, value[2:])
}
if err == nil {
mwdd.Env().Set("MEDIAWIKI_VOLUMES_CODE", value)
mwdd.Env().Set("MEDIAWIKI_VOLUMES_CODE", paths.FullifyUserProvidedPath(value))
} else {
fmt.Println("Can't continue without a MediaWiki code directory")
os.Exit(1)
......
/*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 (
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
/*NotMediaWikiDirectory error when a directory appears to not contain MediaWiki code*/
type NotMediaWikiDirectory struct {
directory string
}
func (e *NotMediaWikiDirectory) Error() string {
return e.directory + " doesn't look like a MediaWiki directory"
}
/*GuessMediaWikiDirectoryBasedOnContext ...*/
func GuessMediaWikiDirectoryBasedOnContext() string {
suggestedMwDir, err := os.Getwd()
if err != nil {
panic(err)
}
for {
// Check if the current directory looks like core
_, checkError := ForDirectory(suggestedMwDir)
if checkError == nil {
// If it does look like core, break out of the loop
break
}
// Otherwise, get the parent directory to try with
suggestedMwDir = filepath.Dir(suggestedMwDir)
if suggestedMwDir == "/" {
// But if we reach the root level, then provide some sensible default
suggestedMwDir = "~/git/gerrit/mediawiki/core"
break
}
}
return suggestedMwDir
}
/*ForDirectory returns a MediaWiki for the current working directory*/
func ForDirectory(directory string) (MediaWiki, error) {
return MediaWiki(directory), errorIfDirectoryDoesNotLookLikeCore(directory)
}
/*ForCurrentWorkingDirectory returns a MediaWiki for the current working directory*/
func ForCurrentWorkingDirectory() (MediaWiki, error) {
currentWorkingDirectory, _ := os.Getwd()
return ForDirectory(currentWorkingDirectory)
}
/*CheckIfInCoreDirectory checks that the current working directory looks like a MediaWiki directory*/
func CheckIfInCoreDirectory() {
_, err := ForCurrentWorkingDirectory()
if err != nil {
log.Fatal("❌ Please run this command within the root of the MediaWiki core repository.")
}
}
func errorIfDirectoryMissingGitReviewForProject(directory string, expectedProject string) error {
b, err := ioutil.ReadFile(directory + string(os.PathSeparator) + ".gitreview")
if err != nil || !strings.Contains(string(b), "project="+expectedProject) {
return &NotMediaWikiDirectory{directory}
}
return nil
}
func errorIfDirectoryDoesNotLookLikeCore(directory string) error {
return errorIfDirectoryMissingGitReviewForProject(directory, "mediawiki/core")
}
......@@ -20,7 +20,6 @@ package mediawiki
import (
"fmt"
"io/ioutil"
"log"
"os"
osexec "os/exec"
"strings"
......@@ -31,50 +30,6 @@ import (
/*MediaWiki representation of a MediaWiki install directory*/
type MediaWiki string
/*NotMediaWikiDirectory error when a directory appears to not contain MediaWiki code*/
type NotMediaWikiDirectory struct {
directory string
}
func (e *NotMediaWikiDirectory) Error() string {
return e.directory + " doesn't look like a MediaWiki directory"
}
/*ForDirectory returns a MediaWiki for the current working directory*/
func ForDirectory(directory string) (MediaWiki, error) {
return MediaWiki(directory), errorIfDirectoryDoesNotLookLikeCore(directory)
}
/*ForCurrentWorkingDirectory returns a MediaWiki for the current working directory*/
func ForCurrentWorkingDirectory() (MediaWiki, error) {
currentWorkingDirectory, _ := os.Getwd()
return ForDirectory(currentWorkingDirectory)
}
/*CheckIfInCoreDirectory checks that the current working directory looks like a MediaWiki directory*/
func CheckIfInCoreDirectory() {
_, err := ForCurrentWorkingDirectory()
if err != nil {
log.Fatal("❌ Please run this command within the root of the MediaWiki core repository.")
}
}
func errorIfDirectoryMissingGitReviewForProject(directory string, expectedProject string) error {
b, err := ioutil.ReadFile(directory + string(os.PathSeparator) + ".gitreview")
if err != nil || !strings.Contains(string(b), "project="+expectedProject) {
return &NotMediaWikiDirectory{directory}
}
return nil
}
func errorIfDirectoryDoesNotLookLikeCore(directory string) error {
return errorIfDirectoryMissingGitReviewForProject(directory, "mediawiki/core")
}
func errorIfDirectoryDoesNotLookLikeVector(directory string) error {
return errorIfDirectoryMissingGitReviewForProject(directory, "mediawiki/skins/Vector")
}
/*Directory the directory containing MediaWiki*/
func (m MediaWiki) Directory() string {
return string(m)
......@@ -90,6 +45,10 @@ func (m MediaWiki) MediaWikiIsPresent() bool {
return errorIfDirectoryDoesNotLookLikeCore(m.Directory()) == nil
}
func errorIfDirectoryDoesNotLookLikeVector(directory string) error {
return errorIfDirectoryMissingGitReviewForProject(directory, "mediawiki/skins/Vector")
}
/*VectorIsPresent ...*/
func (m MediaWiki) VectorIsPresent() bool {
return errorIfDirectoryDoesNotLookLikeVector(m.Path("skins/Vector")) == nil
......
/*Package paths in internal utils is functionality for interacting with paths in generic ways
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 paths
import (
"os/user"
"path/filepath"
"strings"
)
/*FullifyUserProvidedPath fullify people entering ~/ paths and them not being handeled anywhere*/
func FullifyUserProvidedPath(userProvidedPath string) string {
usr, _ := user.Current()
usrDir := usr.HomeDir
if userProvidedPath == "~" {
return usrDir
}
if strings.HasPrefix(userProvidedPath, "~/") {
return filepath.Join(usrDir, userProvidedPath[2:])
}
// Fallback to what we were provided
return userProvidedPath
}
/*Package paths in internal utils is functionality for interacting with paths in generic ways
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 paths
import (
"os/user"
"testing"
)
func TestFullifyUserProvidedPath(t *testing.T) {
usr, _ := user.Current()
usrDir := usr.HomeDir
tests := []struct {
name string
given string
want string
}{
{
name: "Passthrough",
given: "/foo",
want: "/foo",
},
{
name: "User dir 1",
given: "~",
want: usrDir,
},
{
name: "User dir 2",
given: "~/",
want: usrDir,
},
{
name: "User sub dir",
given: "~/foo",
want: usrDir + "/foo",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := FullifyUserProvidedPath(tt.given); got != tt.want {
t.Errorf("FullifyUserProvidedPath() = %v, want %v", got, tt.want)
}
})
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment