More Installer and Sake/Packages documentation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

More Installer and Sake/Packages documentation

Ken G. Brown
More Installer and Sake/Packages documentation
For those who cannot be bothered to look in an Image for documentation, here are some of the
Class Comments retrieved from an 090628-1523_Squeak3.10.2-lpf-atomic image from <ftp://ftp.squeak.org/3.11/Squeak3.10.2-lpf-atomic/latest/> after executing Installer install: 'Packages'.
This is also being posted to <http://squeaktipsandtrickswatch.blogspot.com/>.

Ken G. Brown

--
Installer-Core/Installer

Documentation now available at http://installer.pbwiki.com/Installer
 
useFileIn - flag to load source.st rather than using Monticello

--
Installer-Core/InstallerMantis

Search feature is based upon a custom mantis query ceveloped and maintained by Ken Causey <[hidden email]>

Installer mantis bugsAll select: [ :ea | ea status = 'testing' ].

--
Installer-Formats/SARInstaller

I am an object that handles the loading of SAR (Squeak ARchive) files.

A SAR file is a Zip file that follows certain simple conventions:

* it may have a member named "install/preamble".

This member, if present, will be filed in as Smalltalk source code at the beginning of installation.
Typically, the code in the preamble will make whatever installation preparations are necessary,
and will then call methods in the "client services" method category to extract or install other zip members.

* It may have a member named "install/postscript".

This member, if present, will be filed in as Smalltalk source code at the end of installation.
Typically, the code in the postscript will set up the operating environment,
and will perhaps put objects in flaps, open projects or README files, or launch samples.

Within the code in the preamble and postscript, "self" is set to the instance of the SARInstaller.

If neither an "install/preamble" nor an "install/postscript" file is present,
all the members will be installed after prompting the user,
based on a best guess of the member file types that is based on member filename extensions.

This is new behavior.

--
Installer-Scripts/InstallerScripts

(self new addPackage: 'Example') options collect: [ :ea  | ea value asLegalSelector asSymbol ]  #(#scriptExampleSqueak310forKPH #scriptExampleSqueak310 #scriptExampleSqueak310)

--
Installer-Launcher/Launcher

A Launcher provides squeak with a range of capabilities that are intended to be used from the command line.

As a design goal, the startup process can invoke Launcher several times at several points in the startup sequence. In particular 1) below aims to provide a mechanism for getting in to images that are broken in some form, so as to enable a script to be run before morphic has attempted to startup.

1) Launcher is registered to handle startup notification after Security manager
any class which wishes to provide a service to be usable at this time implements startFrom:

2) Launcher is wired in to ProjectLauncher to handle startup notification when squeak is fully initialized. Any class wishing to provide a service to be usable at this time implements launchFrom:

#startFrom: and #launchFrom: are called providing a handle to the launcher which may be used to obtain parameters using the desired scheme.

a) launcher getParameters . key=value +yes -no
b) launcher getParametersOldStyle . key value key2 value2

Instance Variables
    actionSelector: #startFrom: #launchFrom:
        commandLineClass: aClass
        image:  the smalltalk image or self if being a mock
     mock: the mock array of startup parameters
      nextCommandLineDocument: aString
        nextParameterIndex:     anInteger
 
--
Sake-Core/SakeBlock

Raise this if for some reason you find that the task you are doing is blocked. This might occur in a multi builder build system where two building threads decide to build the same item.

(implementation idea - not implemented yet)

When a Block is detected, Sake, looks for any following dependent task that is not dependant upon the blocked task.
Alternatively, Sake could simply randomise the task order and re-sort them, tryng again.

--
Sake-Core/SakeCompiler

Enables methods to include raw uncompiled text for documentation purposes following a line containing 6 quotes """"""

--
Sake-Core/SakeMeta

I'm a dictionary which can be used using any method call instead of #at:put: and at:. Use me like:

- (aSakeMeta foo: 'bar') which is equivalent to (aSakeMeta at: 'foo' put: 'bar')
- (aSakeMeta foo) which is equivalent to (aSakeMeta at: 'foo')

The instance variable 'order' remembers the order in which the elements have been added. The methods #withIndexDo: and #printOn: use this variable to iterate in the same order.

| s |
s := ReadWriteStream on: String new.
(self new a: 1; b: 2; yourself) storeOn: s.
s reset contents
--
Sake-Core/SakeTask

SakeTasks are typically defined as class side methods, which return an instance of SakeTask.

To obtain a list of available tasks, do "Senders of #define: "

MyClass-task1: aParameter

     ^ SakeTask define: [ :task |
                    task dependsOn: {self ruleL3.}.
                task if: [ <return true if action is needed> ].
        task action: [ <do something> ]
  ]

The 'unique id' of a task is the method context in which it is instanciated, and its paramters.
Therefore only one task should be instanciated per method.

Note: Sake tasks can have parameters, Rake tasks dont.

To execute a task...

(MyClass task1: 'param') run.

Results of the prior tasks are available via #results.

FAQ
====
How can I call one Sake task from inside another task?

Generally, if you want invoke one task from another task, the proper way to do that is to include the task to be invoked as a prerequisite of the task doing the invoking.

For example:

MyTasks-c-#taskPrimary

^ SakeTask define: [ :task |
  task dependsOn: { self taskSecondary }.
task action: [ self log sake: 'Doing Primary Task'. ].
]

MyTasks-c-#taskSecondary
^ SakeTask define: [ :task |
     task action: [ self log sake: 'Doing Secondary Task' ].
]

In this case, if the secondary task fails, the whole task stops.

Secondary tasks can also be passed to the ifBlock. In that case, if the task succeeds then the action is performed, if the task fails then the action is considered not needed.

^ SakeTask define: [ :task |
     task if: { self taskSecondary }.
        task action: [ self log sake: 'Doing Primary Task'. ].
]

Action, can also take a list of tasks.  
       
^ SakeTask define: [ :task |
    task action: {
                   self taskSecondary.
                     [ self log sake: 'Doing Primary Task' ].  "a block task"
                               }
].
    
       
--
Sake-Packages/Packages

Sake/Packages usage:

Definitions Search Path
============================
Packages named: 'PackageName'.

Will obtain a package definition. Subclasses of Packages are searched using the order defined by #findPath which is specified by #priority.

e.g. Packages findPath => {PackagesSqueak310 . PackagesDev . PackagesAll . PackagesSeaside29}

Packages-#priority is used to sort classes like so:

The class with defns for a relevant version (listed in #relevantVersions) => 100
The class with defns for dev version (PackagesDev) => 400
The class with defns for all versions (PackagesAll) => 500

Additional package "universes" can define their own priority in order to specify where to appear in the #findPath.
PackagesSeaside29
PackagesGjaller
PackagesBeach

Usage:
========
verbose usage specifying run style.

(Packages named: 'Seaside') run.  " or runQuietly, runStepping, runLogging"

#runStepping , - presents a confirm/debug dialog before each action.
#run            - default.
#runQuietly    - auto-confirms any SakeConfirm dialogs.
#runLogging   - Writes any SakeStop warnings to self log.

default usage:

Packages load: 'Seaside'.
Packages latest: 'Seaside'. "as above, but use latest versions of everything"
Packages unload: 'Seaside'.

multiples:

Packages load: #('Seaside' 'Magma' 'Logging') 

Unloading
========
Unloading comes in two variants.

Each package task loaded by Sake/Packages is remembered in the 'provided' list
If you perform:

    Packages unload: 'Seaside' .

    Packages unloadStepping: 'Seaside' .

Then the 'historical' unload scripts are used, as defined when the original load tasks were run.

If instead you perform:

    (Packages current named: 'Seaside') beUnloading runStepping.
 
Then the most recently defined unload script will be run.

Note: If packages such as "Magma server" and "Magma client" provides "Magma", then

    Packages unload: 'Magma'.

Will unload whichever of the two are loaded.
===
Misc notes...

Universes are using 'instance side' task definition, so the task extensions mechanism does not work in this context.

If a package appears in Packages under an obscure name, it can
tell the PackageInfo instance what name was used to load it via #mcName:

If a package has a version number with a '+' after it, then 'Packages upgrade' will always attempt to load the latest code, leaving Monticello to determine if there are any code changed that need to be applied.

To generate all of the methods based upon universes definitions:
       
        Packages taskGenerateAllUniverses run.
  or
        Packages taskGenerateAll  run.

--
Packages-Library/PackagesDevU

Package definitions for this version as obtained automatically from the Universes server.

To override the definitions in the univere add to my subclass in PackagesSqueak310

To re-read the package definitions from the universes server.

self taskGeneratePackageTasks run

--




Reply | Threaded
Open this post in threaded view
|

Re: More Installer and Sake/Packages documentation

Eliot Miranda-2
Ken,

    thanks.  This is a start.  But how about a better structured document, following some structure like this:

Overview, name of the system and high-level description of is function
Context: context in which it can be used
Major Workflows: what are the major workflows (what they achieve) along with code examples (how to achieve them)
Implementation: a fractal part of the document, overview, major classes, major control flows, etc
Links: further information
Authors/Maintainers
History

On Sat, Nov 7, 2009 at 3:06 PM, Ken G. Brown <[hidden email]> wrote:
For those who cannot be bothered to look in an Image for documentation, here are some of the
Class Comments retrieved from an 090628-1523_Squeak3.10.2-lpf-atomic image from <ftp://ftp.squeak.org/3.11/Squeak3.10.2-lpf-atomic/latest/> after executing Installer install: 'Packages'.
This is also being posted to <http://squeaktipsandtrickswatch.blogspot.com/>.

Ken G. Brown

--
Installer-Core/Installer

Documentation now available at http://installer.pbwiki.com/Installer
 
useFileIn - flag to load source.st rather than using Monticello

--
Installer-Core/InstallerMantis

Search feature is based upon a custom mantis query ceveloped and maintained by Ken Causey <[hidden email]>

Installer mantis bugsAll select: [ :ea | ea status = 'testing' ].

--
Installer-Formats/SARInstaller

I am an object that handles the loading of SAR (Squeak ARchive) files.

A SAR file is a Zip file that follows certain simple conventions:

* it may have a member named "install/preamble".

This member, if present, will be filed in as Smalltalk source code at the beginning of installation.
Typically, the code in the preamble will make whatever installation preparations are necessary,
and will then call methods in the "client services" method category to extract or install other zip members.

* It may have a member named "install/postscript".

This member, if present, will be filed in as Smalltalk source code at the end of installation.
Typically, the code in the postscript will set up the operating environment,
and will perhaps put objects in flaps, open projects or README files, or launch samples.

Within the code in the preamble and postscript, "self" is set to the instance of the SARInstaller.

If neither an "install/preamble" nor an "install/postscript" file is present,
all the members will be installed after prompting the user,
based on a best guess of the member file types that is based on member filename extensions.

This is new behavior.

--
Installer-Scripts/InstallerScripts

(self new addPackage: 'Example') options collect: [ :ea  | ea value asLegalSelector asSymbol ]  #(#scriptExampleSqueak310forKPH #scriptExampleSqueak310 #scriptExampleSqueak310)

--
Installer-Launcher/Launcher

A Launcher provides squeak with a range of capabilities that are intended to be used from the command line.

As a design goal, the startup process can invoke Launcher several times at several points in the startup sequence. In particular 1) below aims to provide a mechanism for getting in to images that are broken in some form, so as to enable a script to be run before morphic has attempted to startup.

1) Launcher is registered to handle startup notification after Security manager
any class which wishes to provide a service to be usable at this time implements startFrom:

2) Launcher is wired in to ProjectLauncher to handle startup notification when squeak is fully initialized. Any class wishing to provide a service to be usable at this time implements launchFrom:

#startFrom: and #launchFrom: are called providing a handle to the launcher which may be used to obtain parameters using the desired scheme.

a) launcher getParameters . key=value +yes -no
b) launcher getParametersOldStyle . key value key2 value2

Instance Variables
    actionSelector: #startFrom: #launchFrom:
        commandLineClass: aClass
        image:  the smalltalk image or self if being a mock
     mock: the mock array of startup parameters
      nextCommandLineDocument: aString
        nextParameterIndex:     anInteger
 
--
Sake-Core/SakeBlock

Raise this if for some reason you find that the task you are doing is blocked. This might occur in a multi builder build system where two building threads decide to build the same item.

(implementation idea - not implemented yet)

When a Block is detected, Sake, looks for any following dependent task that is not dependant upon the blocked task.
Alternatively, Sake could simply randomise the task order and re-sort them, tryng again.

--
Sake-Core/SakeCompiler

Enables methods to include raw uncompiled text for documentation purposes following a line containing 6 quotes """"""

--
Sake-Core/SakeMeta

I'm a dictionary which can be used using any method call instead of #at:put: and at:. Use me like:

- (aSakeMeta foo: 'bar') which is equivalent to (aSakeMeta at: 'foo' put: 'bar')
- (aSakeMeta foo) which is equivalent to (aSakeMeta at: 'foo')

The instance variable 'order' remembers the order in which the elements have been added. The methods #withIndexDo: and #printOn: use this variable to iterate in the same order.

| s |
s := ReadWriteStream on: String new.
(self new a: 1; b: 2; yourself) storeOn: s.
s reset contents
--
Sake-Core/SakeTask

SakeTasks are typically defined as class side methods, which return an instance of SakeTask.

To obtain a list of available tasks, do "Senders of #define: "

MyClass-task1: aParameter

     ^ SakeTask define: [ :task |
                    task dependsOn: {self ruleL3.}.
                task if: [ <return true if action is needed> ].
        task action: [ <do something> ]
  ]

The 'unique id' of a task is the method context in which it is instanciated, and its paramters.
Therefore only one task should be instanciated per method.

Note: Sake tasks can have parameters, Rake tasks dont.

To execute a task...

(MyClass task1: 'param') run.

Results of the prior tasks are available via #results.

FAQ
====
How can I call one Sake task from inside another task?

Generally, if you want invoke one task from another task, the proper way to do that is to include the task to be invoked as a prerequisite of the task doing the invoking.

For example:

MyTasks-c-#taskPrimary

^ SakeTask define: [ :task |
  task dependsOn: { self taskSecondary }.
task action: [ self log sake: 'Doing Primary Task'. ].
]

MyTasks-c-#taskSecondary
^ SakeTask define: [ :task |
     task action: [ self log sake: 'Doing Secondary Task' ].
]

In this case, if the secondary task fails, the whole task stops.

Secondary tasks can also be passed to the ifBlock. In that case, if the task succeeds then the action is performed, if the task fails then the action is considered not needed.

^ SakeTask define: [ :task |
     task if: { self taskSecondary }.
        task action: [ self log sake: 'Doing Primary Task'. ].
]

Action, can also take a list of tasks.  
       
^ SakeTask define: [ :task |
    task action: {
                   self taskSecondary.
                     [ self log sake: 'Doing Primary Task' ].  "a block task"
                               }
].
    
       
--
Sake-Packages/Packages

Sake/Packages usage:

Definitions Search Path
============================
Packages named: 'PackageName'.

Will obtain a package definition. Subclasses of Packages are searched using the order defined by #findPath which is specified by #priority.

e.g. Packages findPath => {PackagesSqueak310 . PackagesDev . PackagesAll . PackagesSeaside29}

Packages-#priority is used to sort classes like so:

The class with defns for a relevant version (listed in #relevantVersions) => 100
The class with defns for dev version (PackagesDev) => 400
The class with defns for all versions (PackagesAll) => 500

Additional package "universes" can define their own priority in order to specify where to appear in the #findPath.
PackagesSeaside29
PackagesGjaller
PackagesBeach

Usage:
========
verbose usage specifying run style.

(Packages named: 'Seaside') run.  " or runQuietly, runStepping, runLogging"

#runStepping , - presents a confirm/debug dialog before each action.
#run            - default.
#runQuietly    - auto-confirms any SakeConfirm dialogs.
#runLogging   - Writes any SakeStop warnings to self log.

default usage:

Packages load: 'Seaside'.
Packages latest: 'Seaside'. "as above, but use latest versions of everything"
Packages unload: 'Seaside'.

multiples:

Packages load: #('Seaside' 'Magma' 'Logging') 

Unloading
========
Unloading comes in two variants.

Each package task loaded by Sake/Packages is remembered in the 'provided' list
If you perform:

    Packages unload: 'Seaside' .

    Packages unloadStepping: 'Seaside' .

Then the 'historical' unload scripts are used, as defined when the original load tasks were run.

If instead you perform:

    (Packages current named: 'Seaside') beUnloading runStepping.
 
Then the most recently defined unload script will be run.

Note: If packages such as "Magma server" and "Magma client" provides "Magma", then

    Packages unload: 'Magma'.

Will unload whichever of the two are loaded.
===
Misc notes...

Universes are using 'instance side' task definition, so the task extensions mechanism does not work in this context.

If a package appears in Packages under an obscure name, it can
tell the PackageInfo instance what name was used to load it via #mcName:

If a package has a version number with a '+' after it, then 'Packages upgrade' will always attempt to load the latest code, leaving Monticello to determine if there are any code changed that need to be applied.

To generate all of the methods based upon universes definitions:
       
        Packages taskGenerateAllUniverses run.
  or
        Packages taskGenerateAll  run.

--
Packages-Library/PackagesDevU

Package definitions for this version as obtained automatically from the Universes server.

To override the definitions in the univere add to my subclass in PackagesSqueak310

To re-read the package definitions from the universes server.

self taskGeneratePackageTasks run

--