Dear All,
For those not familiar with the idea, Sake is an attempt to provide similar functionality to Make and Rake, only using Smalltalk as the DSL. I hope that Sake is simple and sufficiently useful for all Squeak forks make use of it. I apologize that I havent had any time to document Sake in detail, as I would normally do... however I would like to show an example of Sake/Packages. Sake/Packages is a reimplementation of Universes, using Sake. Given the recent announcement that the 310 universe is now closed, I think it is time for Sake/Packages to come into its own, since it provides the same functionality, from the same data, but is not closed, nor is editing restricted in any way. Also the Sake definition of a universe is simply a class, so you can subclass it in any way that you wish for your own projects. Below is a SakeTask as generated from the universes package definition. What follows is a "method", in the class PackagesSqueak310U. So here is a Sake Task Definition for Seaside.... (info is simply a dictionary for non-essential meta information) ---------- PackagesSqueak310U -i- Seaside self name: 'Seaside'. info category: 'Web Development'. info description: 'A framework for building sophisticated web applications in Squeak. Develop for the web using reusable, embeddable components and unique call/return semantics for moving between pages.'. info maintainer: 'Lukas Renggli <[hidden email]>'. info homepage: 'http://www.seaside.st/'. info squeakMapID: ''. info url: 'http://www.squeaksource.com/Seaside/Seaside2.8a1-lr.522.mcz'. info version: '2.8.522'. info provides: #(). self dependsOn: #('KomHttpServer'). self load: [ Installer installUrl:'http://www.squeaksource.com/Seaside/Seaside2.8a1-lr.522.mcz'. ]. self unloadDependsOn: { self taskUnloadDependants }. self unload: [ Installer unload: 'Seaside'. ]. ------------- Notice that we have an unload block as well as a load block! This is a new and very experimental feature, we can now define unload scripts for each package, and Sake/Packages provides a way to capture and publish them for some or all image versions. Indeed this feature is barely tested, I mention it here simply to intoduce the concept. usage: PackagesSqueak310 new Seaside load. or, (PackagesSqueak310 named:'Seaside') load. PackagesSqueak310 new Seaside unload. or, (PackagesSqueak310 named:'Seaside') unload. Packages/Sake is also supported by Installer in a manner similar to universes support, e.g. Installer sake addPackage: 'PackagesA'; addPackage: 'PackageB'; install. enjoy... best regards Keith p.s. to load Installer install: 'Packages'. |
2008/4/9 Keith Hodges <[hidden email]>:
> Dear All, > > For those not familiar with the idea, Sake is an attempt to provide similar > functionality to Make and Rake, only using Smalltalk as the DSL. I hope that > Sake is simple and sufficiently useful for all Squeak forks make use of it. > > I apologize that I havent had any time to document Sake in detail, as I > would normally do... however I would like to show an example of > Sake/Packages. Sake/Packages is a reimplementation of Universes, using > Sake. > > Given the recent announcement that the 310 universe is now closed, I think > it is time for Sake/Packages to come into its own, since it provides the > same functionality, from the same data, but is not closed, nor is editing > restricted in any way. Also the Sake definition of a universe is simply a > class, so you can subclass it in any way that you wish for your own > projects. > > Below is a SakeTask as generated from the universes package definition. > What follows is a "method", in the class PackagesSqueak310U. > > So here is a Sake Task Definition for Seaside.... (info is simply a > dictionary for non-essential meta information) > > ---------- > > PackagesSqueak310U -i- Seaside > > self name: 'Seaside'. > info category: 'Web Development'. > info description: > 'A framework for building sophisticated web applications in Squeak. Develop > for the web using reusable, embeddable components and unique call/return > semantics for moving between pages.'. > info maintainer: 'Lukas Renggli <[hidden email]>'. > info homepage: 'http://www.seaside.st/'. > info squeakMapID: ''. > info url: 'http://www.squeaksource.com/Seaside/Seaside2.8a1-lr.522.mcz'. > info version: '2.8.522'. > info provides: #(). > > self dependsOn: #('KomHttpServer'). > > self load: [ > Installer > installUrl:'http://www.squeaksource.com/Seaside/Seaside2.8a1-lr.522.mcz'. > ]. > > self unloadDependsOn: { self taskUnloadDependants }. > self unload: [ > Installer unload: 'Seaside'. > ]. > What i like in above, that it's self-explanatory, easy to find and don't requires extra UI/GUI to manage package. Any developer can describe/define own package in a few minutes as simple as writing a method! Just choose appropriate name for a method, like #packageConfiguration. Then anyone can browse all packages by hitting implementors. :) > ------------- > > Notice that we have an unload block as well as a load block! This is a new > and very experimental feature, we can now define unload scripts for each > package, and Sake/Packages provides a way to capture and publish them for > some or all image versions. Indeed this feature is barely tested, I mention > it here simply to intoduce the concept. > > usage: > > PackagesSqueak310 new Seaside load. or, (PackagesSqueak310 > named:'Seaside') load. > PackagesSqueak310 new Seaside unload. or, (PackagesSqueak310 > named:'Seaside') unload. > > Packages/Sake is also supported by Installer in a manner similar to > universes support, e.g. > > Installer sake addPackage: 'PackagesA'; addPackage: 'PackageB'; install. > > enjoy... > > best regards > > Keith > > p.s. to load > > Installer install: 'Packages'. > > -- Best regards, Igor Stasenko AKA sig. |
On Wed, Apr 9, 2008 at 8:21 AM, Igor Stasenko <[hidden email]> wrote:
> What i like in above, that it's self-explanatory, easy to find and > don't requires extra UI/GUI to manage package. But users needs a UI to install new packages. -- Damien Cassou Peter von der Ahé: «I'm beginning to see why Gilad wished us good luck». (http://blogs.sun.com/ahe/entry/override_snafu) |
In reply to this post by keith1y
On Wed, Apr 9, 2008 at 1:50 AM, Keith Hodges <[hidden email]> wrote:
Dear All, At work, we built something very similar to this...what you call a SakeTask is similar to what we call a target. We define them a bit differently however and our targets produce one or more files in the file system. A target is defined by writing a method with a special pragma (this is VisualWorks). The pragma typically specifies prerequisite targets (names of methods that return a filename) as well as its product (usually just one method that specifies the name of some file produced). The body of the method then does the work of producing the target (producing a tarball is a typical example). A slight variation on a target is one that transforms an image...you provide the name of a starting image and it launches that image, shuffles the code in the method over to it, runs that code, then snapshots the image as the filename specified as the product of the target. The build system just checks to see whether a target's product exists on disk to determine whether that target has already been produced or not. The classes and methods defining targets and the code implementing the build system are all versioned along with our product's code so that everything is highly reproducible. Only a small bit of bootstrapping logic lives outside. On launching a build, we gather all the methods implementing these pragmas, create instances of a target class, and construct a dependency graph and begin building the requested targets. This system has served us well for several years now.
I think a target/task boils do to the following operations: prerequisites (identifiers of prerequisite tasks), product (some kind of identifier) do, isDone, and undo (though we do not have that in our system). Does SakeTask have any means of testing isDone? Also, is it generalized to the degree that do and undo actions could perform pretty much any action (i.e. actions in the file system) and not be tied to a concept of code packages?
In any case, this looks promising. - Stephen |
In reply to this post by Igor Stasenko
On Wed, Apr 9, 2008 at 2:21 AM, Igor Stasenko <[hidden email]> wrote:
What i like in above, that it's self-explanatory, easy to find and I don't think whether something requires an extra GUI or not should weigh heavily in evaluating something. With a better browser, you could accomodate a greater variety of things. Years ago, similar thinking led to the use of classes and inheritance to define exception hierarchies and I think that was a mistake. I implemented the original exception handling system for ObjectStudio and I patterned it after the VisualWorks instance based approach (it was instance based then, a sort of hybrid now). Then the ANSI standard came along and I re-implemented it on the theory that standards compliance was of greater importance. But, I felt, and still feel that the instance based approach that VisualWorks had originall was simpler and superior despite not being browser friendly.
- Stephen |
In reply to this post by Damien Cassou-3
2008/4/9 Damien Cassou <[hidden email]>:
> On Wed, Apr 9, 2008 at 8:21 AM, Igor Stasenko <[hidden email]> wrote: > > What i like in above, that it's self-explanatory, easy to find and > > don't requires extra UI/GUI to manage package. > > But users needs a UI to install new packages. > Yes, of course but it's more or less trivial - show a list and add some actions. What is not trivial is to create UI to build own packages, when developer need to create new package and include all required info. This is unnecessary if developer simply needs to define a method which describes package. It is also can be extended very simply. Suppose i want to include information that given package is successor of older package and provides similar functionality but with new design under new brand. It could be done as simple as writing: info ancestors: #( 'Foo' ). Adding maturity level: info maturity: #beta. I didn't looked yet at Sake, but if each package contains something like 'printDescription: stream' method, again, it's easy for developer to override this method and include new fields which will be showed to users. > > -- > Damien Cassou > Peter von der Ahé: «I'm beginning to see why Gilad wished us good > luck». (http://blogs.sun.com/ahe/entry/override_snafu) > > > > -- Best regards, Igor Stasenko AKA sig. |
In reply to this post by Damien Cassou-3
Damien Cassou wrote:
> On Wed, Apr 9, 2008 at 8:21 AM, Igor Stasenko <[hidden email]> wrote: > >> What i like in above, that it's self-explanatory, easy to find and >> don't requires extra UI/GUI to manage package. >> > > But users needs a UI to install new packages. > Do they? It has a command line/code UI. Perhaps you mean a GUI. For the most part I would expect end users to have images that are already configured to perform the task that they are interested in. Overall "we" have had a stated intention to move to more minimal images, and have kernel images which dont have GUI's at all. In this instance a solution that can work in a minimal environment is useful. GUI based tools have been a bottleneck in enabling new GUI frameworks to gain acceptance e.g. tweak. So having a GUI is a significant disadvantage. GUI tools have been a big source of bugs, remember the transparent SqueakMap Package loader. An additional UI is available since with Launcher a predefined set of packages can be built into an image by passing command line params at startup. For production work the process of building a complex image is best handles by Installer scripts (or similar) anyhow. Poking around or scripting UI's is slow and difficult to automate. so all in all, I dont see the lack of GUI as a great disadvantage. However, if SakeTasks (or similar) catches on, then perhaps a "run task" menu item may be added to class browsers. best regards Keith |
In reply to this post by Stephen Pair
Dear Stephen,
thanks for your feedback and ideas. Stephen Pair wrote: > On Wed, Apr 9, 2008 at 1:50 AM, Keith Hodges <[hidden email] > <mailto:[hidden email]>> wrote: > > Dear All, > > For those not familiar with the idea, Sake is an attempt to > provide similar functionality to Make and Rake, only using > Smalltalk as the DSL. I hope that Sake is simple and sufficiently > useful for all Squeak forks make use of it. > > > At work, we built something very similar to this...what you call a > SakeTask is similar to what we call a target. We define them a bit > differently however and our targets produce one or more files in the > file system. to work with Files... for example... Class ensure: #Object hasSubclass: #MyClass. Is a SakeTask which defines a non-file based target, and will create the subclass if it does not already exist. The api for this kind of task still up for debate, perhaps it would read better as a method on SakeTask, or a class called ClassTask. (opinions?) You can then define a task depending upon the target like so: myTask ^ SakeTask new: [ :task | task dependsOn: { Class ensure: #Object hasSubclass: #MyClass. }. task if: [ true ]. "basic isDone functionality" task action: [ ..... ] ] > A target is defined by writing a method with a special pragma (this is > VisualWorks). The pragma typically specifies prerequisite targets > (names of methods that return a filename) as well as its product > (usually just one method that specifies the name of some file produced). My plan is for the package Rio, to be the basis of File based targets... I have yet to work out the details, but the objective would be to achieve the same kind of functionality as Rake does with its specialised Directory classes. > The body of the method then does the work of producing the target > (producing a tarball is a typical example). A slight variation on a > target is one that transforms an image...you provide the name of a > starting image and it launches that image, shuffles the code in the Transforming image files, i.e building image files is also on the list, and was part of Sake's ruby based predecessor. To be known as "Bob", (the builder). > method over to it, runs that code, then snapshots the image as the > filename specified as the product of the target. The build system > just checks to see whether a target's product exists on disk to > determine whether that target has already been produced or not. The > classes and methods defining targets and the code implementing the > build system are all versioned along with our product's code so that > everything is highly reproducible. Only a small bit of bootstrapping > logic lives outside. On launching a build, we gather all the methods > implementing these pragmas, create instances of a target class, and > construct a dependency graph and begin building the requested targets. > This system has served us well for several years now > I think a target/task boils do to the following operations: > prerequisites (identifiers of prerequisite tasks), product (some kind > of identifier) do, isDone, and undo (though we do not have that in our > system). The #unload functionality is implemented in Packages, rather than being an inherent feature of Sake. unload simply swaps the undoAction for the doAction block before running the task, so Sake is none the wiser. > Does SakeTask have any means of testing isDone? A task will not run, if it has already run in the invocation. When a task is run, its priorTasks are run first. Then a task consults its ifBlock (default being true) before actually doing the task. hmm, perhaps I might enable multiple actions to give case-statement like behaviour... task if: [ this ] do: [ that ]. task if: [ theOther ] do: [ somethingElse ]. Subclasses of SakeTask, i.e. SakeFileTask are able to consult the priorTasks' results in order to determine whether of not the task isNeeded. for example SakeFileTask includes the following test... isNeeded: runPriorTasks .... (runPriorTasks noneSatisfy: [ :each | each isNewerThan: self timeStamp ]) ifTrue: [ ^ false ]. .... > Also, is it generalized to the degree that do and undo actions could > perform pretty much any action (i.e. actions in the file system) and > not be tied to a concept of code packages? the undo concept is currently only part of the Packages system, since the undo-dependancies rely upon knowing the full history of which packages were loaded afterwards. > In any case, this looks promising. > > - Stephen thanks for your detailed reply Keith |
In reply to this post by keith1y
Hello All,
The Sake/Packages unloading process should now be functional, though the recommended usage is slightly changed. enjoy Keith ----------------- (from the class comment) Sake/Packages usage: Public API ============ "load package definition for your current version of Squeak" (Packages current load: 'Seaside') run. " or runQuietly, runStepping, runLogging" (Packages currentBeta load: 'Seaside') run. multiples: (Packages current load: #('Seaside' 'Magma' 'Logging') ) run. Run-variants ========= #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. 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') runStepping. Then the 'historical' unload scripts are used, as defined when the original load tasks were run. If instead you perform: (Packages current named: 'Seaside') unload 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') run. Will unload whichever of the two are loaded. ===== |
Free forum by Nabble | Edit this page |