Git Product home page Git Product logo

launchpad's Introduction

Launchpad

Logo

A command-line interface to start, list, and explain the applications available within the image.

Pharo Unit Tests GS64 - Unit Tests Pharo Docker Tests GS64 Docker Tests Coverage Status

Baseline Groups GS64 Components Markdown Lint Shellcheck

Pharo Docker Build GS64 Docker Build

GitHub release

Pharo 10 Pharo 11

GS64 3.7.0 GS64 3.7.1

Quick links

Launchpad provides abstractions to architect your application:

  • Configuration parameters (mandatory, optional, and sensitive)
  • Command-line arguments, environment variables, or settings file configuration providers.
  • Inline help
  • Textual and binary stack trace generation

License

  • The code is licensed under MIT.
  • The documentation is licensed under CC BY-SA 4.0.

Installation

To load the project in a Pharo image follow these instructions.

Contributing

Check the Contribution Guidelines


Icons by Icons8

launchpad's People

Contributors

fortizpenaloza avatar gcotelli avatar jvanecek avatar macta avatar mtabacman avatar serpi90 avatar ytsejam78 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

launchpad's Issues

Testing extensions

Add some abstractions to tackle common problems when testing Launchpad applications:

  • Catch unexpected Exit exceptions to avoid closing the image when making a mistake in a test
  • Add facilities to test somehow the produced logging
  • Cleanup Launchpad-related Beacon announcements during tear down
  • Machinery to simulate the application start-up

Add explanations to doc

Explain in more detail:

  • What happens when debugging mode is enabled
  • What happens during the application startup sequence
  • How the value of a parameter is resolved

Loading v5.2.0 into clean P11 image gives error about missing TonelWriterV3

Followed the instructions to load Launchpad using latest fixed version v5.2.0 eg.

Metacello new
baseline: 'Launchpad';
repository: 'github://ba-st/Launchpad:release-candidate';
load: 'Development'.

And I get a walkback:

MCPackageLoader(Object)>>notify:
MCPackageLoader>>warnAboutDependencies
MCPackageLoader>>validate
MCPackageLoader>>loadWithNameLike:
MCVersionLoader>>basicLoadWithNameLike:
[ self basicLoadWithNameLike: aString ] in MCVersionLoader>>loadWithNameLike: in Block: [ self basicLoadWithNameLike: aString ]
[ returnValue := aBlock value ] in [
[ returnValue := aBlock value ] ensure: [
self announceLoadStop: aString ] ] in MCVersionLoader>>announceLoad:do: in Block: [ returnValue := aBlock value ]
FullBlockClosure(BlockClosure)>>ensure:
[
[ returnValue := aBlock value ] ensure: [
self announceLoadStop: aString ] ] in MCVersionLoader>>announceLoad:do: in Block: [ ...
FullBlockClosure(BlockClosure)>>ensure:
MCVersionLoader>>announceLoad:do:
MCVersionLoader>>loadWithNameLike:
[ self ensurePackage: version package.
self loadWithNameLike: version info name ] in [
| version |
version := versions first.
[ self ensurePackage: version package.
self loadWithNameLike: version info name ] asJob
title: 'Loading ', version info name asString;
run ] in MCVersionLoader>>load in Block: [ self ensurePackage: version package....
FullBlockClosure(BlockClosure)>>cull:
[ ^ block cull: self ] in [ self prepareForRunning.
CurrentJob value: self during: [ ^ block cull: self ] ] in Job>>run in Block: [ ^ block cull: self ]
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in CurrentJob(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
CurrentJob(DynamicVariable)>>value:during:
CurrentJob class(DynamicVariable class)>>value:during:
[ self prepareForRunning.
CurrentJob value: self during: [ ^ block cull: self ] ] in Job>>run in Block: [ self prepareForRunning....
FullBlockClosure(BlockClosure)>>ensure:
Job>>run
[
| version |
version := versions first.
[ self ensurePackage: version package.
self loadWithNameLike: version info name ] asJob
title: 'Loading ', version info name asString;
run ] in MCVersionLoader>>load in Block: [ ...
FullBlockClosure(BlockClosure)>>ensure:
RPackageSet class>>withCacheDo:
MCVersionLoader>>load
MetacelloGoferLoad(GoferLoad)>>execute
[ "mcLoader preLoad: packageSpec."
goferLoad := MetacelloGoferLoad on: aGofer.
goferLoad addResolved: resolvedReference.
goferLoad execute.
MetacelloPlatform current clearCurrentVersionCache "mcLoader postLoad: packageSpec"
] in [ | loadBlock goferLoad answers resolvedReference |

		aGofer disablePackageCache.	"for good luck:)"
		resolvedReference := self resolvePackageSpec: packageSpec gofer: aGofer.
		resolvedReference ifNil: [ "Package version already loaded into image" ^ self ].
		loadBlock := [ "mcLoader preLoad: packageSpec."
		goferLoad := MetacelloGoferLoad on: aGofer.
		goferLoad addResolved: resolvedReference.
		goferLoad execute.
		MetacelloPlatform current clearCurrentVersionCache	"mcLoader postLoad: packageSpec"
		].
		MetacelloNotification signal:
				'Loading -> ' , resolvedReference name , ' --- '
					, aPackageLoadDirective repository repositoryDescription , ' --- '
					, resolvedReference repository description.
		( answers := packageSpec answers ) notEmpty
			ifTrue: [ loadBlock valueSupplyingMetacelloAnswers: answers ]
			ifFalse: [ loadBlock value ].
		resolvedReference workingCopy repositoryGroup addRepository: aPackageLoadDirective repository.
		MetacelloNotification signal:
				'Loaded -> ' , resolvedReference name , ' --- '
					, aPackageLoadDirective repository repositoryDescription , ' --- '
					, resolvedReference repository description
		] in MetacelloLoadingMCSpecLoader(MetacelloCommonMCSpecLoader)>>loadPackageDirective:gofer: in Block: [ "mcLoader preLoad: packageSpec."...

[ | loadBlock goferLoad answers resolvedReference |

		aGofer disablePackageCache.	"for good luck:)"
		resolvedReference := self resolvePackageSpec: packageSpec gofer: aGofer.
		resolvedReference ifNil: [ "Package version already loaded into image" ^ self ].
		loadBlock := [ "mcLoader preLoad: packageSpec."
		goferLoad := MetacelloGoferLoad on: aGofer.
		goferLoad addResolved: resolvedReference.
		goferLoad execute.
		MetacelloPlatform current clearCurrentVersionCache	"mcLoader postLoad: packageSpec"
		].
		MetacelloNotification signal:
				'Loading -> ' , resolvedReference name , ' --- '
					, aPackageLoadDirective repository repositoryDescription , ' --- '
					, resolvedReference repository description.
		( answers := packageSpec answers ) notEmpty
			ifTrue: [ loadBlock valueSupplyingMetacelloAnswers: answers ]
			ifFalse: [ loadBlock value ].
		resolvedReference workingCopy repositoryGroup addRepository: aPackageLoadDirective repository.
		MetacelloNotification signal:
				'Loaded -> ' , resolvedReference name , ' --- '
					, aPackageLoadDirective repository repositoryDescription , ' --- '
					, resolvedReference repository description
		] in MetacelloLoadingMCSpecLoader(MetacelloCommonMCSpecLoader)>>loadPackageDirective:gofer: in Block: [ | loadBlock goferLoad answers resolvedRefere[..]

[:bar |
bar value: 1.
aBlock value.
bar value: 2 ] in IceMetacelloPharoPlatform(MetacelloPharoCommonPlatform)>>do:displaying: in Block: [:bar |...
FullBlockClosure(BlockClosure)>>cull:
[ ^ block cull: self ] in [ self prepareForRunning.
CurrentJob value: self during: [ ^ block cull: self ] ] in Job>>run in Block: [ ^ block cull: self ]
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in CurrentJob(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
CurrentJob(DynamicVariable)>>value:during:
CurrentJob class(DynamicVariable class)>>value:during:
[ self prepareForRunning.
CurrentJob value: self during: [ ^ block cull: self ] ] in Job>>run in Block: [ self prepareForRunning....
FullBlockClosure(BlockClosure)>>ensure:
Job>>run
MorphicUIManager(UIManager)>>displayProgress:from:to:during:
ByteString(String)>>displayProgressFrom:to:during:
IceMetacelloPharoPlatform(MetacelloPharoCommonPlatform)>>do:displaying:
MetacelloLoadingMCSpecLoader(MetacelloCommonMCSpecLoader)>>loadPackageDirective:gofer:
MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadPackageDirective:gofer:
MetacelloPackageLoadDirective>>loadUsing:gofer:
[:directive | directive loadUsing: aLoaderDirective gofer: aGofer ] in MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadLinearLoadDirective:gofer: in Block: [:directive | directive loadUsing: aLoaderDire[..]
OrderedCollection>>do:
MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadLinearLoadDirective:gofer:
MetacelloLinearLoadDirective>>loadUsing:gofer:
[:directive | directive loadUsing: aLoaderDirective gofer: aGofer ] in MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadLinearLoadDirective:gofer: in Block: [:directive | directive loadUsing: aLoaderDire[..]
OrderedCollection>>do:
MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadLinearLoadDirective:gofer:
MetacelloLinearLoadDirective>>loadUsing:gofer:
[:directive | directive loadUsing: aLoaderDirective gofer: aGofer ] in MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadLinearLoadDirective:gofer: in Block: [:directive | directive loadUsing: aLoaderDire[..]
OrderedCollection>>do:
MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadLinearLoadDirective:gofer:
MetacelloLinearLoadDirective>>loadUsing:gofer:
MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadWithPolicy:
MetacelloLoaderPolicy>>load
MetacelloFetchingMCSpecLoader>>doLoad
[ fetchLoader doLoad ] in [ | fetchLoader |
fetchLoader := self fetchRequiredFromArray: (self defaultPackageNamesToLoad: anArray).
MetacelloPlatform current
do: [ fetchLoader doLoad ]
displaying: 'Loading ', displayString.
MetacelloNotification signal: ('...finished ', self versionNumber printString).
^fetchLoader ] in MetacelloMCVersion>>doLoadRequiredFromArray: in Block: [ fetchLoader doLoad ]
[:bar |
bar value: 1.
aBlock value.
bar value: 2 ] in IceMetacelloPharoPlatform(MetacelloPharoCommonPlatform)>>do:displaying: in Block: [:bar |...
FullBlockClosure(BlockClosure)>>cull:
[ ^ block cull: self ] in [ self prepareForRunning.
CurrentJob value: self during: [ ^ block cull: self ] ] in Job>>run in Block: [ ^ block cull: self ]
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in CurrentJob(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
CurrentJob(DynamicVariable)>>value:during:
CurrentJob class(DynamicVariable class)>>value:during:
[ self prepareForRunning.
CurrentJob value: self during: [ ^ block cull: self ] ] in Job>>run in Block: [ self prepareForRunning....
FullBlockClosure(BlockClosure)>>ensure:
Job>>run
MorphicUIManager(UIManager)>>displayProgress:from:to:during:
ByteString(String)>>displayProgressFrom:to:during:
IceMetacelloPharoPlatform(MetacelloPharoCommonPlatform)>>do:displaying:
[ | fetchLoader |
fetchLoader := self fetchRequiredFromArray: (self defaultPackageNamesToLoad: anArray).
MetacelloPlatform current
do: [ fetchLoader doLoad ]
displaying: 'Loading ', displayString.
MetacelloNotification signal: ('...finished ', self versionNumber printString).
^fetchLoader ] in MetacelloMCVersion>>doLoadRequiredFromArray: in Block: [ | fetchLoader |...
FullBlockClosure(BlockClosure)>>ensure:
MetacelloMCVersion>>doLoadRequiredFromArray:
ByteString(String)>>loadRequiredForMetacelloMCVersion:
MetacelloMCVersion>>load:
[
| version loadedSpec |
self setDefaultsAndValidateProjectSpec.
[ loadedSpec := (self lookupProjectSpecFor: self projectSpec) copy ]
on: MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
do: [ :ex | ex handleOnDownGrade: onDownGradeBlock onUpgrade: onUpgradeBlock ].
version := loadedSpec versionForScriptEngine: self.
self
root:
(required isEmpty
ifTrue: [ version load ]
ifFalse: [ version load: required ]) loadDirective.
loadedSpec loads: required.
MetacelloProjectRegistration
registrationForProjectSpec: loadedSpec
ifAbsent: [ :new |
new
loadedInImage: true;
registerProject ]
ifPresent: [ :existing :new |
existing
copyOnWrite: [ :existingCopy |
existingCopy
loadedInImage: true;
merge: new ] ] ] in [
self
handleNotificationsForAction: [
| version loadedSpec |
self setDefaultsAndValidateProjectSpec.
[ loadedSpec := (self lookupProjectSpecFor: self projectSpec) copy ]
on: MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
do: [ :ex | ex handleOnDownGrade: onDownGradeBlock onUpgrade: onUpgradeBlock ].
version := loadedSpec versionForScriptEngine: self.
self
root:
(required isEmpty
ifTrue: [ version load ]
ifFalse: [ version load: required ]) loadDirective.
loadedSpec loads: required.
MetacelloProjectRegistration
registrationForProjectSpec: loadedSpec
ifAbsent: [ :new |
new
loadedInImage: true;
registerProject ]
ifPresent: [ :existing :new |
existing
copyOnWrite: [ :existingCopy |
existingCopy
loadedInImage: true;
merge: new ] ] ] ] in MetacelloScriptEngine>>load:onProjectDownGrade:onProjectUpgrade: in Block: [ ...
FullBlockClosure(BlockClosure)>>on:do:
[
actionBlock
on:
MetacelloLookupProjectSpec , MetacelloLookupProjectSpecForLoad
, MetacelloProjectSpecLoadedNotification
, MetacelloScriptEnsureProjectLoadedForDevelopment
, MetacelloLookupBaselineSpecForEnsureLoad
do: [ :ex |
"lookup and registration handlers need to be innermost set of handlers ...they may throw option notifications"
ex handleResolutionFor: self ] ] in [
[
actionBlock
on:
MetacelloLookupProjectSpec , MetacelloLookupProjectSpecForLoad
, MetacelloProjectSpecLoadedNotification
, MetacelloScriptEnsureProjectLoadedForDevelopment
, MetacelloLookupBaselineSpecForEnsureLoad
do: [ :ex |
"lookup and registration handlers need to be innermost set of handlers ...they may throw option notifications"
ex handleResolutionFor: self ] ]
on:
MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
, MetacelloAllowConflictingProjectUpgrade
do: [ :ex |
"option handlers need to be outermost set of handlers ... last line of defense before users are involved"
ex handleResolutionFor: self ] ] in [
[
[
actionBlock
on:
MetacelloLookupProjectSpec , MetacelloLookupProjectSpecForLoad
, MetacelloProjectSpecLoadedNotification
, MetacelloScriptEnsureProjectLoadedForDevelopment
, MetacelloLookupBaselineSpecForEnsureLoad
do: [ :ex |
"lookup and registration handlers need to be innermost set of handlers ...they may throw option notifications"
ex handleResolutionFor: self ] ]
on:
MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
, MetacelloAllowConflictingProjectUpgrade
do: [ :ex |
"option handlers need to be outermost set of handlers ... last line of defense before users are involved"
ex handleResolutionFor: self ] ]
on: MetacelloAllowLockedProjectChange
do: [ :ex |
"MetacelloAllowLockedProjectChange need to be outermost handler ... since it is signaled from second line of handlers"
ex handleResolutionFor: self ] ] in MetacelloScriptEngine>>handleNotificationsForAction: in Block: [ ...
FullBlockClosure(BlockClosure)>>on:do:
[
[
actionBlock
on:
MetacelloLookupProjectSpec , MetacelloLookupProjectSpecForLoad
, MetacelloProjectSpecLoadedNotification
, MetacelloScriptEnsureProjectLoadedForDevelopment
, MetacelloLookupBaselineSpecForEnsureLoad
do: [ :ex |
"lookup and registration handlers need to be innermost set of handlers ...they may throw option notifications"
ex handleResolutionFor: self ] ]
on:
MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
, MetacelloAllowConflictingProjectUpgrade
do: [ :ex |
"option handlers need to be outermost set of handlers ... last line of defense before users are involved"
ex handleResolutionFor: self ] ] in [
[
[
actionBlock
on:
MetacelloLookupProjectSpec , MetacelloLookupProjectSpecForLoad
, MetacelloProjectSpecLoadedNotification
, MetacelloScriptEnsureProjectLoadedForDevelopment
, MetacelloLookupBaselineSpecForEnsureLoad
do: [ :ex |
"lookup and registration handlers need to be innermost set of handlers ...they may throw option notifications"
ex handleResolutionFor: self ] ]
on:
MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
, MetacelloAllowConflictingProjectUpgrade
do: [ :ex |
"option handlers need to be outermost set of handlers ... last line of defense before users are involved"
ex handleResolutionFor: self ] ]
on: MetacelloAllowLockedProjectChange
do: [ :ex |
"MetacelloAllowLockedProjectChange need to be outermost handler ... since it is signaled from second line of handlers"
ex handleResolutionFor: self ] ] in MetacelloScriptEngine>>handleNotificationsForAction: in Block: [ ...
FullBlockClosure(BlockClosure)>>on:do:
[
[
[
actionBlock
on:
MetacelloLookupProjectSpec , MetacelloLookupProjectSpecForLoad
, MetacelloProjectSpecLoadedNotification
, MetacelloScriptEnsureProjectLoadedForDevelopment
, MetacelloLookupBaselineSpecForEnsureLoad
do: [ :ex |
"lookup and registration handlers need to be innermost set of handlers ...they may throw option notifications"
ex handleResolutionFor: self ] ]
on:
MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
, MetacelloAllowConflictingProjectUpgrade
do: [ :ex |
"option handlers need to be outermost set of handlers ... last line of defense before users are involved"
ex handleResolutionFor: self ] ]
on: MetacelloAllowLockedProjectChange
do: [ :ex |
"MetacelloAllowLockedProjectChange need to be outermost handler ... since it is signaled from second line of handlers"
ex handleResolutionFor: self ] ] in MetacelloScriptEngine>>handleNotificationsForAction: in Block: [ ...
FullBlockClosure(BlockClosure)>>on:do:
MetacelloScriptEngine>>handleNotificationsForAction:
[
self
handleNotificationsForAction: [
| version loadedSpec |
self setDefaultsAndValidateProjectSpec.
[ loadedSpec := (self lookupProjectSpecFor: self projectSpec) copy ]
on: MetacelloAllowProjectDowngrade , MetacelloAllowProjectUpgrade
do: [ :ex | ex handleOnDownGrade: onDownGradeBlock onUpgrade: onUpgradeBlock ].
version := loadedSpec versionForScriptEngine: self.
self
root:
(required isEmpty
ifTrue: [ version load ]
ifFalse: [ version load: required ]) loadDirective.
loadedSpec loads: required.
MetacelloProjectRegistration
registrationForProjectSpec: loadedSpec
ifAbsent: [ :new |
new
loadedInImage: true;
registerProject ]
ifPresent: [ :existing :new |
existing
copyOnWrite: [ :existingCopy |
existingCopy
loadedInImage: true;
merge: new ] ] ] ] in MetacelloScriptEngine>>load:onProjectDownGrade:onProjectUpgrade: in Block: [ ...
FullBlockClosure(BlockClosure)>>ensure:
MetacelloProjectRegistration class>>copyRegistryRestoreOnErrorWhile:
MetacelloScriptEngine>>load:onProjectDownGrade:onProjectUpgrade:
MetacelloScriptEngine>>load:
[ :projectSpec |
| engine |
engine := MetacelloScriptEngine new
options: self options copy;
projectSpec: projectSpec;
yourself.
engine perform: actionArg key withArguments: actionArg value.
engine root ifNotNil: [ :root | self roots add: root ] ] in MetacelloScriptApiExecutor(MetacelloScriptExecutor)>>execute: in Block: [ :projectSpec | ...
[ :projectSpec |
projectSpec
ifNotNil: [ projectSpecBlock value: (self applyArgsToProjectSpec: projectSpec copy) ] ] in MetacelloScriptApiExecutor>>executeString:do: in Block: [ :projectSpec | ...
Array(SequenceableCollection)>>do:
MetacelloScriptApiExecutor>>executeString:do:
ByteString(String)>>execute:against:
MetacelloScriptApiExecutor(MetacelloScriptExecutor)>>execute:
[
super execute: statements ] in MetacelloScriptApiExecutor>>execute: in Block: [ ...
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in IceMetacelloLoadSessionContext(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
IceMetacelloLoadSessionContext(DynamicVariable)>>value:during:
IceMetacelloLoadSessionContext class(DynamicVariable class)>>value:during:
IceMetacelloPharoPlatform>>withMetacelloLoadSessionDo:
MetacelloScriptApiExecutor>>execute:
Metacello>>execute:args:
Metacello>>load:
UndefinedObject>>DoIt
OCReceiverDoItSemanticScope(OCDoItSemanticScope)>>evaluateDoIt:
OpalCompiler>>evaluate
[
self announcer announce: (SpCodeWillBeEvaluatedAnnouncement newContent: aString).
oldBindings := self interactionModel bindings copy.
receiver := self interactionModel doItReceiver.
result := receiver class compiler
source: aString;
context: self interactionModel doItContext;
receiver: self interactionModel doItReceiver;
requestor: self interactionModel;
environment: self environment;
failBlock: [
self announcer announce: (SpCodeEvaluationFailedAnnouncement newContent: aString).
^ compileErrorBlock value ];
evaluate.
oldBindings size = self interactionModel bindings size
ifFalse: [ self withAdapterDo: [ :anAdapter | anAdapter refreshStyling ] ].
self announcer announce: (SpCodeEvaluationSucceedAnnouncement newContent: aString).
result ] in SpCodePresenter>>evaluate:onCompileError:onError: in Block: [...
FullBlockClosure(BlockClosure)>>on:do:
SpCodePresenter>>evaluate:onCompileError:onError:
SpCodeDoItCommand(SpCodeSelectionCommand)>>evaluate:andDo:
SpCodeDoItCommand(SpCodeSelectionCommand)>>evaluateSelectionAndDo:
SpCodeDoItCommand>>execute
SpCommand(CmCommandDecorator)>>execute
[ self decoratedCommand execute ] in SpToolCurrentApplicationCommand>>execute in Block: [ self decoratedCommand execute ]
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in SpToolCurrentApplication(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
SpToolCurrentApplication(DynamicVariable)>>value:during:
SpToolCurrentApplication class(DynamicVariable class)>>value:during:
SpToolCurrentApplicationCommand>>execute
[ self decoratedCommand execute ] in SpToolCurrentApplicationCommand>>execute in Block: [ self decoratedCommand execute ]
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in SpToolCurrentApplication(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
SpToolCurrentApplication(DynamicVariable)>>value:during:
SpToolCurrentApplication class(DynamicVariable class)>>value:during:
SpToolCurrentApplicationCommand>>execute
[
aCmCommand canBeExecuted
ifTrue: [ aCmCommand execute ] ] in SpKMCategoryBuilder>>visitCommand: in Block: [ ...
FullBlockClosure(BlockClosure)>>cull:
FullBlockClosure(BlockClosure)>>cull:cull:
FullBlockClosure(BlockClosure)>>cull:cull:cull:
KMCategoryBinding>>completeMatch:buffer:
[ :l | l completeMatch: self buffer: aBuffer ] in KMKeymap>>notifyCompleteMatchTo:buffer: in Block: [ :l | l completeMatch: self buffer: aBuffer ]
Array(SequenceableCollection)>>do:
KMKeymap>>notifyCompleteMatchTo:buffer:
KMKeymap>>onMatchWith:notify:andDo:
[ :entry |
entry onMatchWith: anEventBuffer
notify: aMatchListener
andDo: aBlock ] in KMCategory>>onMatchWith:notify:andDo: in Block: [ :entry |...
Set>>do:
KMCategory>>onMatchWith:notify:andDo:
KMCategoryBinding>>verifyMatchWith:notifying:thenDoing:
[ :aTarget |
"nice hack to stop in the first listener"
aTarget
verifyMatchWith: anEventBuffer
notifying: self
thenDoing: [ ^self ] ] in KMDispatcher>>dispatch: in Block: [ :aTarget |...
OrderedCollection>>do:
KMDispatcher>>dispatch:
KMTarget>>dispatch:
[ :targetToDispatch |
targetToDispatch dispatch: KMBuffer uniqueInstance buffer copy.
aKeyboardEvent wasHandled ifTrue: [ ^self ].
] in KMDispatchChain>>dispatch: in Block: [ :targetToDispatch |...
KMDispatchChain>>do:
KMDispatchChain>>dispatch:
KMDispatcher>>dispatchKeystroke:
RubEditingArea(Morph)>>dispatchKeystrokeForEvent:
RubEditingArea(Morph)>>handleKeystrokeWithKeymappings:
KMShortcutHandler>>handleKeystroke:inMorph:
RubEditingArea(Morph)>>handleKeyDown:
RubEditingArea(RubAbstractTextArea)>>handleKeyDown:
KeyboardEvent>>sentTo:
RubEditingArea(Morph)>>handleEvent:
RubEditingArea(Morph)>>handleFocusEvent:
[
result := focusHolder handleFocusEvent: transformedEvent.
] in HandMorph>>sendFocusEvent:to:clear: in Block: [...
FullBlockClosure(BlockClosure)>>on:do:
WorldMorph>>becomeActiveDuring:
HandMorph>>sendFocusEvent:to:clear:
HandMorph>>sendEvent:focus:clear:
HandMorph>>sendKeyboardEvent:
HandMorph>>handleEvent:
[
(morphicWorld activeHand isNotNil and: [ anEvent hand isNotNil ]) ifTrue: [
morphicWorld activeHand handleEvent: anEvent
]
] in OSWindowMorphicEventHandler>>dispatchMorphicEvent: in Block: [...
WorldState>>runStepMethodsIn:
WorldMorph>>runStepMethods
WorldState>>doOneCycleFor:
WorldMorph>>doOneCycleNow
WorldMorph>>doOneCycle
[
| extraWorldsToDraw |
extraWorldsToDraw := ExtraWorldListMutex critical: [
self extraWorldList ].
extraWorldsToDraw do: [ :world | world doOneCycle ].

	(self currentWorld isNotNil and: [
		 (extraWorldsToDraw includes: self currentWorld) not ]) ifTrue: [
		self currentWorld doOneCycle ] ] in WorldMorph class>>doOneCycle in Block: [...

FullBlockClosure(BlockClosure)>>ensure:
WorldState class>>doDrawCycleWith:
WorldMorph class>>doOneCycle
MorphicRenderLoop>>doOneCycle
MorphicRenderLoop>>doOneCycleWhile:
[ MorphicRenderLoop new doOneCycleWhile: [ true ] ] in MorphicUIManager>>spawnNewProcess in Block: [ MorphicRenderLoop new doOneCycleWhile: [ tru[..]
[self value.
"IMPORTANT: Do not step over next line of code. See method comments for details"
Processor terminateRealActive] in FullBlockClosure(BlockClosure)>>newProcess in Block: [self value....

Reference documentation

  • Launchpad CLI reference
  • Configuration parameter types
  • Configuration providers
  • Logging infrastructure
  • Stack trace generation

Create tutorial

Create a tutorial explaining how to create a basic application, including several configuration parameters & options

Add VAST 2024 as a supported platform

  • Import the packages in VAST 2022 and the required dependencies
  • A-priori Launchpad-Tracing package will require a VAST specific version
  • Create configuration maps for the equivalent Baseline groups
  • Export again to Tonel format to write the required VAST specific metadata

Loading the metacello group "Deployment" gives errors

If using launchpad in a production app, I believe you are supposed to use the "Deployment" group baseline to avoid loading tests etc.

In my my CI build pipeline in a clean image I see the follow errors/warnings (greped from the log file) - so I think the dependencies might not be quite right (or you aren't supposed to use this group?)

NewUndeclaredWarning: BaselineOfLaunchpad>>addLaunchpadLogRecordAsGlobalAndConfigureTransientClasses (LogRecord is Undeclared)
NewUndeclaredWarning: BaselineOfLaunchpad>>addLaunchpadLogRecordAsGlobalAndConfigureTransientClasses (LaunchpadApplication is Undeclared)
NewUndeclaredWarning: BaselineOfLaunchpad>>addLaunchpadLogRecordAsGlobalAndConfigureTransientClasses (CurrentlyRunningLaunchpadApplication is Undeclared)
NewUndeclaredWarning: CurrentApplicationConfigurationTest>>testAccessingConfigurationOfRunningApplication (LaunchpadBrokenApplication is Undeclared)
NewUndeclaredWarning: LaunchpadApplicationTest>>testIsDebugModeEnabled (LaunchpadBrokenApplication is Undeclared)
NewUndeclaredWarning: LaunchpadApplicationTest>>testIsDebugModeNotEnabled (LaunchpadBrokenApplication is Undeclared)
NewUndeclaredWarning: StackTraceBinarySerializerTest>>testDumpStack (StackTraceBinarySerializer is Undeclared)
NewUndeclaredWarning: StackTraceBinarySerializerTest>>testDumpStackOnFile (StackTraceBinarySerializer is Undeclared)

In Pharo 10 can't materialize a binary stack

Whether "draganddropping" or loading it with the following snippet

| session |

session := Processor activeProcess
  newDebugSessionNamed: 'External stack'
  startedAt: (FLMaterializer materializeFromFileNamed: 'the-file.fuel').

StDebugger openOn: session withFullView: true

the serializer raises different DNUs but won't work any way

Loading the default baseline give Undeclared warnings - should clean load?

I'm tracking down the errors mentioned in my clean load example #66 and I notice that the default load for Launcpad in a clean P12 (and I believe P11) image gives undeclared variables. Its easier to detect legitimate errors if it clean loads and I think this should be fixed.

e.g. heres the load output using:

Metacello new
baseline: 'Launchpad';
repository: 'github://ba-st/Launchpad:release-candidate';
load: 'Development'.

BaselineOfLaunchpad>>addLaunchpadLogRecordAsGlobalAndConfigureTransientClasses (LogRecord is Undeclared)
BaselineOfLaunchpad>>addLaunchpadLogRecordAsGlobalAndConfigureTransientClasses (ApplicationConfiguration is Undeclared)
BaselineOfLaunchpad>>addLaunchpadLogRecordAsGlobalAndConfigureTransientClasses (CurrentlyRunningLaunchpadApplication is Undeclared)
BaselineOfLaunchpad>>addLaunchpadLogRecordAsGlobalAndConfigureTransientClasses (LaunchpadApplication is Undeclared)

Loaded -> BaselineOfLaunchpad --- unresolved
Loading baseline of BaselineOfLaunchpad...
Project: Buoy-Deployment
Loaded -> BaselineOfBuoy --- unresolved
Project: Buoy-SUnit
Project: Buoy-Tools
Project: Bell-Deployment
Loaded -> BaselineOfBell --- unresolved
Project: NeoJSON-Core
Loaded -> BaselineOfNeoJSON --- unresolved
Project: Bell-SUnit
Project: NeoJSON-Core baseline
Project: INIParser-Deployment
Loaded -> BaselineOfINIParser --- unresolved
Project: Hyperspace-SUnit
Loaded -> BaselineOfHyperspace --- unresolved
Project: Buoy-SUnit
Loaded -> Buoy-Assertions-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Chronology-Pharo-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Conditions-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Conditions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Assertions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Conditions-Pharo-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Comparison --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Comparison-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Exception-Handling-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Math --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Math-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Math-Pharo-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Metaprogramming --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Dynamic-Binding --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Collections --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Collections-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Collections-Pharo-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Metaprogramming-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Metaprogramming-Pharo-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-SUnit-Model --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-SUnit-Pharo-Extensions --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Development-Tools --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Buoy-Development-Tools-Pharo-12 --- [email protected]:ba-st/Buoy.gitv7
Loaded -> Neo-JSON-Core --- [email protected]:svenvc/NeoJSON.gitmaster
Loaded -> Neo-JSON-Pharo-Core --- [email protected]:svenvc/NeoJSON.gitmaster
Loaded -> Bell-Logging --- [email protected]:ba-st/Bell.gitv2
Loaded -> Bell-SUnit --- [email protected]:ba-st/Bell.gitv2
Loaded -> INI-Parser --- [email protected]:ba-st-dependencies/INI-Parser.gitv2
Loaded -> Hyperspace-SUnit-Model --- [email protected]:ba-st/Hyperspace.gitv5
Loaded -> Launchpad-Configuration-Pharo-Extensions --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Configuration --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Applications --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Commands --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Commands-Pharo --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Tracing-Pharo --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Tracing --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Examples --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-SUnit --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Configuration-Tests --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Applications-Tests --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Tracing-Tests --- [email protected]:ba-st/Launchpad.gitrelease-candidate
StackTraceBinarySerializerTest>>testDumpStack (StackTraceBinarySerializer is Undeclared)
StackTraceBinarySerializerTest>>testDumpStackOnFile (StackTraceBinarySerializer is Undeclared)

Loaded -> Launchpad-Tracing-Pharo-Tests --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Commands-Tests --- [email protected]:ba-st/Launchpad.gitrelease-candidate
Loaded -> Launchpad-Commands-Pharo-Tests --- [email protected]:ba-st/Launchpad.gitrelease-candidate
...finished baseline

Allow to user environment variables instead of parameters

Would be good if we allowed to specified the expected command lines parameters in environment variables. This will simplify some deployment cases.

The order must be:

  • Try to read the parameter from the command line, if absent
  • Try to read it from an environment variable, if absent
  • Use the default if the parameter is optional or fail if the parameter is required

we need to determine a parameter to environment variable name convention, and decide what to do if the parameter is present in the command line but with an invalid format: try to use the env var? or fail?

In any case log clearly when some option is ignored or taken from the command line or env vars.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.