[squeak-dev] The Inbox: Metacello-Base-ct.126.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Jul 14 14:13:23 UTC 2022


A new version of Metacello-Base was added to project The Inbox:
http://source.squeak.org/inbox/Metacello-Base-ct.126.mcz

==================== Summary ====================

Name: Metacello-Base-ct.126
Author: ct
Time: 22 November 2020, 4:34:17.902871 pm
UUID: 90d418b0-fe04-5c45-abda-f2da2f1d02f2
Ancestors: Metacello-Base-ct.125

Add shortcuts for fetching github repositories

==================== Snapshot ====================

SystemOrganization addCategory: #'Metacello-Base'!

Object subclass: #ConfigurationOf
	instanceVariableNames: 'project'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Metacello-Base'!

!ConfigurationOf commentStamp: 'dkh 5/30/2012 16:31' prior: 0!
You must use a *configuration* when your project is stored in a
repository using `.mcz` files.

If you are using a source code manager (SCM) like [git][1] and have
created a *baseline* (see the [**BaselineOf** class comment][3] for more info)
you may use a *configuration* to associate a specific
git commit (SHA, branch name, tag name) with a [Metacello version][2].

To create a new Metacello configuration:

1. Create a subclass of the **ConfigurationOf** class. The configuration
   class for your project should be names by appending the name of
   your project to the string `ConfigurationOf`. The name of the
   category and package should be the same as the name of the class:

    ```Smalltalk
    ConfigurationOf subclass: #ConfigurationOfExample
      instanceVariableNames: ''
      classVariableNames: ''
      poolDictionaries: ''
      category: 'ConfigurationOfExample'
    ```

2. Create a **baselineXXXX:** method where you specify the structure of your project:

    ```Smalltalk
    baseline0100: spec
      <baseline: '1.0-baseline'>

      spec for: #common do: [
        spec repository: 'http://ss3.gemstone.com/ss/Example'.
        spec
          package: 'Example-Core';
          package: 'Example-Tests' with: [
            spec requires: 'Example-Core' ]].
    ```

3. Create a **versionXXXX:** method where you specify the specific
   versions of the packages to be loaded for this version:

    ```Smalltalk
    version01000: spec
      <version: '1.0' imports: #('1.0-baseline')>

      spec for: #common do: [
        spec blessing: #release.
        spec
          package: 'Example-Core' with: 'Example-Core';
          package: 'Example-Tests' with: 'Example-Tests' ].
    ```

4. Create a Monticello package for your **ConfigurationOf** class and save it in the repository where your packages are stored. 

[1]: http://git-scm.com/
[2]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#metacello-version-numbers
[3]: https://github.com/dalehenrich/metacello-work/blob/master/repository/Metacello-Base.package/BaselineOf.class/README.md
!

ConfigurationOf subclass: #BaselineOf
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Metacello-Base'!

!BaselineOf commentStamp: 'dkh 5/30/2012 16:30' prior: 0!
You should use a *baseline* when you are using a disk-based source
code manager (SCM) like [git][1].

When using a disk-based SCM it is not necessary to use the Metacello
*version* method, because it is intended for use with `.mcz` files. 

With a disk-based SCM you only need a single `baseline:` method. When
you change the structure of your project you can change the baseline and
save everything in a single commit. So multiple `baseline:` methods are
no longer needed.

You may still need a *configuration* when using a *baseline*. The
[Sample project][3] on GitHub has a good example of a configuration used
in conjunction with a *baseline*. See the [**ConfigurationOf** class comment][2] 
for information on creating a *configuration*.

To create a new Metacello baseline:

1. Create a subclass of the **BaselineOf** class. The baseline
   class for your project should be named by appending the name of
   your project to the string `BaselineOf`. The name of the category and
   package should be the same as the name of the class:

    ```Smalltalk
    BaselineOf subclass: #BaselineOfExample
      instanceVariableNames: ''
      classVariableNames: ''
      poolDictionaries: ''
      category: 'BaselineOfExample'
    ```

2. Create a **baseline:** method where you specify the structure of your project:

    ```Smalltalk
    baseline: spec
      <baseline>

      spec for: #common do: [
        spec
          package: 'Example-Core';
          package: 'Example-Tests' with: [
            spec requires: 'Example-Core' ]].
    ```

3. Create a Monticello package for your **BaselineOf** class and save it in the repository where your packages are stored.

4. To load a package from GitHub that contains a baseline evaluate the following:

```Smalltalk
| repositorySpec |
"edit to match your username, repository name and branch"
repositorySpec := 'dalehenrich/metacello-work:master'.
Metacello new
  baseline: 'Sample';
  repository: 'github://', repositorySpec;
  load.
```

For further documentation see For more information on the [github://](MetacelloScriptingAPI.md#github) url specifigation see the [Metacello Scripting API
reference](MetacelloScriptingAPI.md). There more information on [working with GitHub here](GettingStartedWithGitHub.md).

[1]: http://git-scm.com/
[2]: https://github.com/dalehenrich/metacello-work/blob/master/repository/Metacello-Base.package/ConfigurationOf.class/README.md
[3]: https://github.com/dalehenrich/sample/tree/configuration/ConfigurationOfSample.package/ConfigurationOfSample.class
!

----- Method: BaselineOf class>>validate (in category 'accessing') -----
validate
  "Check the configuration for Errors, Critical Warnings, and Warnings (see class comment for MetacelloMCVersionValidator for more information). 
	Errors identify specification issues that will result in unexpected behaviour when you load the configuration. 
	Critical Warnings identify specification issues that may result in unexpected behavior when you load the configuration.
	Warnings identify specification issues that are technically correct, but are worth take a look at."

  "self validate"

  <apiDocumentation>
  self ensureMetacello.
  ^ ((Smalltalk at: #'MetacelloToolBox')
    validateBaseline: self
    debug: #()
    recurse: false) explore!

----- Method: BaselineOf>>projectClass (in category 'accessing') -----
projectClass
    ^ MetacelloMCBaselineProject!

----- Method: BaselineOf>>versionNumberClass (in category 'accessing') -----
versionNumberClass
    ^ MetacelloVersionNumber!

----- Method: ConfigurationOf class>>bootstrapMetacelloFrom: (in category 'private') -----
bootstrapMetacelloFrom: repositoryUrl
  "Corresponds to version 1.0.0-beta.32.6"

  "KEEP MetacelloConfigTemplate class>>ensureMetacelloBaseConfiguration in synch!!"

  | platformPkg |
  self ensureGoferVersion: 'Gofer-Core-lr.115' repositoryUrl: repositoryUrl.
  #('Metacello-Core-dkh.678' 'Metacello-MC-dkh.674')
    do: [ :pkg | self bootstrapPackage: pkg from: repositoryUrl ].
  platformPkg := Smalltalk
    at: #'SystemVersion'
    ifPresent: [ :cl | 
      | versionString |
      versionString := cl current version.
      (versionString beginsWith: 'Squeak')
        ifTrue: [ 
          (versionString beginsWith: 'Squeak3')
            ifTrue: [ 'Metacello-Platform.squeak-dkh.5' ]
            ifFalse: [ 'Metacello-Platform.squeak-dkh.22' ] ]
        ifFalse: [ 
          (versionString beginsWith: 'Pharo')
            ifTrue: [ 
              self bootstrapPackage: 'Metacello-PharoCommonPlatform-dkh.2' from: repositoryUrl.
              (versionString beginsWith: 'Pharo2')
                ifTrue: [ 'Metacello-Platform.pharo20-dkh.33' ]
                ifFalse: [ 'Metacello-Platform.pharo-dkh.34' ] ] ] ].
  self bootstrapPackage: platformPkg from: repositoryUrl!

----- Method: ConfigurationOf class>>bootstrapPackage:from: (in category 'private') -----
bootstrapPackage: aString from: aPath
    | repository version |
    repository := (MCCacheRepository default includesVersionNamed: aString)
        ifTrue: [ MCCacheRepository default ]
        ifFalse: [ MCHttpRepository location: aPath user: '' password: '' ].
    self
        retry: [ 
            repository
                versionReaderForFileNamed: aString , '.mcz'
                do: [ :reader | 
                    version := reader version.
                    version load.
                    version workingCopy repositoryGroup addRepository: repository ] ]!

----- Method: ConfigurationOf class>>ensureGoferVersion:repositoryUrl: (in category 'private') -----
ensureGoferVersion: goferVersion repositoryUrl: repositoryUrl
    "load the p=file goferVersion if Gofer isn't loaded or an earlier version of Gofer is currently loaded"

    | goferVersionNumber wc pName |
    (Smalltalk at: #'Gofer' ifAbsent: [  ]) == nil
        ifTrue: [ ^ self bootstrapPackage: goferVersion from: repositoryUrl ].
    goferVersionNumber := (goferVersion copyAfterLast: $.) asNumber.
    wc := [ ((Smalltalk at: #'GoferPackageReference') name: 'Gofer') workingCopy ]
        on: Error
        do: [ :ex | ex return: ((Smalltalk at: #'GoferPackageReference') name: 'Gofer-Core') workingCopy ].
    pName := wc ancestry ancestors first name.
    (pName copyAfterLast: $.) asNumber <= goferVersionNumber
        ifTrue: [ self bootstrapPackage: goferVersion from: repositoryUrl ]!

----- Method: ConfigurationOf class>>ensureMetacello (in category 'private') -----
ensureMetacello
    "Bootstrap Metacello and load the 'botstrap' group"

    self ensureMetacello: #('batch')!

----- Method: ConfigurationOf class>>ensureMetacello: (in category 'private') -----
ensureMetacello: loadList
  "Bootstrap Metacello, retry using alternate repository, if primary repository is not accessible"

  Smalltalk
    at: #'MetacelloProject'
    ifAbsent: [ 
      | version error gofer |
      (Array
        with: 'http://smalltalkhub.com/mc/dkh/metacello/main'
        with: 'http://seaside.gemtalksystems.com/ss/metacello')
        do: [ :repositoryUrl | 
          "bootstrap Metacello"
          [ 
          self bootstrapMetacelloFrom: repositoryUrl.
          Smalltalk
            at: #'ConfigurationOfMetacello'
            ifAbsent: [ 
              self
                retry: [ 
                  gofer := (Smalltalk at: #'Gofer') new.
                  gofer
                    perform: #'url:' with: repositoryUrl;
                    perform: #'package:' with: 'ConfigurationOfMetacello';
                    perform: #'load' ] ].
          version := (Smalltalk at: #'ConfigurationOfMetacello') project
            version: #'previewBootstrap'.
          version load: loadList.
          self
            retry: [ 
              gofer := (Smalltalk at: #'Gofer') new.
              Smalltalk
                at: #'ConfigurationOfMetacelloPreview'
                ifAbsent: [ 
                  gofer
                    perform: #'url:' with: repositoryUrl;
                    perform: #'package:'
                      with: 'ConfigurationOfMetacelloPreview';
                    perform: #'load' ] ].
          version := (Smalltalk at: #'ConfigurationOfMetacelloPreview') project
            version: #'stable'.	"load latest from GitHub"
          version load: loadList.
          ^ self ]
            on: Error
            do: [ :ex | 
              error := ex.
              Transcript
                cr;
                show: 'failed ensureMetacello using ';
                show: repositoryUrl printString;
                show: ' : ';
                show: ex description printString;
                show: '...retrying'.	"try again"
              ex return: nil ] ].	"shouldn't get here unless the load failed ... throw an error"
      self
        error:
          'retry with alternate repository failed: ' , error description printString ]!

----- Method: ConfigurationOf class>>project (in category 'accessing') -----
project

	^self new project!

----- Method: ConfigurationOf class>>retry: (in category 'private') -----
retry: aBlock
    self retry: aBlock retryCount: 3!

----- Method: ConfigurationOf class>>retry:retryCount: (in category 'private') -----
retry: aBlock retryCount: retryCount
    | count |
    count := 1.
    [ true ]
        whileTrue: [ 
            [ 
            aBlock value.
            ^ self ]
                on: Error
                do: [ :ex | 
                    count < retryCount
                        ifTrue: [ 
                            Transcript
                                cr;
                                show: 'RETRYING AFTER:';
                                cr;
                                show: ex description printString.
                            (Delay forSeconds: 5) wait ]
                        ifFalse: [ 
                            Transcript
                                cr;
                                show: 'FAILED RETRYING:';
                                cr;
                                show: ex description printString.
                            ex pass ] ].
            count := count + 1 ]!

----- Method: ConfigurationOf class>>unloadMetacello (in category 'unloading Metacello') -----
unloadMetacello
	"Unload the classes that implement Metacello. Metacello is not needed once a project has been loaded, so it can safely be unloaded."

	"self unloadMetacello"

	<apiDocumentation>
	| gofer |
	gofer := (Smalltalk at: #Gofer) new.
	MCWorkingCopy allManagers do: [:wc |
		((wc packageName beginsWith: 'Metacello') or: [ wc packageName beginsWith: 'OB-Metacello' ])
			ifTrue: [ gofer package: wc packageName ]].
	gofer unload.!

----- Method: ConfigurationOf class>>validate (in category 'accessing') -----
validate
	"Check the configuration for Errors, Critical Warnings, and Warnings (see class comment for MetacelloMCVersionValidator for more information). 
	Errors identify specification issues that will result in unexpected behaviour when you load the configuration. 
	Critical Warnings identify specification issues that may result in unexpected behavior when you load the configuration.
	Warnings identify specification issues that are technically correct, but are worth take a look at."

	"self validate"

	<apiDocumentation>
	self ensureMetacello.
	^ ((Smalltalk at: #MetacelloToolBox) validateConfiguration: self debug: #() recurse: false) explore!

----- Method: ConfigurationOf>>bleedingEdge (in category 'defaults') -----
bleedingEdge 
	"override if different behavior desired.
	 Use:
		self versionDoesNotExistError: #bleedingEdge
	 if #bleedingEdge version is disallowed."

	<defaultSymbolicVersion: #bleedingEdge>
	
	^self defaultBleedingEdgeVersion!

----- Method: ConfigurationOf>>customProjectAttributes (in category 'accessing') -----
customProjectAttributes
    "Edit to return a collection of any custom attributes e.g. for conditional loading: Array with: #'Condition1' with: #'Condition2.
	For more information see: http://code.google.com/p/metacello/wiki/CustomProjectAttrributes "

    ^ #()!

----- Method: ConfigurationOf>>defaultBleedingEdgeVersion (in category 'defaults') -----
defaultBleedingEdgeVersion
	| bleedingEdgeVersion |
	bleedingEdgeVersion := (self project map values select: [ :version | version blessing == #baseline ])
		detectMax: [ :version | version ].
	bleedingEdgeVersion ifNil: [ ^#'notDefined' ].
	^ bleedingEdgeVersion versionString!

----- Method: ConfigurationOf>>project (in category 'accessing') -----
project
    ^ project
        ifNil: [ 
            "Bootstrap Metacello if it is not already loaded"
            self class ensureMetacello.
            project := self projectClass new projectAttributes: self customProjectAttributes.	"Create the Metacello project"
            project versionNumberClass: self versionNumberClass.
            project class versionConstructorClass on: self project: project.	"Construct the project"
            project loadType: #'linear'.	"change to #atomic if desired"
            project ]!

----- Method: ConfigurationOf>>project: (in category 'accessing') -----
project: aProject

	project ifNil: [ self class ensureMetacello ].
	project := aProject!

----- Method: ConfigurationOf>>projectClass (in category 'accessing') -----
projectClass
    ^ MetacelloMCProject!

----- Method: ConfigurationOf>>versionDoesNotExistError: (in category 'private') -----
versionDoesNotExistError: versionStringOrSymbol

	((Smalltalk at: #MetacelloSymbolicVersionDoesNotExistError) project: self project versionString: versionStringOrSymbol) signal!

----- Method: ConfigurationOf>>versionNumberClass (in category 'accessing') -----
versionNumberClass
    ^ MetacelloSemanticVersionNumber!

Object subclass: #Metacello
	instanceVariableNames: 'executorSpec statements'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Metacello-Base'!

!Metacello commentStamp: 'dkh 7/28/2012 20:04' prior: 0!
# Metacello User Guide

In this guide we'll take a walk through a couple of common development
scenarios and highlight some of the features of the *Metacello Scripting
API*.

*For installatation and more detailed documentation on the Metacello
Scripting API, see the [Metcello Scripting API Documentation][1].*

## Introduction

The number one job of the *Metacello Scripting API* is to simplify the
job of loading projects into your image. As you are probably all
too aware, today it's a two step process where you first load the
configuration into your image using [Gofer][2] and then load your
project using Metacello:

```Smalltalk
Gofer new
  package: 'ConfigurationOfSeaside30';
  squeaksource: 'MetacelloRepository';
  load.
((Smalltalk at: #ConfigurationOfSeaside30) version: #stable) load.
```

In the early days of Metacello (and Gofer) this was a great improvement
over the alternatives, but today, 3 years after the introduction of
Metacello, there should be a better way...and there is.
Using the *Metacello Scripting API* the above expression reduces to the
following:

```Smalltalk
Metacello new
  configuration: 'Seaside30';
  load.
```

## Loading

In this example of the [`load` command][5] we are leveraging a couple of
default values, namely the `version` of the project and the `repository` where the
**ConfigurationOfSeaside** package can be found:

```Smalltalk
Metacello new
  configuration: 'Seaside30';
  load.
```

Here is a variant
of the same expression with the (current) default values explicitly specified:

```Smalltalk
Metacello new
  configuration: 'Seaside30';
  version: #stable;
  squeaksource: 'MetacelloRepository';
  load.
```

The `version` attribute can be any legal [version number][10].
`squeaksource` is a [repository shortcut][4]. You can also specify the
full [repository description][3] as follows:

```Smalltalk
Metacello new
  configuration: 'Seaside30';
  version: #stable;
  repository: 'http://www.squeaksource.com/MetacelloRepository';
  load.
```

##Listing

Once you've loaded one or more projects into your image, you may want to
list them. The following is an example of the [`list` command][6]:

```Smalltalk
Metacello image
  configuration: [:spec | true ];
  list.
```

The `image` message tells Metacello that you'd like to look
at only loaded configurations. 

The *block* argument to the
`configuration:` message is used to *select* against the list of loaded
[MetacelloProjectSpec][7] instances in the [registry][8].

The `list` command itself returns a list of [MetacelloProjectSpec][7] instances that can be printed, inspected or otherwise manipulated.

In addition to a *select block*, you can specify a *select collection*
specifying the names of the projects you'd like to select:

```Smalltalk
Metacello registry
  configuration: #('Seaside30' 'MetacelloPreview');
  list.
```

The `registry` message tells Metacello that you'd like to
look at all projects in the [registry][8] whether or not they are loaded.

The *collection* argument to the `configuration:` message is used to
*select* against the list of project names in the [registry][8].

The `list` command can also be used to look at configurations in
Monticello repositories. For example:

```Smalltalk
Metacello new
  configuration: [:spec | spec name beginsWith: 'Seaside'];
  squeaksource: 'MetacelloRepository';
  list.
```

lists the configurations whose names (sans the `ConfigurationOf`) begin
with `Seaside` in the `MetacelloRepositry` in the
[Squeaksource](http://www.squeaksource.com) repostory.

## Getting

Once you've loaded a project into your image the next logical step is
upgrading your project to a new version. 

Let's say that a new `#stable` version of Seaside30 has been released
and that you want to upgrade. This is a two step process: 

* [get a new version of the configuration][11]
* [load the new version][12]

### Get a new version of the configuration

The following expression gets the latest version of the
configuration:

```Smalltalk
Metacello image
  configuration: 'Seaside30';
  get.
```

By using the `image` message, you can leverage the fact that the [registry][8] remembers
from which repository you loaded the original version of the configuration.

The `get` command simply downloads the latest version of the
configuration package from the repository.

You may download the configuration from a different repository:

```Smalltalk
Metacello image
  configuration: 'Seaside30';
  squeaksource: 'Seaside30;
  get.
```

The `get` command will update the [registry][8] with the new
repository location information.

You may also use the `get` command to load a configuration for a project
into your image without actually loading the project itself:

```Smalltalk
Metacello image
  configuration: 'SeasideRest';
  squeaksource: 'Seaside30';
  get.
```

The 'SeasideRest' project information will be registered in the [registry][8] and marked
as *unloaded*.

### Load the new version

Once you've got a new copy of the Seaside30 configuration loaded into your image, you may
upgrade your image with the following expression:

```Smalltalk
Metacello image
  configuration: 'Seaside30';
  version: #stable;
  load.
```

By using the `image` message, you are asking Metacello to look the
project up in the [registry][8] before performing the
operation, so it isn't necessary to supply all of the project details for every
command operation.

Of course, the `load` command updates the [registry][8].

If you want to load a project for which you've already done a `get`
(like the SeasideRest project earlier), you can do the following:

```Smalltalk
Metacello registry
  configuration: 'SeasideRest';
  version: #stable;
  load.
```

In this case you use the `registry` message to indicate that you are
interested in both *loaded* and *unloaded* projects.

##Locking

Let's say that you are using an older version of Seaside30 (say 3.0.5)
instead of the #stable version (3.0.7) and that your application doesn't
work with newer versions of Seaside30 (you've tried and it's more work
to get you application to work with the newer version of Seaside30 than
it's worth).

Let's also say that you want to try out something in the
SeasideRest project, but when you try loading SeasideRest, you end up
having Seaside 3.0.7 loaded as well. 

This is an unfortunate side effect of Metacello trying to *do the right
thing*, only in your case it is the wrong thing.

Fortunately, the [`lock` command][9] can give you control. First you
need to `lock` the Seaside30 project:

```Smalltalk
Metacello image
  configuration: 'Seaside30';
  lock.
```

The `image` message tells Metacello to do a lookup in the list of loaded
projects and then to put a lock on the loaded version of the project.

If you want you can specify which version of the project you want
locked:

```Smalltalk
Metacello image
  configuration: 'Seaside30';
  version: '3.0.5';
  lock.
```

After a project is locked an error (**MetacelloLockedProjectError**) is 
thrown when you attempt to load a project that has a dependency upon a 
different version of Seaside30. The error is thrown before any packages 
are actually loaded.

### Bypassing locks

Let's say that you want to load the SeasideRest project even though it may
require a version of Seaside30 that is later than the version that you have
locked. To do that you need to suppress the upgrade of the Seaside30
project during the load of the SeasideRest project and you can do that
with the use of the `onUpgrade:` message:

```Smalltalk
Metacello new
  configuration: 'SeasideRest';
  version: #stable;
  onUpgrade: [:ex :existing :new | 
    existing baseName = 'Seaside30'
      ifTrue: [ ex disallow ].
    ex pass ];
  load.
```

The `onUpgrade:` block tells Metacello to disallow the upgrade of any
project whose `baseName` is `Seaside30` and to continue with the load.
Of course if there are any explicit dependencies between SeasideRest and
the later version of Seaside30 (missing classes, etc.) then you may very
well get load errors or errors while using the SeasideRest, but that's
the price you pay for not upgrading.

### Upgrading a locked project

If you want to explicitly upgrade a locked project, you can use the
`load` command. The following command will upgrade Seaside30 to version
3.0.6 even if it is locked:

 ```Smalltalk
Metacello image
  configuration: 'Seaside30';
  version: '3.0.6';
  lock.
```

The newly loaded of the project will continue to be locked.

[1]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md
[2]: http://www.lukas-renggli.ch/blog/gofer
[3]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#repository-descriptions
[4]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#repository-shortcuts
[5]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#loading
[6]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#listing
[7]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#metacelloprojectspec
[8]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#metacello-project-registry
[9]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#locking
[10]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloScriptingAPI.md#metacello-version-numbers
[11]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloUserGuide.md#get-a-new-version-of-the-configuration
[12]: https://github.com/dalehenrich/metacello-work/blob/master/docs/MetacelloUserGuide.md#load-the-new-version!

----- Method: Metacello class>>classic (in category 'instance creation') -----
classic
    "set the options such that the load performed will be identical to the classic ConfigurationOf load:
	(ConfigurationOfExample project version: '1.0') load
	
	#classic forces Metacello to look at image state to determine which version of a project is loaded instead of using
		the registry to tell us explicitly which version of a project is loaded .. image state is not PRECISE"

    "useCurrentVersion is a 'private' option for enforcing classic rules, so it's not part of scripting api"

    ^ self new
        onUpgrade: [ :ex | ex allow ];
        onConflict: [ :ex | ex allow ];
        addStatement: #'useCurrentVersion:' args: {true};
        yourself!

----- Method: Metacello class>>image (in category 'instance creation') -----
image
    ^ self new
        executorSpec: #'MetacelloScriptImageExecutor' -> 'batch';
        yourself!

----- Method: Metacello class>>registrations (in category 'instance creation') -----
registrations
  ^ MetacelloProjectRegistration registry registrations!

----- Method: Metacello class>>registry (in category 'instance creation') -----
registry
    ^ self new
        executorSpec: #'MetacelloScriptRegistryExecutor' -> 'batch';
        yourself!

----- Method: Metacello class>>scriptExecutorClass (in category 'private') -----
scriptExecutorClass
    ^ self scriptExecutorClass: {(#'MetacelloScriptApiExecutor' -> 'batch')}!

----- Method: Metacello class>>scriptExecutorClass: (in category 'private') -----
scriptExecutorClass: anExecutorSpec
    Smalltalk at: anExecutorSpec key ifAbsent: [ ConfigurationOf ensureMetacello: anExecutorSpec value ].
    ^ Smalltalk at: anExecutorSpec key!

----- Method: Metacello>>addStatement:args: (in category 'private') -----
addStatement: selector args: args
    self statements add: selector -> args!

----- Method: Metacello>>baseline: (in category 'api projectSpec') -----
baseline: projectName
    self addStatement: #'baselineArg:' args: {projectName}!

----- Method: Metacello>>bitbucketUser:project:commitish:path: (in category 'api repository shortcuts') -----
bitbucketUser: userName project: projectName commitish: commitish path: path
  | branchOrCommitOrTag |
  branchOrCommitOrTag := commitish.
  branchOrCommitOrTag isEmpty
    ifTrue: [ branchOrCommitOrTag := 'master' ].
  self
    repository:
      'bitbucket://' , userName , '/' , projectName , ':' , branchOrCommitOrTag , '/'
        , path!

----- Method: Metacello>>blueplane: (in category 'api repository shortcuts') -----
blueplane: projectName
    self repository: 'http://squeaksource.blueplane.jp/' , projectName!

----- Method: Metacello>>cacheRepository: (in category 'api options') -----
cacheRepository: aRepositoryDescription
    self addStatement: #'cacheRepository:' args: {aRepositoryDescription}!

----- Method: Metacello>>className: (in category 'api projectSpec') -----
className: className
    self addStatement: #'classNameArg:' args: {className}!

----- Method: Metacello>>configuration: (in category 'api projectSpec') -----
configuration: projectName
    self addStatement: #'configurationArg:' args: {projectName}!

----- Method: Metacello>>croquet: (in category 'api repository shortcuts') -----
croquet: projectName
    self repository: 'http://hedgehog.software.umn.edu:8888/' , projectName!

----- Method: Metacello>>execute:args: (in category 'private') -----
execute: selector args: args
  | script |
  script := self statements copy.
  script add: selector -> args.
  ^ self scriptExecutor execute: script!

----- Method: Metacello>>executorSpec (in category 'accessing') -----
executorSpec
    executorSpec ifNil: [ executorSpec := #'MetacelloScriptApiExecutor' -> 'batch' ].
    ^ executorSpec!

----- Method: Metacello>>executorSpec: (in category 'accessing') -----
executorSpec: anAssoc
    executorSpec := anAssoc!

----- Method: Metacello>>fetch (in category 'api actions') -----
fetch
  ^ self execute: #'fetch:' args: #(#())!

----- Method: Metacello>>fetch: (in category 'api actions') -----
fetch: required
  ^ self execute: #'fetch:' args: {required}!

----- Method: Metacello>>filetreeDirectory: (in category 'api repository shortcuts') -----
filetreeDirectory: directoryName
  self repository: 'filetree://' , directoryName!

----- Method: Metacello>>gemsource: (in category 'api repository shortcuts') -----
gemsource: projectName
  self repository: 'http://seaside.gemtalksystems.com/ss/' , projectName!

----- Method: Metacello>>get (in category 'api actions') -----
get
  "resolve project name in given repository and return an instance of MetacelloProject resolved from a ConfigurationOf or BaselineOf"

  ^ self execute: #'get' args: #()!

----- Method: Metacello>>githubUser:project:commitish:path: (in category 'api repository shortcuts') -----
githubUser: userName project: projectName commitish: commitish path: path
	"commitish can be a branch name, commit hash, or tag."

	self repository: (
		'github://' , userName , '/' , projectName , (
			(commitish isNil or: [commitish isEmpty])
				ifTrue: ['']
				ifFalse: [':' , commitish]
		) , '/' , path)!

----- Method: Metacello>>githubUser:project:path: (in category 'api repository shortcuts') -----
githubUser: userName project: projectName path: path

	^ self
		githubUser: userName
		project: projectName
		commitish: nil
		path: path!

----- Method: Metacello>>ignoreImage (in category 'api options') -----
ignoreImage
    "ignore image state"

    self addStatement: #'ignoreImage:' args: {true}!

----- Method: Metacello>>impara: (in category 'api repository shortcuts') -----
impara: projectName
    self repository: 'http://source.impara.de/' , projectName!

----- Method: Metacello>>list (in category 'api actions') -----
list
  "list projects in registry"

  ^ self execute: #'list' args: #()!

----- Method: Metacello>>load (in category 'api actions') -----
load
  ^ self execute: #'load:' args: #(#())!

----- Method: Metacello>>load: (in category 'api actions') -----
load: required
  ^ self execute: #'load:' args: {required}!

----- Method: Metacello>>lock (in category 'api actions') -----
lock
  "lock projects in registry"

  ^ self execute: #'lock' args: #()!

----- Method: Metacello>>locked (in category 'api actions') -----
locked
  "list of locked projects in registry"

  ^ self
    project: [ :projectSpec | projectSpec isLocked ];
    list!

----- Method: Metacello>>onConflict: (in category 'api options') -----
onConflict: aBlock
    self addStatement: #'onConflict:' args: {aBlock}!

----- Method: Metacello>>onConflictUseIncoming (in category 'api options') -----
onConflictUseIncoming
  self onConflict: [ :ex :loaded :incoming | ex useIncoming ]!

----- Method: Metacello>>onConflictUseIncoming:useLoaded: (in category 'api options') -----
onConflictUseIncoming: incomingProjects useLoaded: loadedProjects
  self
    onConflict: [ :ex :loaded :incoming | 
      (incomingProjects includes: incoming baseName)
        ifTrue: [ ex useIncoming ]
        ifFalse: [ 
          (loadedProjects includes: incoming baseName)
            ifTrue: [ ex useLoaded ] ].
      ex pass ]!

----- Method: Metacello>>onConflictUseLoaded (in category 'api options') -----
onConflictUseLoaded
  self onConflict: [ :ex :loaded :incoming | ex useLoaded ]!

----- Method: Metacello>>onDowngrade: (in category 'api options') -----
onDowngrade: aBlock
    self addStatement: #'onDowngrade:' args: {aBlock}!

----- Method: Metacello>>onDowngradeUseIncoming (in category 'api options') -----
onDowngradeUseIncoming
  self onDowngrade: [ :ex :loaded :incoming | ex useIncoming ]!

----- Method: Metacello>>onDowngradeUseIncoming: (in category 'api options') -----
onDowngradeUseIncoming: projectNames
  self
    onDowngrade: [ :ex :loaded :incoming | 
      (projectNames includes: loaded baseName)
        ifTrue: [ ex useIncoming ]
        ifFalse: [ ex useLoaded ] ]!

----- Method: Metacello>>onLock: (in category 'api options') -----
onLock: aBlock
  self addStatement: #'onLock:' args: {aBlock}!

----- Method: Metacello>>onLockBreak (in category 'api options') -----
onLockBreak
  self onLock: [ :ex :loaded :incoming | ex break ]!

----- Method: Metacello>>onLockBreak: (in category 'api options') -----
onLockBreak: projectNames
  self
    onLock: [ :ex :loaded :incoming | 
      (projectNames includes: loaded baseName)
        ifTrue: [ ex break ]
        ifFalse: [ ex honor ] ]!

----- Method: Metacello>>onUpgrade: (in category 'api options') -----
onUpgrade: aBlock
    self addStatement: #'onUpgrade:' args: {aBlock}!

----- Method: Metacello>>onUpgradeUseLoaded (in category 'api options') -----
onUpgradeUseLoaded
  self onUpgrade: [ :ex :loaded :incoming | ex useLoaded ]!

----- Method: Metacello>>onUpgradeUseLoaded: (in category 'api options') -----
onUpgradeUseLoaded: projectNames
  self
    onUpgrade: [ :ex :loaded :incoming | 
      (projectNames includes: loaded baseName)
        ifTrue: [ ex useLoaded ]
        ifFalse: [ ex useIncoming ] ]!

----- Method: Metacello>>onWarning: (in category 'api options') -----
onWarning: aBlock
  self addStatement: #'onWarning:' args: {aBlock}!

----- Method: Metacello>>onWarningLog (in category 'api options') -----
onWarningLog
  self
    onWarning: [ :ex | 
      Transcript
        cr;
        show: ex description.
      ex resume ]!

----- Method: Metacello>>password: (in category 'api projectSpec') -----
password: aString
	"Password or access token to authenticate to the repository. Optional. Depending on the repository provider, the username might be optional if an access token is provided as a password. See https://github.com/Metacello/metacello/pull/536. See also implementors of #sitePassword:."

	self addStatement: #'passwordArg:' args: {aString}!

----- Method: Metacello>>project: (in category 'api projectSpec') -----
project: projectName
    self addStatement: #'projectArg:' args: {projectName}!

----- Method: Metacello>>record (in category 'api actions') -----
record
  ^ self execute: #'record:' args: #(#())!

----- Method: Metacello>>record: (in category 'api actions') -----
record: required
  ^ self execute: #'record:' args: {required}!

----- Method: Metacello>>register (in category 'api actions') -----
register
  "change registered project"

  ^ self execute: #'register' args: #()!

----- Method: Metacello>>renggli: (in category 'api repository shortcuts') -----
renggli: projectName
    self repository: 'http://source.lukas-renggli.ch/' , projectName!

----- Method: Metacello>>repository: (in category 'api projectSpec') -----
repository: repositoryDescription
    self addStatement: #'repositoryArg:' args: {repositoryDescription}!

----- Method: Metacello>>repositoryOverrides: (in category 'api options') -----
repositoryOverrides: aRepositoryDescriptionCollection
    self addStatement: #'repositoryOverrides:' args: {aRepositoryDescriptionCollection}!

----- Method: Metacello>>saltypickle: (in category 'api repository shortcuts') -----
saltypickle: projectName
    self repository: 'http://squeak.saltypickle.com/' , projectName!

----- Method: Metacello>>scriptExecutor (in category 'accessing') -----
scriptExecutor
    ^ (self class scriptExecutorClass: self executorSpec) new!

----- Method: Metacello>>silently (in category 'api options') -----
silently
    "no progress bars"

    self addStatement: #'silently:' args: {true}!

----- Method: Metacello>>smalltalkhubUser:project: (in category 'api repository shortcuts') -----
smalltalkhubUser: userName project: projectName
  self
    repository:
      'http://smalltalkhub.com/mc/' , userName , '/' , projectName , '/main'!

----- Method: Metacello>>squeakfoundation: (in category 'api repository shortcuts') -----
squeakfoundation: projectName
    self repository: 'http://source.squeakfoundation.org/' , projectName!

----- Method: Metacello>>squeaksource3: (in category 'api repository shortcuts') -----
squeaksource3: projectName
  self repository: 'http://ss3.gemtalksystems.com/ss/' , projectName!

----- Method: Metacello>>squeaksource: (in category 'api repository shortcuts') -----
squeaksource: projectName
    self repository: 'http://www.squeaksource.com/' , projectName!

----- Method: Metacello>>ss3: (in category 'api repository shortcuts') -----
ss3: projectName
    self squeaksource3: projectName!

----- Method: Metacello>>statements (in category 'accessing') -----
statements
    statements ifNil: [ statements := OrderedCollection new ].
    ^ statements!

----- Method: Metacello>>statements: (in category 'accessing') -----
statements: anObject
	statements := anObject!

----- Method: Metacello>>swa: (in category 'api repository shortcuts') -----
swa: projectName
    self swasource: projectName!

----- Method: Metacello>>swasource: (in category 'api repository shortcuts') -----
swasource: projectName
    self repository: 'http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/' , projectName!

----- Method: Metacello>>unlock (in category 'api actions') -----
unlock
  "unlock projects in registry"

  ^ self execute: #'unlock' args: #()!

----- Method: Metacello>>unregister (in category 'api actions') -----
unregister
  "unlock projects in registry"

  ^ self execute: #'unregister' args: #()!

----- Method: Metacello>>username: (in category 'api projectSpec') -----
username: aString
	"Username to authenticate to the repository. Optional. See https://github.com/Metacello/metacello/pull/536. See also implementors of #siteUsername:."

	self addStatement: #'usernameArg:' args: {aString}!

----- Method: Metacello>>version: (in category 'api projectSpec') -----
version: versionString
    self addStatement: #'versionArg:' args: {versionString}!

----- Method: Metacello>>wiresong: (in category 'api repository shortcuts') -----
wiresong: projectName
    self repository: 'http://source.wiresong.ca/' , projectName!




More information about the Squeak-dev mailing list