Skip to content

Installer for PVM: Update to 1.2.0 #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
/.idea
/.vscode
pvm.exe
/.vscode
40 changes: 28 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,53 @@ This utility changes that.

## Installation

Download the latest pvm version from the releases page (1.0-alpha-1, it's currently a pre-release).
> [!WARNING]
> version lower than 1.3.0 will have only pvm.exe
> version 1.3.0 or higher will include pvm-setup.exe but can still get pvm.exe from source

Create the folder `%UserProfile%\.pvm\bin` (e.g. `C:\Users\Harry\.pvm\bin`) and drop the pvm exe in there. Add the folder to your PATH.
### Installer
> Download the latest pvm installer from the releases page (>= 1.3.0).

### Manual Installation
> Create the folder `%UserProfile%\.pvm\bin` (e.g. `C:\Users\Harry\.pvm\bin`) and drop the pvm.exe in there. Add the folder to your PATH.

## Commands

```
pvm list
```

Will list out all the available PHP versions you have installed

```
pvm path
pvm install 8
```
Will tell you what to put in your Path variable.

> [!NOTE]
> The install command will automatically determine the newest minor/patch versions if they are not specified

Will install PHP 8 at the latest minor and patch.

```
pvm use 8.2.9
pvm use 8.2
```
> [!NOTE]

> [!NOTE]
> Versions must have major.minor specified in the *use* command. If a .patch version is omitted, newest available patch version is chosen.

Will switch your currently active PHP version to PHP 8.2.9
Will switch your currently active PHP version to PHP 8.2 latest patch.

```
pvm install 8.2
pvm uninstall 8.2.9
```
> [!NOTE]
> The install command will automatically determine the newest minor/patch versions if they are not specified

Will install PHP 8.2 at the latest patch.
> [!NOTE]
> Versions must have major.minor.patch specified in the *uninstall* command. If a .patch version is omitted, it will not uninstalling.

Will uninstall PHP version to PHP 8.2.9

## Composer support

`pvm` now installs also composer with each php version installed.
It will install Composer latest stable release for PHP >= 7.2 and Composer latest 2.2.x LTS for PHP < 7.2.
You'll be able to invoke composer from terminal as it is intended:
Expand All @@ -53,6 +68,7 @@ composer --version
## Build this project

To compile this project use:

```shell
GOOS=windows GOARCH=amd64 go build -o pvm.exe
```
```
22 changes: 0 additions & 22 deletions commands/path.go

This file was deleted.

Binary file added pvm-setup.exe
Binary file not shown.
139 changes: 139 additions & 0 deletions pvm-setup.iss
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "PVM"
#define MyAppVersion "1.3.0"
#define MyAppPublisher "hjb.dev"
#define MyAppURL "https://github.com/hjbdev/pvm"
#define MyAppExeName "pvm.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{DA006438-7CC4-41E4-B2BF-2AD84AAA18E9}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={%USERPROFILE}\.pvm
UninstallDisplayIcon={app}\{#MyAppExeName}
; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run
; on anything but x64 and Windows 11 on Arm.
ArchitecturesAllowed=x64os
; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the
; install be done in "64-bit mode" on x64 or Windows 11 on Arm,
; meaning it should use the native 64-bit Program Files directory and
; the 64-bit view of the registry.
ArchitecturesInstallIn64BitMode=x64compatible
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile=LICENSE
InfoAfterFile=README.md
; Uncomment the following line to run in non administrative install mode (install for current user only).
PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog
OutputDir=.
OutputBaseFilename=pvm-setup
SolidCompression=yes
WizardStyle=modern

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Files]
Source: "src\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Dirs]
Name: "{app}\bin"
Name: "{app}\versions"

[UninstallDelete]
Type: filesandordirs; Name: "{app}"

[Code]
var
path: string;

procedure InitializePath();
begin
if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path) then
begin
if Pos(ExpandConstant('{app}'), path) = 0 then
begin
// Check if PATH is empty
if path <> '' then
path := path + ';';

// Add the app directory and bin directory to the PATH
path := path + ExpandConstant('{app}') + ';' + ExpandConstant('{app}') + '\bin';

// Remove extra semicolons (e.g., ;; becomes ; or ;;; becomes ;)
StringChangeEx(path, ';;', ';', True);

// Remove any leading semicolon at the start of the path if present
if (Pos(';', path) = 1) then
path := Copy(path, 2, Length(path) - 1);

// Ensure there's no trailing semicolon at the end of the path
if (Pos(';', path) = Length(path)) then
path := Copy(path, 1, Length(path) - 1);

// Write the added path back to the registry
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
end;
end
else
begin
MsgBox('Unable to read PATH environment variable.', mbError, MB_OK);
end;
end;

procedure RemovePath();
begin
if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path) then
begin
// Remove the app directory and bin directory from the PATH
StringChangeEx(path, ExpandConstant('{app}') + ';', '', True);
StringChangeEx(path, ExpandConstant('{app}') + '\bin' + ';', '', True);

// Remove extra semicolons (e.g., ;; becomes ; or ;;; becomes ;)
StringChangeEx(path, ';;', ';', True);

// Remove any leading semicolon at the start of the path if present
if (Pos(';', path) = 1) then
path := Copy(path, 2, Length(path) - 1);

// Ensure there's no trailing semicolon at the end of the path
if (Pos(';', path) = Length(path)) then
path := Copy(path, 1, Length(path) - 1);

// Write the cleaned path back to the registry
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
end
else
begin
MsgBox('Unable to read PATH environment variable.', mbError, MB_OK);
end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
InitializePath();
end
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usUninstall then
begin
RemovePath();
end;
end;


6 changes: 3 additions & 3 deletions commands/help.go → src/commands/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

func Help(notFoundError bool) {
theme.Title("pvm: PHP Version Manager")
theme.Info("Version 1.2.0")
theme.Info("Version 1.3.0")

if notFoundError {
theme.Error("Command not found")
Expand All @@ -16,8 +16,8 @@ func Help(notFoundError bool) {
fmt.Println("Available Commands:")
fmt.Println(" help")
fmt.Println(" install")
fmt.Println(" list")
fmt.Println(" uninstall")
fmt.Println(" list-remote")
fmt.Println(" path")
fmt.Println(" list")
fmt.Println(" use")
}
20 changes: 11 additions & 9 deletions commands/install.go → src/commands/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,17 @@ func Install(args []string) {
desiredMinorVersion := desiredVersionNumbers.Minor
desiredPatchVersion := desiredVersionNumbers.Patch

versions, err := common.RetrievePHPVersions()
latestVersions, err := common.RetrievePHPVersions("https://windows.php.net/downloads/releases/")
if err != nil {
log.Fatalln(err)
}
archivesVersions, err := common.RetrievePHPVersions("https://windows.php.net/downloads/releases/archives/")
if err != nil {
log.Fatalln(err)
}

versions := append(latestVersions, archivesVersions...)

// find desired version
var desiredVersion common.Version

Expand All @@ -78,21 +84,17 @@ func Install(args []string) {

fmt.Printf("Installing PHP %s\n", desiredVersion)

homeDir, err := os.UserHomeDir()
// get current dir
currentDir, err := os.Executable()

if err != nil {
log.Fatalln(err)
}

// check if .pvm folder exists
pvmPath := filepath.Join(homeDir, ".pvm")
if _, err := os.Stat(pvmPath); os.IsNotExist(err) {
theme.Info("Creating .pvm folder in home directory")
os.Mkdir(pvmPath, 0755)
}
fullDir := filepath.Dir(currentDir)

// check if .pvm/versions folder exists
versionsPath := filepath.Join(pvmPath, "versions")
versionsPath := filepath.Join(fullDir, "versions")
if _, err := os.Stat(versionsPath); os.IsNotExist(err) {
theme.Info("Creating .pvm/versions folder in home directory")
os.Mkdir(versionsPath, 0755)
Expand Down
11 changes: 10 additions & 1 deletion commands/list-remote.go → src/commands/list-remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ import (
)

func ListRemote() {
versions, err := common.RetrievePHPVersions()
latestVersions, err := common.RetrievePHPVersions("https://windows.php.net/downloads/releases/")
if err != nil {
log.Fatalln(err)
}
archivesVersions, err := common.RetrievePHPVersions("https://windows.php.net/downloads/releases/archives/")
if err != nil {
log.Fatalln(err)
}

versions := append(latestVersions, archivesVersions...)
if err != nil {
log.Fatalln(err)
}
Expand Down
1 change: 0 additions & 1 deletion commands/list.go → src/commands/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package commands
import (
"hjbdev/pvm/common"
"hjbdev/pvm/theme"

"github.com/fatih/color"
)

Expand Down
Loading