'From Squeak3.9gamma of ''23 July 2006'' [latest update: #7064] on 7 November 2006 at 7:09:55 pm'!
Object subclass: #Installer
instanceVariableNames: 'sm wsm mc ma url user markers password project package bug answers packages messagesToSuppress'
classVariableNames: ''
poolDictionaries: ''
category: 'Installer-Core'!
!Installer commentStamp: 'kph 11/7/2006 05:45' prior: 0!
Installer provides a simple Domain Specific Language for installing packages from monticello and squeakmap of various version.
One design decision is to be able to paste scripts a workspace and run and tested from there without any special editing.
Examples - Using SqueakMap
1)
squeakmap := Installer squeakmap.
squeakmap install: 'DynamicBindings'.
squeakmap open.
2)
Installer squeakmap install: 'DynamicBindings'.
3) Alternatively using websqueakmap
squeakmap := Installer websqueakmap.
squeakmap package: 'DynamicBindings'; install.
Examples - Using Monticello
1)
squeaksource := Installer repository: 'http://www.squeaksource.com'.
seaside := squeaksource project: 'Seaside'.
seaside install: 'Comet-lr.8';
install: 'Scriptaculous'.
2)
squeaksource := Installer repository: 'http://www.squeaksource.com'
squeaksource project: 'Seaside';
install: 'Comet-lr.8;
install: 'Scriptaculous'.
Examples - install straight from a url
1a)
(Installer url: 'http://minnow.cc.gatech.edu/squeak/uploads/5889/MakeTestsGreen39.cs') install.
1b)
Installer installUrl: 'http://minnow.cc.gatech.edu/squeak/uploads/5889/MakeTestsGreen39.cs'.
2)
| page |
page := Installer url: 'http://minnow.cc.gatech.edu/squeak/uploads/5889/'.
page package: 'MakeTestsGreen39.cs'.
page install.
3)
In html page scripts are delimited by
| page |
page := Installer url: 'http://wiki.squeak.org/742'.
page install.
4)
specify your own delimeters
| page |
page := Installer url: 'http://wiki.squeak.org/742'.
page markers: 'begin>......' ]! !
!Installer methodsFor: 'accessing' stamp: 'kph 11/7/2006 05:06'!
markers: anObject
"Set the value of markers"
markers := anObject! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 06:38'!
mc
"Answer the value of mc"
^ mc! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/19/2006 07:07'!
mc: aUrl
"Set the value of host"
mc := aUrl last = $/ ifTrue: [ aUrl ] ifFalse: [ aUrl, '/' ]! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/17/2006 14:30'!
messagesToSuppress
^ messagesToSuppress ifNil: [ messagesToSuppress := OrderedCollection new ]! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/19/2006 06:55'!
messagesToSuppress: anObject
"Set the value of messagesToSuppress"
messagesToSuppress := anObject! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 07:59'!
open
self sm ifTrue: [ SMLoader open ].
self mc ifNotNil: [self mcRepository morphicOpen: nil ].! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 04:05'!
package
"Answer the value of package"
^ package! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 04:05'!
package: anObject
"Set the value of package"
package := anObject! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/21/2006 03:08'!
packages
self sm ifTrue: [ ^SMLoader new packages ].
self mc ifNotNil: [ ^self mcRepository allFileNames ].
self wsm ifNotNil: [ ^self wsmPackagesByName keys ].! !
!Installer methodsFor: 'accessing' stamp: 'kph 11/7/2006 05:06'!
packages: anObject
"Set the value of packages"
packages := anObject! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/21/2006 03:09'!
packagesMatching: aMatch
self sm ifTrue: [ ^ (self packages select: [ :p | aMatch match: p name ]) collect: [ :p | self copy package: p name; yourself ] ].
self mc ifNotNil: [ ^ (self packages select: [ :p | ( aMatch , '.mcz' ) match: p ]) collect: [ :p | self copy package: p ; yourself ] ].
self wsm ifNotNil: [ ^ (self packages select: [ :p | ( aMatch) match: p ]) collect: [ :p | self copy package: p ; yourself ] ].! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 04:16'!
password
"Answer the value of password"
^ password ifNil: [ '' ]! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 03:56'!
password: anObject
"Set the value of password"
password := anObject! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/21/2006 06:14'!
printOn: s
s nextPutAll: '(Installer'.
self sm ifTrue: [ s nextPutAll: ' squeakmap' ].
self ma ifNotNil: [ s nextPutAll: ' mantis' ].
self wsm ifNotNil: [ s nextPutAll: ' websqueakmap' ].
self mc ifNotNil: [ s nextPutAll: ' repository:''', self mc,'''' ].
s nextPut: $).
self project ifNotNil: [ s nextPutAll: ' project:';
nextPutAll: '''', self project, ''''.
self package ifNotNil: [ s nextPutAll: '; '] ].
self package ifNotNil: [ s nextPutAll: ' package:';
nextPutAll: '''', self package asString, '''' ].
s nextPut: $..! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 06:30'!
project
"Answer the value of project"
^ project! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 06:33'!
project: anObject
"Set the value of project"
project := anObject.
^self copy.! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 06:55'!
sm
"Answer the value of sm"
^ sm ifNil: [ false ]! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 06:38'!
sm: anObject
"Set the value of sm"
sm := anObject! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/17/2006 15:37'!
unload: workingCopyPackageName
self logCR: 'Unloading ', workingCopyPackageName.
(MCWorkingCopy forPackage: (MCPackage new name: workingCopyPackageName)) unload! !
!Installer methodsFor: 'accessing' stamp: 'kph 11/7/2006 04:23'!
url
^url! !
!Installer methodsFor: 'accessing' stamp: 'kph 11/7/2006 04:23'!
url: aUrl
url := aUrl! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 04:15'!
user
"Answer the value of user"
^ user ifNil: [ '' ]! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/15/2006 03:56'!
user: anObject
"Set the value of user"
user := anObject! !
!Installer methodsFor: 'accessing' stamp: 'kph 10/21/2006 05:50'!
versions
self sm ifTrue: [ ^self smVersions ].
self mc ifNotNil: [ ^self mcVersions ].
self wsm ifNotNil: [ ^self wsmVersions ].! !
!Installer methodsFor: 'monticello' stamp: 'kph 10/21/2006 06:53'!
mcInstall
| repository sortMczs files fileToLoad version detectFileBlock count |
self logCR: 'installing ', self package asString, '...'.
self package isString ifTrue: [ detectFileBlock := [ :file | file beginsWith: self package ] ].
(self package isKindOf: Array)
ifTrue: [ detectFileBlock := [ :file | (self package detect: [ :item | file beginsWith: item ] ifNone: [ false ]) ~= false ] ].
self package isBlock ifTrue: [ detectFileBlock := self package ].
repository := MCHttpRepository location: self mcUrl user: self user password: self password.
sortMczs := [:a :b |
[(a findBetweenSubStrs: #($.)) allButLast last asInteger > (b findBetweenSubStrs: #($.)) allButLast last asInteger] on: Error do: [:ex | false]].
"several attempts to read files - repository readableFileNames sometimes fails"
count := 0. fileToLoad := nil.
[count := count + 1.
(fileToLoad = nil) and:[ count < 5 ] ]
whileTrue: [
files := repository readableFileNames asSortedCollection: sortMczs.
fileToLoad := files detect: detectFileBlock ifNone: [ nil ].
].
version := repository versionFromFileNamed: fileToLoad.
version workingCopy repositoryGroup addRepository: repository.
repository creationTemplate: 'MCHttpRepository
location: ''', self mcUrl, '''
user: ''', self user, '''
password: ''', self password, ''''.
self log: ' ', version fileName, '...'.
self withAnswersDo: [ version load ].
self log: 'done'.
! !
!Installer methodsFor: 'monticello' stamp: 'kph 10/15/2006 07:59'!
mcRepository
^MCHttpRepository location: (self mcUrl) user: self user password: self password.! !
!Installer methodsFor: 'monticello' stamp: 'kph 10/15/2006 06:49'!
mcUrl
^ self mc, self project! !
!Installer methodsFor: 'monticello' stamp: 'kph 10/21/2006 05:47'!
mcVersions
^ (self packages select: [ :p | ( self package,'-*.mcz' ) match: p ]) collect: [ :p | self copy package: p ; yourself ].
! !
!Installer methodsFor: 'monticello' stamp: 'kph 10/21/2006 06:52'!
withAnswersDo: aBlock
(aBlock respondsTo: #valueSuppressingMessages:supplyingAnswers: )
ifTrue: [aBlock valueSuppressingMessages: self messagesToSuppress supplyingAnswers: self answers.]
ifFalse: [ aBlock value ]
! !
!Installer methodsFor: 'auto answering' stamp: 'kph 10/17/2006 13:07'!
answer: aString with: anAnswer
^self answers add: ( Array with: aString with: anAnswer )! !
!Installer methodsFor: 'auto answering' stamp: 'kph 10/17/2006 14:30'!
suppress: aMessage
messagesToSuppress add: aMessage! !
!Installer methodsFor: 'squeakmap' stamp: 'kph 10/21/2006 06:54'!
smInstall
| pkgAndVersion releases release |
pkgAndVersion := self smPackageAndVersion.
self logCR: 'installing ', self package, ' from SqueakMap...'.
releases := self smReleasesForPackage: pkgAndVersion first.
release := pkgAndVersion last isEmpty ifTrue: [ releases last ]
ifFalse:[ releases detect: [ :rel | rel version = pkgAndVersion last ] ].
self withAnswersDo: [ release install ].
self log: ' done'.
! !
!Installer methodsFor: 'squeakmap' stamp: 'kph 10/17/2006 15:24'!
smPackageAndVersion
| p |
p := ReadStream on: self package .
^Array with: (p upTo: $() with: (p upTo: $)).! !
!Installer methodsFor: 'squeakmap' stamp: 'kph 10/21/2006 06:09'!
smReleasesForPackage: name
^(SMSqueakMap default packageWithName: name) releases! !
!Installer methodsFor: 'squeakmap' stamp: 'kph 10/21/2006 06:12'!
smVersions
^ (self smReleasesForPackage: self package) collect: [ :p | self copy package: (p name,'(',p version,')'); yourself. ] ! !
!Installer methodsFor: 'websqueakmap' stamp: 'kph 10/21/2006 01:37'!
wsm
"Answer the value of wsm"
^ wsm! !
!Installer methodsFor: 'websqueakmap' stamp: 'kph 10/21/2006 01:37'!
wsm: aUrl
"Set the value of host"
wsm := aUrl last = $/ ifTrue: [ aUrl ] ifFalse: [ aUrl, '/' ]! !
!Installer methodsFor: 'websqueakmap' stamp: 'kph 11/7/2006 18:57'!
wsmDownloadUrl
| pkgAndVersion packageId packageName packageVersion releaseAutoVersion
downloadPage |
pkgAndVersion := self smPackageAndVersion.
packageName := pkgAndVersion first.
packageVersion := pkgAndVersion last.
packageVersion isEmpty ifTrue: [ packageVersion := #latest ].
packageId := self wsmPackagesByName at: packageName.
releaseAutoVersion := (self wsmReleasesFor: packageId) at: packageVersion.
downloadPage := HTTPSocket httpGet: (self wsm,'/package/',packageId,'/autoversion/', releaseAutoVersion).
^ downloadPage upToAll: 'Download:'; upToAll: 'href="'; upTo: $"
! !
!Installer methodsFor: 'websqueakmap' stamp: 'kph 11/7/2006 18:57'!
wsmInstall
| downloadUrl |
self logCR: 'finding ', self package, ' from websqueakmap(', self wsm, ') ...'.
downloadUrl := self wsmDownloadUrl.
self logCR: 'found at ', downloadUrl asString, ' ...'.
self install: downloadUrl fromStream: (HTTPSocket httpGet: downloadUrl).
! !
!Installer methodsFor: 'websqueakmap' stamp: 'kph 11/7/2006 18:54'!
wsmPackagesByName
| html id name |
packages ifNotNil: [ ^packages ].
packages := Dictionary new.
html := HTTPSocket httpGet: (self wsm, 'packagesbyname').
[
id := html upToAll: '/package/'; upToAll: '">'.
name := html upTo: $<.
(id notEmpty and: [ name notEmpty ])
] whileTrue: [ packages at: name put: id ].
^ packages
! !
!Installer methodsFor: 'websqueakmap' stamp: 'kph 11/7/2006 18:54'!
wsmReleasesFor: packageId
| html autoVersion version releases |
releases := Dictionary new.
html := HTTPSocket httpGet: (self wsm, '/package/', packageId ).
[
releases at: #latest put: autoVersion.
autoVersion := html upToAll: '/autoversion/'; upTo: $".
version := html upTo: $-; upTo: $<.
(autoVersion notEmpty and: [version notEmpty ])
] whileTrue: [ releases at: version put: autoVersion ].
^ releases
! !
!Installer methodsFor: 'websqueakmap' stamp: 'kph 10/21/2006 06:04'!
wsmVersions
| pkgAndVersion packageId packageName packageVersion versions |
pkgAndVersion := self smPackageAndVersion.
packageName := pkgAndVersion first.
packageVersion := pkgAndVersion last.
packageVersion isEmpty ifTrue: [ packageVersion := #latest ].
packageId := self wsmPackagesByName at: packageName.
versions := (self wsmReleasesFor: packageId) keys.
versions remove: #latest.
^ versions collect: [ :version | self copy package: (packageName,'(', version ,')'); yourself ]. ! !
!Installer methodsFor: 'mantis' stamp: 'kph 10/19/2006 12:21'!
bug: aBugNo
^ (self maFilesFor: aBugNo) keys! !
!Installer methodsFor: 'mantis' stamp: 'kph 10/19/2006 13:55'!
bug: aBugNo retrieve: aFileName
^ (self streamFor: aBugNo file: aFileName) contents! !
!Installer methodsFor: 'mantis' stamp: 'kph 11/7/2006 18:53'!
maFilesFor: maBugNo
"
self mantis bug: 5251.
"
| file files bugPage id |
files := Dictionary new.
bugPage :=HTTPSocket httpGet: (self ma, 'view.php?id=', maBugNo asString).
[
id := bugPage upToAll: 'href="file_download.php?file_id='; upTo: $&.
file := bugPage upToAll: 'amp;type=bug"' ; upTo: $<.
((file size > 1) and: [file first = $>]) ifTrue: [ files at: file copyWithoutFirst put: id ].
id notEmpty ] whileTrue.
^files ! !
!Installer methodsFor: 'mantis' stamp: 'kph 11/7/2006 18:53'!
streamFor: aBugNo file: aFileName
| fileId |
fileId := (self maFilesFor: aBugNo) at: aFileName.
^ HTTPSocket httpGet: (self ma, 'file_download.php?file_id=' , fileId , '&type=bug').
! !
!Installer methodsFor: 'url' stamp: 'kph 11/7/2006 18:51'!
fileInFromHtml: html
| source in start stop |
start := self markers copyUpTo: $..
stop := self markers copyAfterLast: $..
html upToAll: start.
in := (html upToAll: stop) readStream.
source := ReadWriteStream on: (String new: 100).
[ in atEnd ] whileFalse: [
source nextPutAll: (in upTo: $<).
in upTo: $>.
].
source reset fileIn.
! !
!Installer methodsFor: 'url' stamp: 'kph 11/7/2006 18:38'!
urlInstall
"
Installer installUrl: 'wiki.squeak.org/742'.
"
| downloadUrl page |
downloadUrl := self url, self package.
self logCR: 'found ', downloadUrl , ' ...'.
page := HTTPSocket httpGet: downloadUrl.
((page upTo: $L) = '