Skip to content

Commit

Permalink
[feat] Use PHP Mirror to download and install on x64 arch
Browse files Browse the repository at this point in the history
  • Loading branch information
BrainBuzzer committed Jan 28, 2023
1 parent 128da80 commit 4555bc5
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 20 deletions.
36 changes: 36 additions & 0 deletions cmd/ch/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ch

import (
"fmt"
"os"
"path/filepath"

"github.com/BrainBuzzer/php-ch/pkg"
"github.com/spf13/cobra"
)

var listCommand = &cobra.Command{
Use: "list",
Short: "List all available PHP versions",
Long: `List all available PHP versions`,
Run: func(cmd *cobra.Command, args []string) {
root := os.Getenv("PHP_HOME")
vs, err := pkg.ListAllVersions()
if err != nil {
fmt.Println("Error while fetching versions: ", err)
}

for _, v := range vs {
installdir := filepath.Join(root, "versions", v.String())
if _, err := os.Stat(installdir); os.IsNotExist(err) {
fmt.Println(v.String())
} else {
fmt.Println(v.String() + "* Installed")
}
}
},
}

func init() {
rootCmd.AddCommand(listCommand)
}
2 changes: 1 addition & 1 deletion cmd/ch/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var setupCommand = &cobra.Command{
_, err := exec.Command("php", "-v").Output()
if err != nil {
fmt.Println("No PHP installation found. Installing the latest PHP.")
pkg.ChangeVersion("8.2")
pkg.ChangeVersion("8.2.0")
}

// check if the exec path of php is the same as the PHP_HOME env variable
Expand Down
21 changes: 21 additions & 0 deletions cmd/ch/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ch

import (
"fmt"

"github.com/spf13/cobra"
)

var versionCommand = &cobra.Command{
Use: "set",
Short: "Set PHP Version",
Aliases: []string{"v"},
Long: `This command checks if there is existing PHP installation for given version, if not, downloads the specified PHP version.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("0.0.3")
},
}

func init() {
rootCmd.AddCommand(versionCommand)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
)

require (
github.com/Masterminds/semver/v3 v3.2.0
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
123 changes: 104 additions & 19 deletions pkg/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import (
"os"
"os/exec"
"path/filepath"
"sort"
"strings"

"github.com/Masterminds/semver/v3"
"github.com/schollz/progressbar/v3"
)

Expand All @@ -20,15 +22,60 @@ var env = Environment{
Symlink: os.Getenv("PHP_SYMLINK"),
}

func ListAllVersions() ([]*semver.Version, error) {
// fetch all versions from https://windows.php.net/downloads/releases/archives/
// print all versions
resp, err := http.Get("https://windows.php.net/downloads/releases/archives/")
if err != nil {
fmt.Println("Error while fetching versions: ", err)
return nil, err
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error while fetching versions: ", err)
return nil, err
}

versions := strings.Split(string(body), "php-")
allVersions := make(map[string]bool)
for _, version := range versions {
if strings.Contains(version, "-Win32") && !strings.Contains(version, "pack") {
allVersions[strings.Split(version, "-")[0]] = true
}
}

// convert map[string]bool to []string
var versionsList []string
for version := range allVersions {
versionsList = append(versionsList, version)
}

vs := make([]*semver.Version, len(versionsList))
for i, r := range versionsList {
v, err := semver.NewVersion(r)
if err != nil {
fmt.Println("Error while fetching versions: ", err)
return nil, err
}

vs[i] = v
}

sort.Sort(semver.Collection(vs))

return vs, nil
}

func ChangeVersion(version string) {
// check if there is directory in C:\php\versions\version
// if not, start download
// if yes, run command "cmd /c mklink /D C:\php\current C:\php\versions\version"
installdir := filepath.Join(env.Root, "versions", version)

if _, err := os.Stat(installdir); os.IsNotExist(err) {
fmt.Println("Version", version, "does not exist")
fmt.Println("Downloading " + version + "...")
fmt.Println("Version", version, "does not exist on local machine, checking if version is available on PHP Servers.")
DownloadVersion(version)
} else {
if _, err := os.Stat(env.Symlink); !os.IsNotExist(err) {
Expand All @@ -49,24 +96,50 @@ func ChangeVersion(version string) {
}

func DownloadVersion(version string) {
// check if system is 32 or 64 bit
// download the correct version
// extract the zip file
// move all content from where to C:\php\versions\version
// open php.ini from C:\php\versions\version and add the following lines
// extension_dir = "ext"
allVersions, err := ListAllVersions()
if err != nil {
panic(err)
}

isPresent := false
for _, v := range allVersions {
if v.Original() == version {
isPresent = true
break
}
}

if isPresent {
resp, err := http.Get("https://windows.php.net/downloads/releases/archives/")
if err != nil {
fmt.Println("Error while fetching versions: ", err)
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error while fetching versions: ", err)
}

versions := strings.Split(string(body), "php-"+version+"-Win32-")
matched := false
for _, v := range versions {
// test regex for php-{version}-Win32-{something}-x64.zip
part := strings.Split(v, ".zip")[0]
if strings.Contains(part, "x64") {
matched = true
fmt.Println("Found x64 version: ", part)
url := "https://windows.php.net/downloads/releases/archives/php-" + version + "-Win32-" + part + ".zip"
fmt.Println("Downloading from: ", url)
downloadAndInstall(url, version)
break
}
}

if !matched {
fmt.Println("Could not find x64 version for PHP " + version)
}

switch version {
case "8.2":
downloadAndInstall("https://windows.php.net/downloads/releases/php-8.2.1-Win32-vs16-x64.zip", version)
case "8.1":
downloadAndInstall("https://windows.php.net/downloads/releases/php-8.1.14-Win32-vs16-x64.zip", version)
case "8.0":
downloadAndInstall("https://windows.php.net/downloads/releases/php-8.0.27-Win32-vs16-x64.zip", version)
case "7.4":
downloadAndInstall("https://windows.php.net/downloads/releases/php-7.4.33-Win32-vc15-x64.zip", version)
default:
fmt.Println("Version", version, "does not exist")
}
}

Expand Down Expand Up @@ -141,6 +214,18 @@ func downloadAndInstall(url string, version string) {
// copy php.ini from C:\php\versions\version\php.ini-development to C:\php\versions\version\php.ini
os.Rename(dst+"\\php.ini-development", dst+"\\php.ini")

// edit php.ini and add the following lines
// extension_dir = "ext"
file, err := os.OpenFile(dst+"\\php.ini", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
defer file.Close()

if _, err = file.WriteString("extension_dir = \"ext\""); err != nil {
panic(err)
}

// change version to the one that was just downloaded
ChangeVersion(version)
}
Expand Down

0 comments on commit 4555bc5

Please sign in to comment.