├── .gitattributes ├── .github └── workflows │ └── continuous.yml ├── .gitignore ├── .project ├── .smalltalk.ston ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── resources ├── documentation │ └── UserGuide.md └── test │ └── testFile.txt └── src ├── .properties ├── BaselineOfGitBridge ├── BaselineOfGitBridge.class.st └── package.st ├── GitBridge-Tests ├── GitBridgeTest.class.st ├── ManifestGitBridgeTests.class.st └── package.st └── GitBridge ├── GBBridge.class.st ├── GBError.class.st ├── GBRepositoryNotFound.class.st ├── GBRepositoryWithoutLocalRepository.class.st ├── GitBridge.class.st ├── ManifestGitBridge.class.st └── package.st /.gitattributes: -------------------------------------------------------------------------------- 1 | **/*.st linguist-language=Smalltalk -------------------------------------------------------------------------------- /.github/workflows/continuous.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | env: 4 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 5 | 6 | # Controls when the action will run. Triggers the workflow on push or pull request 7 | # events but only for the development branch 8 | on: 9 | push: 10 | branches: 11 | - '**' 12 | pull_request: 13 | types: [assigned, opened, synchronize, reopened] 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | strategy: 19 | matrix: 20 | smalltalk: [ Pharo64-7.0, Pharo64-8.0, Pharo64-9.0, Pharo64-10, Pharo64-11, Pharo64-12, Pharo64-13 ] 21 | name: ${{ matrix.smalltalk }} 22 | steps: 23 | - uses: actions/checkout@v3 24 | with: 25 | fetch-depth: '0' 26 | - uses: hpi-swa/setup-smalltalkCI@v1 27 | with: 28 | smalltalk-image: ${{ matrix.smalltalk }} 29 | - run: smalltalkci -s ${{ matrix.smalltalk }} 30 | shell: bash 31 | timeout-minutes: 15 32 | 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # changes file 2 | *.changes 3 | 4 | # system image 5 | *.image 6 | 7 | # Pharo Smalltalk Debug log file 8 | PharoDebug.log 9 | 10 | # Squeak Smalltalk Debug log file 11 | SqueakDebug.log 12 | 13 | # Monticello package cache 14 | /package-cache 15 | 16 | # playground cache 17 | /play-cache 18 | /play-stash 19 | 20 | # Metacello-github cache 21 | /github-cache 22 | github-*.zip 23 | 24 | **/.DS_STORE 25 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | { 2 | 'srcDirectory' : 'src', 3 | 'tags' : [ #Jecisc ] 4 | } -------------------------------------------------------------------------------- /.smalltalk.ston: -------------------------------------------------------------------------------- 1 | SmalltalkCISpec { 2 | #loading : [ 3 | SCIMetacelloLoadSpec { 4 | #baseline : 'GitBridge', 5 | #directory : 'src', 6 | #registerInIceberg : true 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution 2 | 3 | This file is currently not complete but will be improve step by step. 4 | 5 | # Release management 6 | 7 | This project use semantic versioning to define the releases. This means that each stable release of the project will be assigned a version number of the form `vX.Y.Z`. 8 | 9 | - **X** defines the major version number 10 | - **Y** defines the minor version number 11 | - **Z** defines the patch version number 12 | 13 | When a release contains only bug fixes, the patch number increases. When the release contains new features that are backward compatible, the minor version increases. When the release contains breaking changes, the major version increases. 14 | 15 | Thus, it should be safe to depend on a fixed major version and moving minor version of this project. 16 | 17 | # Branch management 18 | 19 | This project use gitflow management. 20 | 21 | This project contains two main branches: 22 | - **master** : This branch is a stable branch. Each version on this branch should be a stable release of Material Components for Seaside, and idealy each commit modifying the source code of the project should be tagged with a version number. 23 | - **development** : This branch contains the current development of this project. 24 | 25 | ## New feature 26 | 27 | When a new feature will take some time to implement, this feature should be developed in a specific branch. Once done, it will be merged in development before the next release of Material Design Lite for Seaside. 28 | 29 | ## Hot fix 30 | 31 | If a bug is found in a stable version and the correction is backward compatible, it should be corrected in an hotfix branch. Once the correction is finished the hotfix branch should be merged into master and development and a new bugfix release should be done. 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 CyrilFerlicot 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitBridge 2 | 3 | GitBridge is a project which allow Pharo projects to communicate with the git repository storing them. Once the bridge is made, you can access resources in or information about the repository. 4 | 5 | - [Installation](#installation) 6 | - [Quick start](#quick-start) 7 | - [Documentation](#documentation) 8 | - [Version management](#version-management) 9 | - [Smalltalk versions compatibility](#smalltalk-versions-compatibility) 10 | - [Contact](#contact) 11 | 12 | ## Installation 13 | 14 | To install GitBridge in your Pharo image execute: 15 | 16 | ```Smalltalk 17 | Metacello new 18 | githubUser: 'jecisc' project: 'GitBridge' commitish: 'v1.x.x' path: 'src'; 19 | baseline: 'GitBridge'; 20 | load 21 | ``` 22 | 23 | To add it to your baseline: 24 | 25 | ```Smalltalk 26 | spec 27 | baseline: 'GitBridge' 28 | with: [ spec repository: 'github://jecisc/GitBridge:v1.x.x/src' ] 29 | ``` 30 | 31 | Note that you can replace the #v1.x.x by another branch such as #development or a tag such as #v1.0.0, #v1.? or #v1.1.?. 32 | 33 | ## Quick start 34 | 35 | In order to create a GitBridge to your project, you first need to subclass `GitBridge` and to store your bridge in a package of your project. 36 | 37 | ```Smalltalk 38 | GitBridge subclass: #MyProjectBridge 39 | slots: { } 40 | classVariables: { } 41 | package: 'MyProject' 42 | ``` 43 | 44 | This new bridge needs a class initialization like this one: 45 | 46 | ```Smalltalk 47 | MyProjectBridge class>>initialize 48 | SessionManager default registerSystemClassNamed: self name 49 | ``` 50 | 51 | This will allow the bridge to reset some cache at the image startup. 52 | 53 | Now that your bridge is created, if it finds an Iceberg repository, associated to its local clone, containing the package in which the bridge is defined, you will be able to use the bridge to access some resources. 54 | 55 | For example you can get a file reference to the git folder like this: 56 | 57 | ```Smalltalk 58 | MyProjectBridge root 59 | ``` 60 | 61 | You can open the git repository by executing: 62 | 63 | ```Smalltalk 64 | MyProjectBridge openInNativeFileSystem 65 | ``` 66 | 67 | You can get the version of you project by executing: 68 | 69 | ```Smalltalk 70 | MyProjectBridge versionOrBranchNameWithLastTag 71 | ``` 72 | 73 | For more informations see the following documentation. 74 | 75 | ## Documentation 76 | 77 | You can find the full documentation here : [User documentation](resources/documentation/UserGuide.md). 78 | 79 | ## Version management 80 | 81 | This project uses semantic versioning to define the releases. This means that each stable release of the project will be assigned a version number of the form `vX.Y.Z`. 82 | 83 | - **X** defines the major version number 84 | - **Y** defines the minor version number 85 | - **Z** defines the patch version number 86 | 87 | When a release contains only bug fixes, the patch number increases. When the release contains new features that are backward compatible, the minor version increases. When the release contains breaking changes, the major version increases. 88 | 89 | Thus, it should be safe to depend on a fixed major version and moving minor version of this project. 90 | 91 | ## Smalltalk versions compatibility 92 | 93 | | Version | Compatible Pharo versions | 94 | |------------- |--------------------------- | 95 | | 1.x.x | Pharo 70, 80, 90, 10, 11 | 96 | 97 | ## Contact 98 | 99 | If you have any questions or problems do not hesitate to open an issue or contact cyril (a) ferlicot.me 100 | -------------------------------------------------------------------------------- /resources/documentation/UserGuide.md: -------------------------------------------------------------------------------- 1 | # User documentation of GitBridge 2 | 3 | GitBridge is a project allowing Pharo projects to communicate with the git repository storing them. Once the bridge is made, you can access resources in and get information about the repository. 4 | 5 | This documentation will cover the creation of a GitBridge for your project and all the different features it offers. 6 | 7 | > Some notes like this one will be present in the documentation. They will give implementation details since there is not enough material to do a full page on implementation details. 8 | 9 | - [Create a bridge for your project](#create-a-bridge-for-your-project) 10 | * [Create a simple bridge](#create-a-simple-bridge) 11 | * [Add conditions on the bridge selection](#add-conditions-on-the-bridge-selection) 12 | - [Access resources and information](#access-resources-and-information) 13 | * [Access to local resources](#access-to-local-resources) 14 | * [Get information of the project version](#get-information-of-the-project-version) 15 | * [Actions](#actions) 16 | - [Use GitBridge in CI environment](#use-gitbridge-in-ci-environment) 17 | 18 | ## Create a bridge for your project 19 | 20 | ### Create a simple bridge 21 | 22 | In order to create a simple GitBridge to your project, you first need to subclass `GitBridge` and to store your bridge in a package of your project. 23 | 24 | ```Smalltalk 25 | GitBridge subclass: #MyProjectBridge 26 | slots: { } 27 | classVariables: { } 28 | package: 'MyProject' 29 | ``` 30 | 31 | This new bridge needs a class initialization like this one: 32 | 33 | ```Smalltalk 34 | MyProjectBridge class>>initialize 35 | SessionManager default registerSystemClassNamed: self name 36 | ``` 37 | 38 | This will allow the bridge to reset some cache at the image startup. 39 | 40 | > When you access your bridge for the first time after you launched your image, the Iceberg repository linked to your project will be cached. By registering your bridge to the SessionManager you will provide a way to your image to clear this cache at startup in case you moved your image. If you need to clear the cache yourself, you can call the method `#reset` on your git bridge. 41 | 42 | By default, a bridge will be made to the first Iceberg repository registered meeting two conditions: 43 | - The repository needs to contain the package in which the bridge is defined (here `MyProject`) 44 | - The repository needs to have a local clone of the project 45 | 46 | In case none of those conditions are met, special exceptions will be launched: `GBRepositoryNotFound` or `GBRepositoryWithoutLocalRepository`. 47 | 48 | ### Add conditions on the bridge selection 49 | 50 | The previous section shows how to create bridges for simple projects, but sometimes this is not enough. For example, if the package containing your bridge is present in multiple projects, you might want to add more conditions to your repository lookup. 51 | 52 | This is possible in two ways. 53 | 54 | The first one is to override the method `#isValideRepository:`. This method will be called with each iceberg repository as parameter. In case we want to select the first repository containing the package of the bridge that does not contain a package `BaselineOfPharo` we can do: 55 | 56 | ```Smalltalk 57 | MyProjectBridge class>>isValidRepository: anIcebergRepository 58 | ^ (super isValidRepository: anIcebergRepository) and: [ (anIcebergRepository includesPackageNamed: 'BaselineOfPharo') not ] 59 | ``` 60 | 61 | The second way is to override the method `findIcebergRepository` to create your own lookup. 62 | 63 | ## Access resources and information 64 | 65 | Once your bridge created, you have the possibility to access diverse information. 66 | 67 | ### Access to local resources 68 | 69 | One of the main feature of GitBridge is to be able to access local resources. Before Pharo improved its git integration, we used Monticello to store code. Monticello did not allow the developer to store files. Thus, a lot of projects stored files in memory or downloaded them during the installation. Now, with GitBridge, we can just store them in a git repository and access them from the image via a GitBridge. 70 | 71 | This can be useful in many case such has: 72 | - Storing files used as test resources 73 | - Access to CSS, JS or image files for web applications 74 | - Storing documentation in Markdown format to get a nice rendering in Github/Bitbucket/Gitlab 75 | - ... 76 | 77 | Access to those files can be easily done via the GitBridge: 78 | 79 | ```Smalltalk 80 | MyProjectBridge root. "Return a FileReference to the root folder of the git repository." 81 | 82 | MyProjectBridge sourceDirectory. "Return a FileReference to the source directory of the project." 83 | ``` 84 | 85 | You can also create your own access methods such as: 86 | 87 | ```Smalltalk 88 | MyProjectBridge class>>resources 89 | ^ self root / 'resources' 90 | ``` 91 | 92 | ### Get information of the project version 93 | 94 | It can often be useful to display version info for a project. Git bridge allows one to access such info. Here is a description of the API: 95 | - `#gitTags` : Return the list of all tags of the project. 96 | - `#currentBranchName` : Return the name of the current branch. 97 | - `#tagsOfCurrentCommit` : Return the tags of the current commit. If none, return an empty array. 98 | - `#tagsOfClosestTaggedAncestor` : Return the tags of the closest ancestor with tags. 99 | - `#version` : Return a string which can either be a tag name of the current commit or a branch name in case the commit has no tag. 100 | - `#closestVersion` : Return a string which can either be the tag name of the closest tagged ancestor commit or a branch name in case the project has no tag. 101 | - `#versionOrBranchNameWithLastTag` : Return the name of a tag of the current commit, in case there is none, return the name of the current branch with the tag name of the closest ancestor in parenthesis. 102 | 103 | Example: 104 | 105 | ```Smalltalk 106 | MyProjectBridge gitTags. "an Array(IceTag: 'v0.1.0' IceTag: 'v1.0.0' IceTag: 'v1.0.x' IceTag: 'v1.x.x')" 107 | 108 | MyProjectBridge currentBranchName. "'master'" 109 | 110 | MyProjectBridge tagsOfCurrentCommit. "#()" 111 | 112 | MyProjectBridge tagsOfClosestTaggedAncestor. "an Array(IceTag: 'v1.0.0' IceTag: 'v1.0.x' IceTag: 'v1.x.x')" 113 | 114 | MyProjectBridge version. "'master'" 115 | 116 | MyProjectBridge closestVersion. "'v1.0.0'" 117 | 118 | MyProjectBridge versionOrBranchNameWithLastTag. "'master (from v1.0.0)'" 119 | ``` 120 | 121 | ### Actions 122 | 123 | GitBridge can also be used to enable some actions. 124 | 125 | For now, only one action is possible: open in the Native file browser the root folder of the git repository. 126 | 127 | ```Smalltalk 128 | MyProjectBridge openInNativeFileSystem 129 | ``` 130 | 131 | ## Use GitBridge in CI environment 132 | 133 | If you use your Git Bridge to access resources in tests, you might need some extra setup with your continuous integration. 134 | 135 | For Jenkins, if you use a bash script, you might not need any extra step since you will probably load your project with the Iceberg integration enabled. 136 | 137 | If you use SmalltalkCI (in Github actions, gitlab ci or other supported CI), you will need to register your repository in Iceberg since SmalltalkCI disable the Metacello integration by default. 138 | 139 | You can do this via your smalltalk.ston file. For example: 140 | 141 | ```Smalltalk 142 | SmalltalkCISpec { 143 | #loading : [ 144 | SCIMetacelloLoadSpec { 145 | #baseline : 'GitBridge', 146 | #directory : 'src', 147 | #registerInIceberg : true 148 | } 149 | ] 150 | } 151 | ``` 152 | 153 | ### Use GitHub actions 154 | 155 | When using GitHub actions, it is necessary to configure the `actions/checkout@v3` to fetch the all commits history. 156 | 157 | Using the action looks like this: 158 | 159 | ```yml 160 | steps: 161 | - uses: actions/checkout@v3 162 | with: 163 | fetch-depth: '0' 164 | ``` 165 | -------------------------------------------------------------------------------- /resources/test/testFile.txt: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /src/.properties: -------------------------------------------------------------------------------- 1 | { 2 | #format : #tonel 3 | } -------------------------------------------------------------------------------- /src/BaselineOfGitBridge/BaselineOfGitBridge.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : #BaselineOfGitBridge, 3 | #superclass : #BaselineOf, 4 | #category : #BaselineOfGitBridge 5 | } 6 | 7 | { #category : #baselines } 8 | BaselineOfGitBridge >> baseline: spec [ 9 | 10 | spec 11 | for: #common 12 | do: [ "Packages" 13 | spec 14 | package: 'GitBridge'; 15 | package: 'GitBridge-Tests' with: [ spec requires: #('GitBridge') ]. 16 | 17 | "Group" 18 | spec 19 | group: 'Minimal' with: #('GitBridge'); 20 | group: 'Tests' with: #('GitBridge-Tests') ]. 21 | 22 | spec 23 | for: #'pharo7.x' 24 | do: [ self nativeBrowser: spec. 25 | spec package: 'GitBridge' with: [ spec requires: #('NativeBrowser') ] ] 26 | ] 27 | 28 | { #category : #dependencies } 29 | BaselineOfGitBridge >> nativeBrowser: spec [ 30 | spec baseline: 'NativeBrowser' with: [ spec repository: 'github://jecisc/Native-Browser:v1.x.x/src' ] 31 | ] 32 | 33 | { #category : #accessing } 34 | BaselineOfGitBridge >> projectClass [ 35 | ^ self class environment at: #MetacelloCypressBaselineProject ifAbsent: [ super projectClass ] 36 | ] 37 | -------------------------------------------------------------------------------- /src/BaselineOfGitBridge/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #BaselineOfGitBridge } 2 | -------------------------------------------------------------------------------- /src/GitBridge-Tests/GitBridgeTest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : #GitBridgeTest, 3 | #superclass : #TestCase, 4 | #instVars : [ 5 | 'bridge' 6 | ], 7 | #category : #'GitBridge-Tests' 8 | } 9 | 10 | { #category : #running } 11 | GitBridgeTest >> setUp [ 12 | super setUp. 13 | bridge := GBBridge 14 | ] 15 | 16 | { #category : #tests } 17 | GitBridgeTest >> testGitTags [ 18 | self assert: (bridge gitTags anySatisfy: [ :tag | tag name = 'tagForTests' ]) 19 | ] 20 | 21 | { #category : #tests } 22 | GitBridgeTest >> testIcebergRepository [ 23 | self shouldnt: [ bridge icebergRepository ] raise: Error. 24 | self assert: (bridge testResources / 'testFile.txt') contents equals: 'test' 25 | ] 26 | 27 | { #category : #tests } 28 | GitBridgeTest >> testRoot [ 29 | self assert: bridge root exists. 30 | self assert: ((bridge root entries collect: #basename) includesAll: #('README.md' 'resources' 'src')) 31 | ] 32 | 33 | { #category : #tests } 34 | GitBridgeTest >> testSourceDirectory [ 35 | self assert: bridge sourceDirectory exists. 36 | self assert: bridge sourceDirectory basename equals: 'src' 37 | ] 38 | 39 | { #category : #tests } 40 | GitBridgeTest >> testTagsOfClosestTaggedAncestor [ 41 | self shouldnt: [ bridge tagsOfClosestTaggedAncestor ] raise: Error. 42 | self assert: bridge tagsOfClosestTaggedAncestor isCollection 43 | ] 44 | 45 | { #category : #tests } 46 | GitBridgeTest >> testTagsOfCurrentCommit [ 47 | self shouldnt: [ bridge tagsOfCurrentCommit ] raise: Error. 48 | self assert: bridge tagsOfCurrentCommit isCollection 49 | ] 50 | -------------------------------------------------------------------------------- /src/GitBridge-Tests/ManifestGitBridgeTests.class.st: -------------------------------------------------------------------------------- 1 | " 2 | GitBridge is a project allow Pharo projects to communicate with the git repository storing them. 3 | 4 | Once the bridge is made, you can access resources or informations about the repository. 5 | " 6 | Class { 7 | #name : #ManifestGitBridgeTests, 8 | #superclass : #PackageManifest, 9 | #category : #'GitBridge-Tests-Manifest' 10 | } 11 | -------------------------------------------------------------------------------- /src/GitBridge-Tests/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'GitBridge-Tests' } 2 | -------------------------------------------------------------------------------- /src/GitBridge/GBBridge.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Description 3 | -------------------- 4 | 5 | I am a git bridge for the GitBridge project. I mostly serve as example and for tests. 6 | " 7 | Class { 8 | #name : #GBBridge, 9 | #superclass : #GitBridge, 10 | #category : #GitBridge 11 | } 12 | 13 | { #category : #'class initialization' } 14 | GBBridge class >> initialize [ 15 | SessionManager default registerSystemClassNamed: self name 16 | ] 17 | 18 | { #category : #accessing } 19 | GBBridge class >> resources [ 20 | ^ self root / 'resources' 21 | ] 22 | 23 | { #category : #accessing } 24 | GBBridge class >> testResources [ 25 | ^ self resources / 'test' 26 | ] 27 | -------------------------------------------------------------------------------- /src/GitBridge/GBError.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Description 3 | -------------------- 4 | 5 | I am a common superclass for all GitBridge errors. 6 | " 7 | Class { 8 | #name : #GBError, 9 | #superclass : #Error, 10 | #instVars : [ 11 | 'bridge' 12 | ], 13 | #category : #GitBridge 14 | } 15 | 16 | { #category : #signalling } 17 | GBError class >> signalFor: aGitBridge [ 18 | ^ self new 19 | bridge: aGitBridge; 20 | signal 21 | ] 22 | 23 | { #category : #accessing } 24 | GBError >> bridge [ 25 | ^ bridge 26 | ] 27 | 28 | { #category : #accessing } 29 | GBError >> bridge: anObject [ 30 | bridge := anObject 31 | ] 32 | -------------------------------------------------------------------------------- /src/GitBridge/GBRepositoryNotFound.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Description 3 | -------------------- 4 | 5 | I am an error raised when no repository in Iceberg correspond to the current bridge. 6 | 7 | Examples 8 | -------------------- 9 | 10 | GBRepositoryNotFound signalFor: GBBridge 11 | " 12 | Class { 13 | #name : #GBRepositoryNotFound, 14 | #superclass : #GBError, 15 | #category : #GitBridge 16 | } 17 | 18 | { #category : #accessing } 19 | GBRepositoryNotFound >> messageText [ 20 | ^ String 21 | streamContents: [ :stream | 22 | stream 23 | << 'Bridge not found. Associate an Iceberg repository containing the package '; 24 | << self bridge package name; 25 | << ' to use the bridge.'; 26 | lf; 27 | << 'Available repositories:'; 28 | lf. 29 | IceRepository registry do: [ :each | stream << '- ' << each name ] separatedBy: [ stream lf ] ] 30 | ] 31 | -------------------------------------------------------------------------------- /src/GitBridge/GBRepositoryWithoutLocalRepository.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Description 3 | -------------------- 4 | 5 | I am an error raised when an Iceberg corresponding to the current bridge is found but does not have a local repository. 6 | 7 | Examples 8 | -------------------- 9 | 10 | GBRepositoryWithoutLocalRepository signalFor: GBBridge 11 | " 12 | Class { 13 | #name : #GBRepositoryWithoutLocalRepository, 14 | #superclass : #GBError, 15 | #category : #GitBridge 16 | } 17 | 18 | { #category : #accessing } 19 | GBRepositoryWithoutLocalRepository >> messageText [ 20 | ^ 'The iceberg repository responsible of the bridge does not have a local repository associated. Please provide a local repository in Iceberg to proceed.' 21 | ] 22 | -------------------------------------------------------------------------------- /src/GitBridge/GitBridge.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Description 3 | -------------------- 4 | 5 | I am an abstract superclass for git bridge. 6 | 7 | My subclass should includes an initialize class method calling: `SessionManager default registerSystemClassNamed: self name`. 8 | 9 | My subclasses will be used as a bridge to a git repository for a project. Then they will be used to access things such has: 10 | - Resources stored in the git repository 11 | - Git informations such the the current version of the project (tag) 12 | - ... 13 | 14 | In order to find those information, GitBridge will check the repositories registered in Iceberg and find the first one containing the package storing the GitBridge. 15 | 16 | You can add more/different condition by overriding the method #isValidRepository:. 17 | 18 | A cache containing the found repository will be created and flush at each startup. 19 | 20 | In case no valid repository is present, an error will be thrown. 21 | 22 | 23 | Examples with GBBrigde 24 | -------------------- 25 | 26 | GBBridge root. ""File @ C:\Users\JeCisC\Pharo\GitRepositories\jecisc\GitBridge"" 27 | 28 | GBBridge sourceDirectory. ""File @ C:\Users\JeCisC\Pharo\GitRepositories\jecisc\GitBridge\src"" 29 | 30 | GBBridge currentBranchName. ""'master'"" 31 | 32 | GBBridge tagsOfCurrentCommit. ""#()"" 33 | 34 | GBBridge tagsOfClosestTaggedAncestor. ""an Array(IceTag: 'v1.0.0' IceTag: 'v1.x.x')"" 35 | 36 | GBBridge version. ""'master'"" 37 | 38 | GBBridge closestVersion. ""'v1.0.0'"" 39 | 40 | GBBridge versionOrBranchNameWithLastTag. ""'master (from v1.0.0)'"" 41 | 42 | GBBridge openInNativeFileSystem. 43 | " 44 | Class { 45 | #name : #GitBridge, 46 | #superclass : #Object, 47 | #classInstVars : [ 48 | 'repositoryCache' 49 | ], 50 | #category : #GitBridge 51 | } 52 | 53 | { #category : #versions } 54 | GitBridge class >> closestVersion [ 55 | ^ self 56 | do: [ self tagsOfClosestTaggedAncestor ifEmpty: [ self currentBranchName ] ifNotEmpty: [ :tags | "If there is more than one, take randomly." tags anyOne name ] ] 57 | onRepositoryProblem: [ 'No repository' ] 58 | ] 59 | 60 | { #category : #versions } 61 | GitBridge class >> currentBranchName [ 62 | ^ self icebergRepository branchName 63 | ] 64 | 65 | { #category : #execution } 66 | GitBridge class >> do: aBlock onRepositoryProblem: anotherBlock [ 67 | ^ [ aBlock value ] 68 | on: GBError 69 | do: anotherBlock 70 | ] 71 | 72 | { #category : #actions } 73 | GitBridge class >> findIcebergRepository [ 74 | ^ IceRepository registry detect: [ :each | self isValidRepository: each ] ifNone: [ GBRepositoryNotFound signalFor: self ] 75 | ] 76 | 77 | { #category : #versions } 78 | GitBridge class >> gitTags [ 79 | ^ self icebergRepository tags 80 | ] 81 | 82 | { #category : #assessing } 83 | GitBridge class >> icebergRepository [ 84 | ^ repositoryCache ifNil: [ repositoryCache := self findIcebergRepository ] 85 | ] 86 | 87 | { #category : #'class initialization' } 88 | GitBridge class >> initialize [ 89 | SessionManager default registerSystemClassNamed: self name 90 | ] 91 | 92 | { #category : #testing } 93 | GitBridge class >> isAbstract [ 94 | ^ self = GitBridge 95 | ] 96 | 97 | { #category : #testing } 98 | GitBridge class >> isValidRepository: anIcebergRepository [ 99 | ^ anIcebergRepository includesPackageNamed: self package name 100 | ] 101 | 102 | { #category : #actions } 103 | GitBridge class >> openInNativeFileSystem [ 104 | self root openInNativeBrowser 105 | ] 106 | 107 | { #category : #'class initialization' } 108 | GitBridge class >> reset [ 109 | repositoryCache := nil 110 | ] 111 | 112 | { #category : #assessing } 113 | GitBridge class >> root [ 114 | | location | 115 | location := self icebergRepository location. 116 | (location isNil or: [ location exists not ]) ifTrue: [ GBRepositoryWithoutLocalRepository signalFor: self ]. 117 | ^ location 118 | ] 119 | 120 | { #category : #assessing } 121 | GitBridge class >> sourceDirectory [ 122 | ^ self icebergRepository subdirectoryReference 123 | ] 124 | 125 | { #category : #'system startup' } 126 | GitBridge class >> startUp [ 127 | self reset 128 | ] 129 | 130 | { #category : #versions } 131 | GitBridge class >> tagsOfClosestTaggedAncestor [ 132 | self icebergRepository workingCopy referenceCommit commitsDo: [ :commit | commit tags ifNotEmpty: [ :collection | ^ collection ] ]. 133 | 134 | ^ #() 135 | ] 136 | 137 | { #category : #versions } 138 | GitBridge class >> tagsOfCurrentCommit [ 139 | ^ self icebergRepository workingCopy referenceCommit tags 140 | ] 141 | 142 | { #category : #versions } 143 | GitBridge class >> version [ 144 | ^ self 145 | do: [ self tagsOfCurrentCommit ifEmpty: [ self currentBranchName ] ifNotEmpty: [ :tags | "If there is more than one, take randomly." tags anyOne name ] ] 146 | onRepositoryProblem: [ 'No repository' ] 147 | ] 148 | 149 | { #category : #versions } 150 | GitBridge class >> versionOrBranchNameWithLastTag [ 151 | "If there is more than one tag, take randomly." 152 | 153 | ^ self 154 | do: [ self tagsOfCurrentCommit 155 | ifEmpty: [ self tagsOfClosestTaggedAncestor ifEmpty: [ self currentBranchName ] ifNotEmpty: [ :tags | '{1} (from {2})' format: {self currentBranchName . tags anyOne name} ] ] 156 | ifNotEmpty: [ :tags | tags anyOne name ] ] 157 | onRepositoryProblem: [ 'No repository' ] 158 | ] 159 | -------------------------------------------------------------------------------- /src/GitBridge/ManifestGitBridge.class.st: -------------------------------------------------------------------------------- 1 | " 2 | GitBridge is a project allow Pharo projects to communicate with the git repository storing them. 3 | 4 | Once the bridge is made, you can access resources or informations about the repository. 5 | " 6 | Class { 7 | #name : #ManifestGitBridge, 8 | #superclass : #PackageManifest, 9 | #category : #'GitBridge-Manifest' 10 | } 11 | -------------------------------------------------------------------------------- /src/GitBridge/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #GitBridge } 2 | --------------------------------------------------------------------------------