Commit 61f0bfb1 authored by Addshore's avatar Addshore 🏄
Browse files

dev: Check that the PORT can be listened on

Bug: T282352 (#282352)
parent ee98bdbd
...@@ -18,13 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -18,13 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package cmd package cmd
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"strconv"
"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/exec" "gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/exec"
"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/mwdd" "gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/mwdd"
"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/util/ports"
"github.com/manifoldco/promptui" "github.com/manifoldco/promptui"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
...@@ -38,18 +37,9 @@ var mwddCmd = &cobra.Command{ ...@@ -38,18 +37,9 @@ var mwddCmd = &cobra.Command{
mwdd.EnsureReady() mwdd.EnsureReady()
if mwdd.Env().Missing("PORT") { if mwdd.Env().Missing("PORT") {
prompt := promptui.Prompt{ prompt := promptui.Prompt{
Label: "What port would you like to use for your development environment?", Label: "What port would you like to use for your development environment?",
// TODO suggest a port that is definitely available for listening on Default: ports.FreeUpFrom("8080"),
Default: "8080", Validate: ports.IsValidAndFree,
Validate: func(input string) error {
// TODO check the port can be listened on?
// https://coolaj86.com/articles/how-to-test-if-a-port-is-available-in-go/
_, err := strconv.ParseFloat(input, 64)
if err != nil {
return errors.New("Invalid number")
}
return nil
},
} }
value, err := prompt.Run() value, err := prompt.Run()
if err == nil { if err == nil {
......
/*Package ports in internal utils is functionality for interacting with ports
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 ports
import (
"errors"
"log"
"net"
"os"
"strconv"
)
/*FreeUpFrom get a free port up from and including the startingPort. Will attempt 25 ports.*/
func FreeUpFrom(startingPort string) string {
if isValid(startingPort) != nil {
startingPort = "8080"
}
portFloat, _ := strconv.ParseFloat(startingPort, 64)
loops := 1
for portFloat < 65535 && loops <= 25 {
loopPort := strconv.FormatFloat(portFloat, 'f', 0, 64)
if IsValidAndFree(loopPort) == nil {
return loopPort
}
portFloat++
loops++
}
log.Fatal(errors.New("too many loops finding free port"))
os.Exit(1)
return ""
}
/*IsValidAndFree ...*/
func IsValidAndFree(port string) error {
err := isValid(port)
if err != nil {
return err
}
err = isFree(port)
if err != nil {
return err
}
return nil
}
func isFree(port string) error {
ln, err := net.Listen("tcp", ":"+port)
if err != nil {
return errors.New("port is not availible to listen on")
}
ln.Close()
return nil
}
func isValid(port string) error {
parsedPort, err := strconv.ParseFloat(port, 64)
if err != nil {
return errors.New("invalid number")
}
if parsedPort > 65535 || parsedPort < 1 {
return errors.New("invalid port number")
}
return nil
}
Supports Markdown
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