[Enh]: Custom VM/Images - Refactor and Add Squeak
Add Squeak
Extensive Documentation
Rename GToolkit image class due to botched prefix and failure to capitalize "Toolkit"
Refactor hooks now that second example has provided clarity
MODIFY
src/PharoLauncher-Core/PhLImage.class.st
src/PharoLauncher-Core/PhLImage.class.st
"
-I represent a Pharo image. I live in a particular location and have a name. Users can launch me.
+I represent a Pharo (or other) image. I live in a particular location and have a name. Users can launch me.
+
+#VM Matching
+I am matched to the appropriate VM to launch me via my ""version file"", which is in the same folder as me, and whose name is the string returned by #versionFileName. My version file's contents are of the form: `{prefix}{version}`*, where:
+- {prefix} is empty for standard Pharo images. It is made available and used by custom images/VMs e.g. Gtoolkit uses 'gt-'
+- {version} is whatever convention is used by the image/VM type. For standard Pharo, it is the Pharo version with dots removed. Examples:
+ - Pharo 9.0 -> `90`.
+ - Gtoolkit 0.8.83 -> `gt-0.8.83`.
+* This pattern is the same as the matching VM root folder minus the architecture. See PhLVirtualMachine comment, ""Filesystem Location"" section for more info.
+
+#Customized Image Types
+Subclassing me allows you to customize things like:
+- Which VM to use (if not using the standard mapping from Pharo image version to Pharo VM). For example, GToolkit or Squeak VMs. See below for more details.
+- Default image arguments (by overriding #defaultArguments). For example, GToolkit needs this because the image immediately closes after startup unless `'--no-quit'` is supplied.
+
+##Custom VM Mapping
+with contents `{prefix}{version}` e.g. `gt-0.8.83`. This is the same as the VM root folder minus the architecture. See PhLVirtualMachine comment, ""Filesystem Location"" section for more info.
+Let's say you have an image that should be run on a custom VM (i.e. not a standard Pharo one)... subclass me, overriding `#versionPrefix` to match the `#versionPrefix` returned by an appropriate PhLVirtualMachine subclass. N.B. To change the VM of an image that has previously been launched with another VM, you may have to delete the image's metainfo file, which would cache the VM info.
+
+##Installing an existing (on the filesystem) image in Launcher
+Currently, custom images can't be downloaded via Launcher due to differences in URL and other conventions, although this could probably be implemented if someone was interested enough. To create a template from a custom image, you must do the following:
+1. Download the image and changes file.
+2. Create a folder in your Launcher images folder which contains the image and changes file. Both files should have the same basename as the folder. For example, `/path/to/launcher_images/Gtoolkit 0.8.83`, `Gtoolkit 0.8.83.image` and `Gtoolkit 0.8.83.changes`.
+3. Create a ""version file"" as described in ""Custom VM Mapping"" above.
+4. Open or refresh Launcher. The image should appear.
+
+##Template Creation
+To create a template from a custom image, prepare an image as described above in ""Installing..."" and then select the image in Launcher, bring up its context menu, choose ""Create Template"" and go through the dialogs.
+The template should now be available to create new images.
Instance Variables
file: a reference to the .image file
@@ -9,7 +37,7 @@ Instance Variables
pharoVersion: the Pharo version number of the image
originTemplate: template that was used to create this image
-My metadata are serialized when setting description, template or before launching the image (implies to compute formatNumber, architecture and pharo version)
+My metadata are serialized when setting description, template or before launching the image (implies to compute formatNumber, architecture and pharo version).
"
Class {
#name : #PhLImage,
@@ -35,7 +63,7 @@ Class {
{ #category : #accessing }
PhLImage class >> classForLocation: imageFileReference [
^ self allSubclasses
- detect: [ :cls | cls isClassForLocation: imageFileReference ]
+ detect: [ :cls | cls isSubclassForLocation: imageFileReference ]
ifNone: [ self ]
]
@@ -84,8 +112,10 @@ PhLImage class >> initialize [
]
{ #category : #testing }
-PhLImage class >> isClassForLocation: imageFileReference [
- self subclassResponsibility
+PhLImage class >> isSubclassForLocation: imageFileReference [
+ | versionFile |
+ versionFile := imageFileReference parent / self versionFileName.
+ ^ versionFile exists and: [ versionFile contents beginsWith: self versionPrefix ]
]
{ #category : #'instance creation' }
@@ -128,6 +158,13 @@ PhLImage class >> versionFileName [
^ 'pharo.version'
]
+{ #category : #accessing }
+PhLImage class >> versionPrefix [
+ "Used in matching me to a VM. See class comment, 'VM Matching' section"
+
+ ^ ''
+]
+
{ #category : #configuring }
PhLImage >> addLaunchConfiguration: aPhLLaunchConfiguration [
launchConfigurations

MODIFY
src/PharoLauncher-Core/PhLPrivateVirtualMachine.class.st
src/PharoLauncher-Core/PhLPrivateVirtualMachine.class.st
@@ -11,7 +11,7 @@ Class {
}
{ #category : #testing }
-PhLPrivateVirtualMachine class >> isClassForDirectory: aFileReference private: isPrivateVm [
+PhLPrivateVirtualMachine class >> isSubclassForDirectory: aFileReference private: isPrivateVm [
^ isPrivateVm
]

MODIFY
src/PharoLauncher-Core/PhLVirtualMachine.class.st
src/PharoLauncher-Core/PhLVirtualMachine.class.st
"
-I represent a Pharo virtual machine that can be used to run image.
+I represent a Pharo (or other) virtual machine that can be used to run an image.
+
+# Filesystem Location
+For standard Pharo VMs, this is handled automatically and users should not have to be concerned about the details. However, the name of my executable's root folder must follow an exact pattern because this is how I am matched to images. My custom subclasses will have to know where and how to install their files. My executable is kept in the Launcher VM folder, in a root folder of the form `{prefix}{version}{architecture}`, where:
+- {prefix} - Standard Pharo VMs have no prefix, which is available and used to distinguish custom images/VMs. For example, Gtoolkit uses 'gt-'.
+- {version} - Standard Pharo VMs use the image version without dots e.g. '90' for Pharo 9.0. Custom classes can use any convention they wish, e.g. Gtoolkit keeps the dots e.g. '0.8.83' for Gtoolkit 0.8.83.
+- {architecture} - one of #('x64', 'x86')
+
+Three folder naming examples:
+- 64-bit: For Pharo 9.0 64-bit, I would be in the `path/to/vms/90-x64` folder
+- 32-bit: For Pharo 8.0 32-bit, I would be in the `path/to/vms/80-x86` folder
+- Custom VM: For GToolkit 0.8.83, I would be in the `path/to/vms/gt-0.8.83-x64` folder
+
+#Customized VM Types
+Subclassing me allows you to use non-standard Pharo VMs, customizing things like the `#executableName`. Also, pick a prefix as described above in 'Filesystem Location'.
+
+##Setup
+Currently, custom VMs can't be downloaded via Launcher due to differences in URL and other conventions, although this could probably be implemented if someone was interested enough. To install VMs within Launcher
+1. Download the VM
+2. Put the VM, including all libraries and other needed resources - like the sources file - into a folder as described above in 'Filesystem Location'
executableRef is a reference to the script/binary to actually use to launch images.
vmBinaryRef is a reference to the vm binary (not a bash file).
@@ -30,7 +49,7 @@ PhLVirtualMachine class >> directory: aFileReference [
{ #category : #'instance creation' }
PhLVirtualMachine class >> directory: aFileReference private: isPrivateVm [
| targetClass |
- targetClass := self allSubclasses detect: [ :cls | cls isClassForDirectory: aFileReference private: isPrivateVm ] ifNone: [ self ].
+ targetClass := self allSubclasses detect: [ :cls | cls isSubclassForDirectory: aFileReference private: isPrivateVm ] ifNone: [ self ].
^ targetClass new
initializeOn: aFileReference;
yourself
@@ -61,8 +80,16 @@ PhLVirtualMachine class >> id: aString [
]
{ #category : #testing }
-PhLVirtualMachine class >> isClassForDirectory: aFileReference private: isPrivateVm [
- self subclassResponsibility
+PhLVirtualMachine class >> isSubclassForDirectory: aFileReference private: isPrivateVm [
+
+ ^ isPrivateVm not and: [ aFileReference basename beginsWith: self versionPrefix ]
+]
+
+{ #category : #accessing }
+PhLVirtualMachine class >> versionPrefix [
+ "See class comment, 'Filesystem Location' section"
+
+ ^ ''
]
{ #category : #comparing }

DELETE
src/PharoLauncher-GToolkit/PLhGtoolkitImage.class.st
-Class {
- #name : #PLhGtoolkitImage,
- #superclass : #PhLImage,
- #category : #'PharoLauncher-GToolkit'
-}
-
-{ #category : #testing }
-PLhGtoolkitImage class >> isClassForLocation: imageFileReference [
- | versionFile |
- versionFile := imageFileReference parent / self versionFileName.
- ^ versionFile exists and: [ versionFile contents beginsWith: 'gt-' ]
-]
-
-{ #category : #accessing }
-PLhGtoolkitImage >> defaultArguments [
- ^ super defaultArguments
- add: '--no-quit';
- add: '--interactive';
- yourself
-]

ADD
src/PharoLauncher-GToolkit/PhLGToolkitImage.class.st
+"
+See PhLImage comment for setup details. GToolkit VM/image bundles can be downloaded at https://gtoolkit.com/download/.
+"
+Class {
+ #name : #PhLGToolkitImage,
+ #superclass : #PhLImage,
+ #category : #'PharoLauncher-GToolkit'
+}
+
+{ #category : #testing }
+PhLGToolkitImage class >> versionPrefix [
+ ^ PhLGToolkitVirtualMachine versionPrefix
+]
+
+{ #category : #accessing }
+PhLGToolkitImage >> defaultArguments [
+ ^ super defaultArguments
+ add: '--no-quit';
+ add: '--interactive';
+ yourself
+]

MODIFY
src/PharoLauncher-GToolkit/PhLGToolkitVirtualMachine.class.st
src/PharoLauncher-GToolkit/PhLGToolkitVirtualMachine.class.st
+"
+See PhLVirtualMachine's comment for general details. GToolkit VM/image bundles can be downloaded at https://gtoolkit.com/download/
+
+#Setup
+Two things unique to GToolkit setup:
+1. Gtoolkit currently puts some libraries in non-standard locations e.g. on Mac, several dylibs are outside the .app bundle in its parent folder. Make sure to include all these libraries and any other needed resources - like the sources file - when placing the VM in the Launcher VM folder.
+2. For the time being, each image must be launched with the VM distributed with that image version, even for minor and patch releases*. No assumptions can be made about compatibility other than that because the VM may change with every image version.
+
+* Per the GToolkit team on 8/28/2020 on the GT Discord Server, general channel
+"
Class {
#name : #PhLGToolkitVirtualMachine,
#superclass : #PhLVirtualMachine,
@@ -9,7 +19,7 @@ PhLGToolkitVirtualMachine class >> executableName [
^ 'GlamorousToolkit'
]
-{ #category : #testing }
-PhLGToolkitVirtualMachine class >> isClassForDirectory: aFileReference private: isPrivateVm [
- ^ aFileReference basename beginsWith: 'gt-'
+{ #category : #accessing }
+PhLGToolkitVirtualMachine class >> versionPrefix [
+ ^ 'gt-'
]

ADD
src/PharoLauncher-Squeak/PhLSqueakImage.class.st
+"
+See PhLImage comment for setup details. Squeak VM/image bundles can be downloaded at https://squeak.org/downloads/
+"
+Class {
+ #name : #PhLSqueakImage,
+ #superclass : #PhLImage,
+ #category : #'PharoLauncher-Squeak'
+}
+
+{ #category : #testing }
+PhLSqueakImage class >> versionPrefix [
+ ^ PhLSqueakVirtualMachine versionPrefix
+]

ADD
src/PharoLauncher-Squeak/PhLSqueakVirtualMachine.class.st
+"
+See PhLVirtualMachine's comment for general details. Squeak VM/image bundles can be downloaded at https://squeak.org/downloads/
+"
+Class {
+ #name : #PhLSqueakVirtualMachine,
+ #superclass : #PhLVirtualMachine,
+ #category : #'PharoLauncher-Squeak'
+}
+
+{ #category : #querying }
+PhLSqueakVirtualMachine class >> executableName [
+ ^ 'Squeak'
+]
+
+{ #category : #testing }
+PhLSqueakVirtualMachine class >> versionPrefix [
+ ^ 'sq-'
+]

ADD
src/PharoLauncher-Squeak/package.st
+Package { #name : #'PharoLauncher-Squeak' }

MODIFY
src/PharoLauncher-Tests-Functional/PhLOsXMojaveTestImage.class.st
src/PharoLauncher-Tests-Functional/PhLOsXMojaveTestImage.class.st
@@ -9,7 +9,7 @@ Class {
}
{ #category : #testing }
-PhLOsXMojaveTestImage class >> isClassForLocation: aFileReference [
+PhLOsXMojaveTestImage class >> isSubclassForLocation: aFileReference [
^ false
]

[Enh]: Custom VM/Images - Refactor and Add Squeak
- Add Squeak
- Extensive Documentation
- Rename GToolkit image class due to botched prefix and failure to capitalize "Toolkit"
- Refactor hooks now that second example has provided clarity