Providing git friendly file format support to VASmalltalk
Report a defect
|
Request feature
Supporting the Tonel format is a work in progress in VAST 9.2. Our implementation complies with the specification of the format. But since the specification does not take into account some important VAST specific features we extended it in a non intrusive way to make it compatible with the spec and useful to VAST users as well.
There are four main building blocks that work in layers to support Tonel in VA Smalltalk:
Parses the Tonel specific files following the same rules as the canonical version.
Relies on the parser to create first-class objects representing each abstraction from Tonel. E.g. Package, Class, Method Definition, Method Extension
Uses the reader to compile classes, methods, extensions, etc. and then create the required editions and versions in the ENVY Library.
Writes to disk, in a Tonel compatible format (plus the VAST specific features described below) the Applications, SubApplications, Classes, Shared Pools, Methods, Extensions, etc.
If the Application has a class side #tonelPackageName
selector it will then honor it when creating the package name.
For Instantiations and VA Smalltalk, having git support is a priority. The first step is to have a plain text file-based output and input for the sources of its Applications.
Tonel is the current file format widely accepted by the Smalltalk community to store source code on disk with a VCS-friendly format.
- The code is licensed under MIT.
- The documentation is licensed under CC BY-SA 4.0.
- Download VAST 9.2 or newer from Instantiations.
- Clone this repository.
- From the configuration map browser, import all versions of the
Tonel
map fromenvy/Tonel.dat
. Then "Load With Required Maps" the latest version of it. - Explore the documentation.
- (optional) Run SUnit Suite for all
Tonel
map (right click on the map ->Test Loaded Applications
). You should see around 58 unit tests and all passing.
- Open Application Manager and try the menu option "Import/Export" -> "Import Applications from Tonel packages..." and "Export Applications as Tonel packages..."
(TonelLoader readFromPath (CfsPath named: 'tonel-demos'))
loadApplicationNamed: 'TonelExampleApp'.
"or you can load by Tonel package name"
(TonelLoader readFromPath (CfsPath named: 'tonel-demos'))
loadApplicationsForPackagesNamed: #('YourPackage-Core' 'YourPackage-Tests').
"Writing back to Tonel"
TonelWriter new
clearSourcesDirectory; "deletes everything in the target directory"
writeProjectIncluding: (Array with: TonelExampleApp)
into: (CfsPath named: 'tonel-demos').
Below we list the specific features of VAST and how they're handled.
Since VAST supports multiple categories per method (not just one), when writing Tonel from VAST if the method has more than one category in addition to the #category
property containing a single category name, we add a custom #vaCategories
property to the method definition metadata whose value is an array of category names.
This way, when loading methods from source code, single method categories dialects will read only the #category
property and the VAST Tonel loader will look for the vaCategories
(if available).
In VAST method visibility is not a simple category convention but a boolean property of the method itself, so methods can be treated as private
or public
and the tools will accommodate to this accordingly.
To support this feature we added a #vaVisibility
property to the method definition metadata whose value is a string containing either public
or private
values.
When reading code if this property is not present, the method will use public
visibility by default.
VAST Applications have prerequisites, that are the dependencies on other applications. Such concept is absent from the Tonel spec that only has the concept of Package and dependency is managed elsewhere.
We fulfill this need by adding a custom property named #vaPrerequisites
to the package definition file (.package
) whose value is an array containing the names of the prerequisites.
VAST Applications can contain SubApplications, and these SubApplications can contain other SubApplications forming a composition tree, each node in the hierarchy conditioning the load of the sub applications to some condition (aka config expression, more on this later).
Such hierarchy of composition concept is not considered by the original Tonel spec, and for Tonel everything is just a Package on a flat level.
To work around this we map each Application or Subapplication to a Package and write them at the same flat level, also adding VAST specific properties to the package metadata definition. In addition, since the composition depends on some config expression (a Smalltalk expression that returns a boolean) we store the expression and the SubApplications it would load as as a #vaSubapplications
property as follows:
#vaSubApplications : [
{
#condition : '(System subsystemType: #OS) = ''WIN32s''',
#subapps : [
'SomeWindowsSpecificApp'
]
}
]
For the most cases the config expression is just true
meaning the sub applications will always load.
#vaSubApplications : [
{
#condition : 'true',
#subapps : [
'TonelExampleAnotherSubSubApp',
'TonelExampleSubSubApp'
]
}
]
Also, in the case of SubApplications they will contain the name of parent Application or SubApplication using the property #vaParent
, whose value will be the name of the Application or SubApplication in VAST and the name of the Tonel Package.
'TonelExampleApp'.
So extending our example above for the sample subapp
#vaParent: 'TonelExampleApp',
#vaSubApplications : [
{
#condition : 'true',
#subapps : [
'TonelExampleAnotherSubSubApp',
'TonelExampleSubSubApp'
]
}
]
When an Application or SubApplication has different branches of SubApplications based on different config expressions the SubApplications in the branch that is not loaded in the image are called shadow SubApplications. The typical example is some OS-specific features that are loaded based on the OS in which the image is running (e.g. UNIX vs Windows).
The current implementation of Tonel Writer for VAST fully supports writing the conditions and SubApplications to disk, but the Tonel Loader will only compile and create editions for the applications whose config expressions are valid (it is, that evaluates to true).
So if you now write an existing Application with shadow SubApplications they will be written to disk, but once you load them back, the shadowed ones will not be loaded (and hence not versioned in the ENVY Library).
If you want to make your code fully compatible and interoperable with other Smalltalk dialects there is a specific document with the recommendations for compatibility.
VAST's way of declaring and/or initializing Shared Pools is different from other Smalltalk dialects, and to explain how this work with Tonel, there is a specific document explaining how VAST Tonel handles shared pools.
Read the versioning, prerequisites and base editions strategies documentation to learn how to configure the loader to work interactively, unattended, read the version from a git repository, etc.
Although dependency management is outside of the scope of Tonel, VA Smalltalk's Tonel tools provide a way to write them to disk and later read and load them.
Read the Configuration Maps documentation to learn how to use it.
There is a whole Github project that contains demos about Tonel integration with VASmalltalk.
See the roadmap document for further details.
- Mercap Software for their first draft on the Tonel writer
- Github repository layout was generated with Ba-St Github-setup project.
Check the Contribution Guidelines