A new version of Packages-Library was added to project Packages:
http://www.squeaksource.com/Packages/Packages-Library-kph.89.mcz
==================== Summary ====================
Name: Packages-Library-kph.89
Author: kph
Time: 7 July 2009, 5:34:43 pm
UUID: 6f2598d3-3dcd-4fac-a9e2-bfbb531e8a95
Ancestors: Packages-Library-kph.88
regenerated for TestDriveBeachSeaside
=============== Diff against Packages-Library-kph.88 ===============
Item was changed:
----- Method: PackagesDevU>>SakeScheduler (in category 'Group Development') -----
SakeScheduler
self name: 'Sake-Scheduler'.
+ self version: '11'.
- self version: '10'.
info category: 'Group Development'.
info description:
'Periodic actions, with logging support'.
info maintainer: 'Keith Hodges'.
info homepage: 'http://wiki.squeak.org/squeak/5953'.
info squeakMapID: ''.
+ info url: 'http://www.squeaksource.com/Sake/Sake-Scheduler-kph.11.mcz'.
- info url: 'http://www.squeaksource.com/Sake/Sake-Scheduler-kph.10.mcz'.
self provides: #('Sake-Scheduler').
self dependsOn: #('Logging').
!
Item was changed:
----- Method: PackagesDevU>>Monticello15 (in category 'Group Development') -----
Monticello15
self name: 'Monticello15'.
self version: '1.5+'.
info category: 'Group Development'.
info description:
'Monticello - evolution - Improvements over 1.0
- Method/Class Orphanage which enables out-of-order loading of packages, and maintenance of packages whose dependencies have not been loaded.
- Method Overrides (if properly categorized) are fully supported preserving the integrity of a package even if it has overridden methods
- Refactored UI/repository classes so that one UI heirachy serves all.
- Dual Changes Browser
- In memory cache repository
- Support for configurations (Please name them using the MC conventions)
- Support for more complex version numbering conventions i.e. Package-kph-1.0.3.mcz
known problems:
methods have been known to loose their categories
future:
Atomic Loading loader using System Editor is already coded and contained in this release.
See #theChosenLoaderClass.
'.
info maintainer: 'kph <keith_hodges(a)yahoo.co.uk>'.
info homepage: ''.
info squeakMapID: ''.
info url: 'http://ftp.squeak.org/3.11/scripts/mc15.st'.
+ self provides: #('PackageInfo-Base' 'Installer' 'MonticelloConfigurations' 'Monticello15').
- self provides: #('Monticello15' 'Installer' 'MonticelloConfigurations' 'PackageInfo-Base').
self dependsOn: #().
!
Item was changed:
----- Method: PackagesDevU>>ProcessSpecific (in category 'System') -----
ProcessSpecific
self name: 'ProcessSpecific'.
+ self version: '1.0.22'.
- self version: '1.0.19'.
info category: 'System'.
info description:
'My subclasses (not instances of them) keep state specific to the current process.
There are two kinds of process-specific variables: process-local (state available
for read and write in all methods inside the process), and dynamic variables
(implementing dynamic scope).
Includes tests and example: DateAndTimeWarp
Includes extension (if not loaded ignore) for seaside for debugging.'.
info maintainer: 'keith_hodges(a)yahoo.co.uk'.
info homepage: ''.
info squeakMapID: ''.
+ info url: 'http://www.squeaksource.com/Logging/ProcessSpecific-kph.22.mcz'.
- info url: 'http://www.squeaksource.com/Logging/ProcessSpecific-kph.19.mcz'.
self provides: #('ProcessSpecific').
self dependsOn: #().
!
Item was changed:
----- Method: PackagesDevU>>Seaside28Jetsam (in category 'Web Development') -----
Seaside28Jetsam
self name: 'Seaside28Jetsam'.
+ self version: '2.8.547'.
- self version: '2.8.546'.
info category: 'Web Development'.
info description:
'Patches to the base seaside
The version number indicates the version of seaside this is synced with.'.
info maintainer: 'kph'.
info homepage: 'http://www.squeaksource.com/Jetsam.html'.
info squeakMapID: ''.
+ info url: 'http://www.squeaksource.com/Jetsam/Seaside28Jetsam-kph.79.mcz'.
- info url: 'http://www.squeaksource.com/Jetsam/Seaside28Jetsam-kph.67.mcz'.
self provides: #('Seaside28Jetsam-Useful-CSS' 'Seaside28Jetsam-NiftyCorners' 'Seaside28Jetsam' 'Seaside28Jetsam-Supersleight' 'Seaside28Jetsam-Blueprint').
self dependsOn: #('M7219-StreamsReadability' 'M7284-firsOrNil' 'Seaside').
!
Item was changed:
----- Method: PackagesDev>>MysqlDriver (in category 'Group Development') -----
MysqlDriver
super MysqlDriver
+ "it doesnt really depend upon cryptography at all"
+ self dependsOn: { '7319 Integer asByteArray' }.
+
self mcName: 'Mysql'.
!
Item was added:
+ ----- Method: PackagesDevU>>Seaside28JetsamDebugging (in category 'Web Development') -----
+ Seaside28JetsamDebugging
+
+ self name: 'Seaside28Jetsam-Debugging'.
+ self version: '0.3'.
+ info category: 'Web Development'.
+ info description:
+ 'Additional debugging hooks'.
+ info maintainer: 'kph'.
+ info homepage: 'http://www.squeaksource.com/Jetsam.html'.
+ info squeakMapID: ''.
+ info url: 'http://www.squeaksource.com/Jetsam/Seaside28Jetsam-Debugging-kph.3.mcz'.
+ self provides: #().
+
+ self dependsOn: #('Seaside').
+
+ !
Item was changed:
----- Method: PackagesDevU>>Logging (in category 'Development') -----
Logging
self name: 'Logging'.
+ self version: '3.52'.
- self version: '3.44'.
info category: 'Development'.
info description:
'Logging for squeak, a front end to Toothpick OR SimpleLog (apologies to LogEngine)
usage:
self log this.
self log x: 10 y: 20.
and much more...
'.
info maintainer: 'Keith Hodges <keith_hodges(a)yahoo.co.uk>'.
info homepage: 'http://wiki.squeak.org/squeak/3706'.
info squeakMapID: '6c1b03cd-6c37-4acf-b971-72ff132c03f0'.
+ info url: 'http://www.squeaksource.com/Logging/Logging-FT.52.mcz'.
- info url: 'http://www.squeaksource.com/Logging/Logging-kph.44.mcz'.
self provides: #('Logging').
self dependsOn: #('ProcessSpecific' 'StreamsReadability').
!
Item was added:
+ ----- Method: PackagesDevU>>Seaside28JetsamHelpers (in category 'Web Development') -----
+ Seaside28JetsamHelpers
+
+ self name: 'Seaside28Jetsam-Helpers'.
+ self version: '0.4'.
+ info category: 'Web Development'.
+ info description:
+ 'Session and Frame Helpers'.
+ info maintainer: 'kph'.
+ info homepage: 'http://www.squeaksource.com/Jetsam.html'.
+ info squeakMapID: ''.
+ info url: 'http://www.squeaksource.com/Jetsam/Seaside28Jetsam-Helpers-kph.4.mcz'.
+ self provides: #().
+
+ self dependsOn: #('Seaside').
+
+ !
A new version of Sake-Packages was added to project Packages:
http://www.squeaksource.com/Packages/Sake-Packages-kph.35.mcz
==================== Summary ====================
Name: Sake-Packages-kph.35
Author: kph
Time: 3 July 2009, 3:41:07 am
UUID: a990f820-a0f7-42af-a596-1e7907797013
Ancestors: Sake-Packages-kph.34
Seaside 29 packages included here and tested loading and unloading
=============== Diff against Sake-Packages-kph.34 ===============
A new version of Sake-Packages was added to project Packages:
http://www.squeaksource.com/Packages/Sake-Packages-kph.34.mcz
==================== Summary ====================
Name: Sake-Packages-kph.34
Author: kph
Time: 3 July 2009, 3:40 am
UUID: 56810f94-8da0-4fe2-81ce-8cd9a1dbc7c0
Ancestors: Sake-Packages-kph.33
defaultAction sets hasRun so that appended actions may depend upon this task
=============== Diff against Sake-Packages-kph.33 ===============
Item was changed:
----- Method: Packages>>doActionStep: (in category 'as yet unclassified') -----
doActionStep: priorTasks
super doActionStep: priorTasks.
name ifNil: [ ^ self ].
self isUnloading
ifTrue: [ self step: 'Confirm unload: ', self name printString ]
ifFalse: [ self step: 'Confirm load: ', self name printString ]!
Item was changed:
----- Method: Packages class>>unload: (in category 'public') -----
unload: aNameOrList
+ aNameOrList isString ifTrue: [ ^ (self named: aNameOrList) beUnloading run].
- aNameOrList isString ifTrue: [ ^ (self providedAt: aNameOrList) beUnloading run].
+ ^ (aNameOrList collect: [ :ea | (self named: aNameOrList) beUnloading ]) asTask run
- ^ (aNameOrList collect: [ :ea | (self providedAt: aNameOrList) beUnloading ]) asTask run
!
Item was changed:
----- Method: Packages>>dependsOn (in category 'as yet unclassified') -----
dependsOn
self isUnloading ifFalse: [ ^ super dependsOn ].
+
-
unloadPriors ifNil: [ self unloadDependsOn: self loadedDependantsUnloadTasks ].
^ unloadPriors!
Item was changed:
----- Method: Packages>>defaultUnloadAction (in category 'defaults') -----
defaultUnloadAction
+ ^ [ Installer mc unload: self mcName ]!
- Installer mc unload: self mcName!
Item was changed:
----- Method: Packages>>doActionEnd (in category 'as yet unclassified') -----
doActionEnd
+
- self isUnloading ifTrue: [ ^ self ].
self class provided in: [ :reg |
+ self isUnloading ifTrue: [ ^ reg removeKey: self name ].
+
info dependsOn: (self dependsOn collect: [ :ea | ea asString ]).
info provides: self provides.
info class: self class name.
self provides do: [ :each | reg at: each put: info ].
].
self addToPackageInfo.
!
Item was changed:
+ ----- Method: Packages>>beUnloading (in category 'defaults') -----
- ----- Method: Packages>>beUnloading (in category 'mode') -----
beUnloading
isUnload := true.
+ hasRun := false.
+ actionBlock := self defaultUnloadAction.!
- hasRun := false.!
Item was added:
+ ----- Method: Packages class>>latest: (in category 'public') -----
+ latest: aNameOrList
+
+ ^ (self named: aNameOrList) beLatest run!
Item was changed:
----- Method: Packages>>loadedDependants (in category 'as yet unclassified') -----
loadedDependants
+ | ds |
^ self class provided select: [ :dependant |
+ ds := dependant dependsOn.
+
+ ds ifNil: [ false ] ifNotNil: [ ds includesAnyOf: self provides ] .
- dependant dependsOn includesAnyOf: self provides.
].
+
+
!
Item was changed:
----- Method: Packages>>versionIndefinite (in category 'accessing') -----
versionIndefinite
+ (self version last ~= $+) ifTrue: [ version := self version, '+'].
- (self version last ~= $+) ifTrue: [ self version: self version, '+'].
!
Item was changed:
----- Method: Packages>>defaultLatestAction (in category 'defaults') -----
defaultLatestAction
+ ^ [ self info url ifNotNilDo: [ :url | (Installer fromUrl: url) latest install ].
+ self hasRunSet. ]!
- ^ [ self info url ifNotNilDo: [ :url | (Installer fromUrl: url) latest install ] ]!
Item was changed:
----- Method: Packages>>loadedDependantsUnloadTasks (in category 'as yet unclassified') -----
loadedDependantsUnloadTasks
"if the task is the provided one, then we return the provided dependants."
+ ^ self loadedDependants collect: [ : ea | (self class named: ea name) beUnloading ]!
- self loadedDependants in: [ :deps |
-
- deps ifEmpty: [ ^ #() ].
-
- ^ (self class provided at: self name ifAbsent: nil) == self
- ifTrue: [ (deps collect: [ :ea | ea copy beUnloading ]) ]
- ifFalse: [ (deps collect: [ : ea | (self class named: ea name) beUnloading ]) ]
- ].!
Item was changed:
----- Method: Packages>>defaultAction (in category 'defaults') -----
defaultAction
+ ^ [ self info url ifNotNilDo: [ :url | (Installer fromUrl: url) install ].
+ self hasRunSet. ]!
- ^ [ self info url ifNotNilDo: [ :url | (Installer fromUrl: url) install ] ]!
Item was changed:
----- Method: Packages class>>basicNamed: (in category 'private') -----
basicNamed: packageName
+ ^ (self basicNew perform: (self asSelector: packageName)) initialize; yourself!
- ^ self basicNew perform: (self asSelector: packageName); initialize; yourself!
Item was changed:
SakeTask subclass: #Packages
+ instanceVariableNames: 'unload latest useLatest unloadPriors provides requires name mcName version isUnload'
- instanceVariableNames: 'unload latest useLatest unloadPriors provides name mcName version isUnload'
classVariableNames: 'Provided'
poolDictionaries: ''
category: 'Sake-Packages'!
Packages class
instanceVariableNames: 'lastUpdate theUUniverse'!
!Packages commentStamp: 'kph 7/1/2009 03:03' prior: 0!
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.!
A new version of Sake-Core was added to project Sake :
http://www.squeaksource.com/Sake/Sake-Core-kph.108.mcz
==================== Summary ====================
Name: Sake-Core-kph.108
Author: kph
Time: 3 July 2009, 3:37:12 am
UUID: f04a1c2f-813d-46ba-9df4-363a33a5a851
Ancestors: Sake-Core-kph.107
+ tasks are always realised through tasksFromList:
+ The setOfTasks is propagated to actions as well as priors, enabling actions dependents to work
+ what handles dependency loops better
=============== Diff against Sake-Core-kph.107 ===============
Item was changed:
----- Method: SakeTask>>hasRun (in category 'as yet unclassified') -----
hasRun
+ ^ hasRun = true!
- ^ hasRun ifNil: [ false ]!
Item was changed:
----- Method: SakeTask>>tasksFromList: (in category 'as yet unclassified') -----
tasksFromList: list
+ | newTask |
+ ^ (list ifNil: [ ^ #()]) collect: [ :task |
+
+ newTask := (self taskFrom: task) withExtensions.
+
+ (setOfTasks like: newTask) ifNil: [ setOfTasks add: newTask ].
+
+ ]
- ^ (list ifNil: [ ^ #()]) collect: [ :task | (self taskFrom: task) withExtensions ]
!
Item was added:
+ ----- Method: SakeTask>>privateRun (in category 'as yet unclassified') -----
+ privateRun
+
+ | priorTasks blocked wasBlocked |
+
+ "this is the way that Rake orders tasks"
+
+ "we ensure that we obtain the task to run from the overall set of tasks"
+
+ self hasRun ifTrue: [ ^ result ].
+
+ priorTasks := self tasksFromList: self dependsOn.
+
+ "anyting it runs that is blocked is added to the block set, anything that suceeds is removed form the blocked set.
+ at the end, we shall have a list of blocked tasks that can be retried, if that list is the same as the list that was blocked
+ before stop and complain"
+
+ blocked := Set new.
+
+ [
+ wasBlocked := blocked copy.
+
+ priorTasks do: [ :each |
+ each runLevel: runLevel.
+ [
+ each useSetOfTasks: setOfTasks during: [ each privateRun].
+ blocked remove: each ifAbsent: [ ].
+ ] on: SakeBlock do: [ :ex | blocked add: ex task ].
+ ].
+
+ (blocked notEmpty and: [ blocked = wasBlocked ]) ifTrue: [ SakeBlock signalTask: self ].
+
+ ] doWhileFalse: [ blocked isEmpty ].
+
+
+ (self isNeeded: priorTasks)
+ ifTrue: [
+ self trace.
+ self doAction: priorTasks.
+ self hasRunSet.
+
+ ^ result.
+ ].
+
+ ^ false
+ !
Item was changed:
----- Method: SakeTask>>what (in category 'coercion') -----
what
+ ^ self whatOn: Set new!
- | what |
- what := SakeWhat new.
-
- what task: self.
-
- ifBlock ifNotNil: [
- ( ifBlock isBlock )
- ifTrue: [ what if: ifBlock decompileString ]
- ifFalse: [
- what if: ((self tasksFromList: ifBlock) collect: [ :ea | ea what ]).
- ].
- ].
-
- what prior: (self priorTasks collect: [ :ea | ea what ]).
-
- (self action respondsTo: #decompileString)
- ifTrue: [ what action: self action decompileString ]
- ifFalse: [
- what action: ((self tasksFromList: self action) collect: [ :ea | ea what ]).
- ].
-
- ^ what!
Item was added:
+ ----- Method: SakeTask>>whatOn: (in category 'coercion') -----
+ whatOn: set
+
+ | what |
+ what := SakeWhat new.
+
+ set add: self.
+
+ what task: self.
+
+ ifBlock ifNotNil: [
+ ( ifBlock isBlock )
+ ifTrue: [ what if: ifBlock decompileString ]
+ ifFalse: [
+ what if: ((self tasksFromList: ifBlock) collect: [ :ea |
+ ea whatOn: set ]).
+ ].
+ ].
+
+ what prior: (self priorTasks collect: [ :ea | (set includes: ea) ifFalse: [ ea whatOn: set ]]).
+
+ (self action respondsTo: #decompileString)
+ ifTrue: [ what action: self action decompileString ]
+ ifFalse: [
+ what action: ((self tasksFromList: self action) collect: [ :ea | ea whatOn: set ]).
+ ].
+
+ ^ what!
Item was added:
+ ----- Method: SakeTask>>useSetOfTasks:during: (in category 'as yet unclassified') -----
+ useSetOfTasks: aSetOfTasks during: aBlock
+
+ | old |
+
+ [
+ old := setOfTasks.
+
+ setOfTasks := aSetOfTasks.
+
+ ^ aBlock value.
+
+ ] ensure: [ setOfTasks := old ].!
Item was changed:
Object subclass: #SakeTask
+ instanceVariableNames: 'args context info priors ifBlock actionBlock answers hasRun result runLevel target author setOfTasks'
- instanceVariableNames: 'args context info priors ifBlock actionBlock answers hasRun result runLevel target author'
classVariableNames: 'LastStatus Count'
poolDictionaries: ''
category: 'Sake-Core'!
SakeTask class
instanceVariableNames: 'status'!
!SakeTask commentStamp: 'kph 4/22/2008 22:42' prior: 0!
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"
}
].
!
Item was changed:
----- Method: SakeTask>>doTasks: (in category 'as yet unclassified') -----
doTasks: list
+ (self tasksFromList: list) do: [ :task |
+ task useSetOfTasks: setOfTasks during: [
+ result := task perform: runLevel
+ ].
+ ].
- (self tasksFromList: list) do: [ :task | result := task perform: runLevel ].
!
Item was changed:
----- Method: SakeTask>>runInteractively (in category 'running') -----
runInteractively
runLevel ifNil: [ runLevel := #runInteractively ].
+ ^ self useSetOfTasks: (setOfTasks ifNil: [ self withAllPriorTasks ]) during: [ self privateRun ]!
- ^ self privateRun: (self withAllPriorTasks)!
Item was added:
+ ----- Method: SakeTask>>hasRunSet (in category 'as yet unclassified') -----
+ hasRunSet
+
+ hasRun := true!
Item was removed:
- ----- Method: SakeTask>>privateRun: (in category 'as yet unclassified') -----
- privateRun: setOfTasks
-
- | priorTasks blocked wasBlocked |
-
- "this is the way that Rake orders tasks"
-
- "we ensure that we obtain the task to run from the overall set of tasks"
-
- self hasRun ifTrue: [ ^ result ].
-
- priorTasks := self dependsOn collect: [ :prior | setOfTasks like: (self taskFrom: prior) ] thenSelect: [ :ea | ea notNil ].
-
- "anyting it runs that is blocked is added to the block set, anything that suceeds is removed form the blocked set.
- at the end, we shall have a list of blocked tasks that can be retried, if that list is the same as the list that was blocked
- before stop and complain"
-
- blocked := Set new.
-
- [
- wasBlocked := blocked copy.
-
- priorTasks do: [ :each |
- each runLevel: runLevel.
- [
- each privateRun: setOfTasks.
- blocked remove: each ifAbsent: [ ].
- ] on: SakeBlock do: [ :ex | blocked add: ex task ].
- ].
-
- (blocked notEmpty and: [ blocked = wasBlocked ]) ifTrue: [ SakeBlock signalTask: self ].
-
- ] doWhileFalse: [ blocked isEmpty ].
-
-
- (self isNeeded: priorTasks)
- ifTrue: [
- self trace.
- self doAction: priorTasks.
- hasRun := true.
-
- ^ result.
- ].
-
- ^ false
- !