From 5de6a8102941968a9be9fb9563917613250a70cd Mon Sep 17 00:00:00 2001 From: Offray Luna Date: Sun, 19 May 2024 11:47:59 -0500 Subject: [PATCH] Using GtSubprocess instead of OSSubprocess. Will backporting this to "plain" Pharo be a future issue? --- src/ExoRepo/Brew.class.st | 40 +-- src/ExoRepo/ExoPackage.class.st | 84 +++--- src/ExoRepo/ExoRepo.class.st | 246 +++++++++--------- src/ExoRepo/GitHubAsset.class.st | 112 ++++---- src/ExoRepo/Gofer.extension.st | 28 +- src/ExoRepo/MCGiteabRepository.class.st | 158 +++++------ src/ExoRepo/MCGiteabRepository.extension.st | 12 +- .../MetacelloCommonMCSpecLoader.extension.st | 30 +-- src/ExoRepo/MetacelloPlatform.extension.st | 64 ++--- src/ExoRepo/MultiPack.class.st | 54 ++-- src/ExoRepo/NanoID.class.st | 132 +++++----- src/ExoRepo/Nimble.class.st | 178 ++++++------- src/ExoRepo/YQ.class.st | 116 ++++----- src/ExoRepo/package.st | 2 +- 14 files changed, 626 insertions(+), 630 deletions(-) diff --git a/src/ExoRepo/Brew.class.st b/src/ExoRepo/Brew.class.st index 6357f3c..283906e 100644 --- a/src/ExoRepo/Brew.class.st +++ b/src/ExoRepo/Brew.class.st @@ -1,20 +1,20 @@ -Class { - #name : #Brew, - #superclass : #Object, - #category : #ExoRepo -} - -{ #category : #accessing } -Brew class >> install [ - "This is a preliminary starting installation script that is not working. - Dependencies and sudo access are not managed here. - For example, doing 'sudo -S base-devel' on Arch based systems or - 'brew intall gcc' is yet not managed here." - Smalltalk os isWindows ifTrue: [ ^ nil ]. - OSSUnixSubprocess new - shellCommand: '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'; - redirectStdout; - runAndWaitOnExitDo: [ :command :outString | - ^ outString - ]. -] +Class { + #name : #Brew, + #superclass : #Object, + #category : #ExoRepo +} + +{ #category : #accessing } +Brew class >> install [ + "This is a preliminary starting installation script that is not working. + Dependencies and sudo access are not managed here. + For example, doing 'sudo -S base-devel' on Arch based systems or + 'brew intall gcc' is yet not managed here." + Smalltalk os isWindows ifTrue: [ ^ nil ]. + OSSUnixSubprocess new + shellCommand: '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'; + redirectStdout; + runAndWaitOnExitDo: [ :command :outString | + ^ outString + ]. +] diff --git a/src/ExoRepo/ExoPackage.class.st b/src/ExoRepo/ExoPackage.class.st index 48b6d09..a211314 100644 --- a/src/ExoRepo/ExoPackage.class.st +++ b/src/ExoRepo/ExoPackage.class.st @@ -1,42 +1,42 @@ -Class { - #name : #ExoPackage, - #superclass : #Object, - #instVars : [ - 'repository' - ], - #category : #'ExoRepo-External' -} - -{ #category : #accessing } -ExoPackage class >> githubAPIEndPoint [ - ^ 'https://api.github.com/' asUrl -] - -{ #category : #accessing } -ExoPackage >> assets [ - ^ (self lastReleaseData at: 'assets') collect: [:each | - GitHubAsset fromDictionary: each - ] -] - -{ #category : #accessing } -ExoPackage >> lastReleaseData [ - | releasesLink | - releasesLink := self class githubAPIEndPoint addPathSegment: 'repos'. - self repository asUrl segments do: [:segment | - releasesLink addPathSegment: segment - ]. - releasesLink addPathSegment: 'releases'. - ^ (STONJSON - fromString: releasesLink retrieveContents) first -] - -{ #category : #accessing } -ExoPackage >> repository [ - ^ repository -] - -{ #category : #accessing } -ExoPackage >> repository: anUrl [ - repository := anUrl -] +Class { + #name : #ExoPackage, + #superclass : #Object, + #instVars : [ + 'repository' + ], + #category : #'ExoRepo-External' +} + +{ #category : #accessing } +ExoPackage class >> githubAPIEndPoint [ + ^ 'https://api.github.com/' asUrl +] + +{ #category : #accessing } +ExoPackage >> assets [ + ^ (self lastReleaseData at: 'assets') collect: [:each | + GitHubAsset fromDictionary: each + ] +] + +{ #category : #accessing } +ExoPackage >> lastReleaseData [ + | releasesLink | + releasesLink := self class githubAPIEndPoint addPathSegment: 'repos'. + self repository asUrl segments do: [:segment | + releasesLink addPathSegment: segment + ]. + releasesLink addPathSegment: 'releases'. + ^ (STONJSON + fromString: releasesLink retrieveContents) first +] + +{ #category : #accessing } +ExoPackage >> repository [ + ^ repository +] + +{ #category : #accessing } +ExoPackage >> repository: anUrl [ + repository := anUrl +] diff --git a/src/ExoRepo/ExoRepo.class.st b/src/ExoRepo/ExoRepo.class.st index c4b94f2..d9eaf83 100644 --- a/src/ExoRepo/ExoRepo.class.st +++ b/src/ExoRepo/ExoRepo.class.st @@ -1,123 +1,123 @@ -Class { - #name : #ExoRepo, - #superclass : #Object, - #instVars : [ - 'repository' - ], - #category : #ExoRepo -} - -{ #category : #accessing } -ExoRepo class >> index [ - "I list a set of external recommended repositories from the Grafoscopio community, in installation order." - | reposIndex repositoryAddresses users | - users := #('Offray' 'mutabiT' 'ruidajo' ). - reposIndex := OrderedCollection new. - repositoryAddresses := users do: [:user | - reposIndex add: - ((STONJSON fromString:('https://code.sustrato.red/api/v1/users/', user, '/repos') asZnUrl retrieveContents) collect: [:repo | - (repo at: 'name') -> (repo at: 'html_url')])]. - ^ (reposIndex flatCollect: [:i | i]) asDictionary -] - -{ #category : #accessing } -ExoRepo class >> install: shortNameString [ - | repo exoRepo | - [repo := self index at: shortNameString] - onErrorDo: [:err | UIManager default inform: 'No repository named: ', shortNameString, '. - Please run ExoRepo index - to list know repositories or load your own repository with: - - ExoRepo new - repository: {repositoryAddres}; - load. - - replacing {repositoryAddres} with a Git public repository'.^ {self new. err}]. - exoRepo := self new repository: repo. - (IceRepositoryCreator new - location: exoRepo local; - remote: (IceGitRemote url: repo); - createRepository) register. - ^ exoRepo load -] - -{ #category : #accessing } -ExoRepo class >> userDataFolder [ - Smalltalk os isWindows - ifTrue: [ ^ FileLocator home / 'AppData' / 'Local' ] - ifFalse: [ ^ FileLocator userData ]. -] - -{ #category : #accessing } -ExoRepo >> load [ - "I load the configuration of this package using a external Gitea repository." - - "While more Git independient providers are implemented in Monticello, I will - use Iceberg to download the repository and load it from a local directory" - - | localRepo repoName count | - repoName := self repositoryName. - self local exists - ifFalse: [ (IceRepositoryCreator new - location: self local; - remote: (IceGitRemote url: self repository greaseString ", '.git'"); - createRepository) register ]. - localRepo := 'gitlocal://' , self local fullName. - count := 1. - [ true ] - whileTrue: [ [ ^ Metacello new - repository: localRepo; - baseline: repoName; - onConflictUseLoaded; - onWarningLog; - load ] - on: IceGenericError - do: [ :ex | - Notification - signal: (String with: Character cr) , ex description , (String with: Character cr) - , 'RETRYING ' , count greaseString. - (Delay forSeconds: 2) wait. - ex retry ]. - count := count + 1 ] -] - -{ #category : #accessing } -ExoRepo >> local [ - ^ FileLocator localDirectory / 'iceberg' / (self provider) / self repositoryName -] - -{ #category : #accessing } -ExoRepo >> printOn: aStream [ - super initialize. - self repository ifNotNil: [ - aStream nextPutAll: self repositoryName, ' | ', self repository asString] - ifNil: [ aStream nextPutAll: 'ExoRepo without repository' ]. -] - -{ #category : #accessing } -ExoRepo >> provider [ - self repository ifNil: [ ^ nil ]. - ^ self repository segments first -] - -{ #category : #accessing } -ExoRepo >> repository [ - ^ repository. -] - -{ #category : #accessing } -ExoRepo >> repository: aString [ - repository := aString asZnUrl -] - -{ #category : #accessing } -ExoRepo >> repositoryName [ - self repository ifNil: [ ^ self ]. - ^ self repository segments second -] - -{ #category : #accessing } -ExoRepo >> wiki [ - ^ (self local / 'wiki') ensureCreateDirectory. - -] +Class { + #name : #ExoRepo, + #superclass : #Object, + #instVars : [ + 'repository' + ], + #category : #ExoRepo +} + +{ #category : #accessing } +ExoRepo class >> index [ + "I list a set of external recommended repositories from the Grafoscopio community, in installation order." + | reposIndex repositoryAddresses users | + users := #('Offray' 'mutabiT' 'ruidajo' ). + reposIndex := OrderedCollection new. + repositoryAddresses := users do: [:user | + reposIndex add: + ((STONJSON fromString:('https://code.sustrato.red/api/v1/users/', user, '/repos') asZnUrl retrieveContents) collect: [:repo | + (repo at: 'name') -> (repo at: 'html_url')])]. + ^ (reposIndex flatCollect: [:i | i]) asDictionary +] + +{ #category : #accessing } +ExoRepo class >> install: shortNameString [ + | repo exoRepo | + [repo := self index at: shortNameString] + onErrorDo: [:err | UIManager default inform: 'No repository named: ', shortNameString, '. + Please run ExoRepo index + to list know repositories or load your own repository with: + + ExoRepo new + repository: {repositoryAddres}; + load. + + replacing {repositoryAddres} with a Git public repository'.^ {self new. err}]. + exoRepo := self new repository: repo. + (IceRepositoryCreator new + location: exoRepo local; + remote: (IceGitRemote url: repo); + createRepository) register. + ^ exoRepo load +] + +{ #category : #accessing } +ExoRepo class >> userDataFolder [ + Smalltalk os isWindows + ifTrue: [ ^ FileLocator home / 'AppData' / 'Local' ] + ifFalse: [ ^ FileLocator userData ]. +] + +{ #category : #accessing } +ExoRepo >> load [ + "I load the configuration of this package using a external Gitea repository." + + "While more Git independient providers are implemented in Monticello, I will + use Iceberg to download the repository and load it from a local directory" + + | localRepo repoName count | + repoName := self repositoryName. + self local exists + ifFalse: [ (IceRepositoryCreator new + location: self local; + remote: (IceGitRemote url: self repository greaseString ", '.git'"); + createRepository) register ]. + localRepo := 'gitlocal://' , self local fullName. + count := 1. + [ true ] + whileTrue: [ [ ^ Metacello new + repository: localRepo; + baseline: repoName; + onConflictUseLoaded; + onWarningLog; + load ] + on: IceGenericError + do: [ :ex | + Notification + signal: (String with: Character cr) , ex description , (String with: Character cr) + , 'RETRYING ' , count greaseString. + (Delay forSeconds: 2) wait. + ex retry ]. + count := count + 1 ] +] + +{ #category : #accessing } +ExoRepo >> local [ + ^ FileLocator localDirectory / 'iceberg' / (self provider) / self repositoryName +] + +{ #category : #accessing } +ExoRepo >> printOn: aStream [ + super initialize. + self repository ifNotNil: [ + aStream nextPutAll: self repositoryName, ' | ', self repository asString] + ifNil: [ aStream nextPutAll: 'ExoRepo without repository' ]. +] + +{ #category : #accessing } +ExoRepo >> provider [ + self repository ifNil: [ ^ nil ]. + ^ self repository segments first +] + +{ #category : #accessing } +ExoRepo >> repository [ + ^ repository. +] + +{ #category : #accessing } +ExoRepo >> repository: aString [ + repository := aString asZnUrl +] + +{ #category : #accessing } +ExoRepo >> repositoryName [ + self repository ifNil: [ ^ self ]. + ^ self repository segments second +] + +{ #category : #accessing } +ExoRepo >> wiki [ + ^ (self local / 'wiki') ensureCreateDirectory. + +] diff --git a/src/ExoRepo/GitHubAsset.class.st b/src/ExoRepo/GitHubAsset.class.st index 35c74a9..9d4af29 100644 --- a/src/ExoRepo/GitHubAsset.class.st +++ b/src/ExoRepo/GitHubAsset.class.st @@ -1,56 +1,56 @@ -Class { - #name : #GitHubAsset, - #superclass : #Object, - #instVars : [ - 'name', - 'created', - 'updated', - 'size', - 'downloadLink' - ], - #category : #'ExoRepo-External' -} - -{ #category : #accessing } -GitHubAsset class >> fromDictionary: aGitHubAssetDictionary [ - | response | - response := self new - name: (aGitHubAssetDictionary at: 'name'); - size: (aGitHubAssetDictionary at: 'size'); - created: (aGitHubAssetDictionary at: 'created_at'); - updated: (aGitHubAssetDictionary at: 'updated_at'); - downloadLink: (aGitHubAssetDictionary at: 'browser_download_url'). - ^ response -] - -{ #category : #accessing } -GitHubAsset >> created: anObject [ - created := anObject -] - -{ #category : #accessing } -GitHubAsset >> downloadLink: anUrl [ - downloadLink := anUrl -] - -{ #category : #accessing } -GitHubAsset >> name: anObject [ - name := anObject -] - -{ #category : #accessing } -GitHubAsset >> printOn: aStream [ - super initialize. - aStream - nextPutAll: '(', name, ')' -] - -{ #category : #accessing } -GitHubAsset >> size: anObject [ - size := anObject -] - -{ #category : #accessing } -GitHubAsset >> updated: anObject [ - updated := anObject -] +Class { + #name : #GitHubAsset, + #superclass : #Object, + #instVars : [ + 'name', + 'created', + 'updated', + 'size', + 'downloadLink' + ], + #category : #'ExoRepo-External' +} + +{ #category : #accessing } +GitHubAsset class >> fromDictionary: aGitHubAssetDictionary [ + | response | + response := self new + name: (aGitHubAssetDictionary at: 'name'); + size: (aGitHubAssetDictionary at: 'size'); + created: (aGitHubAssetDictionary at: 'created_at'); + updated: (aGitHubAssetDictionary at: 'updated_at'); + downloadLink: (aGitHubAssetDictionary at: 'browser_download_url'). + ^ response +] + +{ #category : #accessing } +GitHubAsset >> created: anObject [ + created := anObject +] + +{ #category : #accessing } +GitHubAsset >> downloadLink: anUrl [ + downloadLink := anUrl +] + +{ #category : #accessing } +GitHubAsset >> name: anObject [ + name := anObject +] + +{ #category : #accessing } +GitHubAsset >> printOn: aStream [ + super initialize. + aStream + nextPutAll: '(', name, ')' +] + +{ #category : #accessing } +GitHubAsset >> size: anObject [ + size := anObject +] + +{ #category : #accessing } +GitHubAsset >> updated: anObject [ + updated := anObject +] diff --git a/src/ExoRepo/Gofer.extension.st b/src/ExoRepo/Gofer.extension.st index eca8073..634eecd 100644 --- a/src/ExoRepo/Gofer.extension.st +++ b/src/ExoRepo/Gofer.extension.st @@ -1,14 +1,14 @@ -Extension { #name : #Gofer } - -{ #category : #'*ExoRepo' } -Gofer >> repositories [ - "Answer the configured monticello repositories." - - | result | - result := OrderedCollection withAll: repositories. - packageCacheRepository ifNotNil: [ result addFirst: packageCacheRepository ]. - ^ result asArray collect: [:each | - (each class = MCHttpRepository and: [each location beginsWith: 'gitea']) - ifTrue: [ MCRepository fromUrl: each location ] ifFalse: [ each ] - ]. -] +Extension { #name : #Gofer } + +{ #category : #'*ExoRepo' } +Gofer >> repositories [ + "Answer the configured monticello repositories." + + | result | + result := OrderedCollection withAll: repositories. + packageCacheRepository ifNotNil: [ result addFirst: packageCacheRepository ]. + ^ result asArray collect: [:each | + (each class = MCHttpRepository and: [each location beginsWith: 'gitea']) + ifTrue: [ MCRepository fromUrl: each location ] ifFalse: [ each ] + ]. +] diff --git a/src/ExoRepo/MCGiteabRepository.class.st b/src/ExoRepo/MCGiteabRepository.class.st index ea36cb7..72e4b20 100644 --- a/src/ExoRepo/MCGiteabRepository.class.st +++ b/src/ExoRepo/MCGiteabRepository.class.st @@ -1,79 +1,79 @@ -Class { - #name : #MCGiteabRepository, - #superclass : #MCGitBasedNetworkRepository, - #category : #ExoRepo -} - -{ #category : #accessing } -MCGiteabRepository class >> basicDescription [ - ^ 'gitea' -] - -{ #category : #'as yet unclassified' } -MCGiteabRepository class >> basicFromUrl: aZnUrl [ - ^ self location: aZnUrl asString -] - -{ #category : #'*ExoRepo' } -MCGiteabRepository class >> createRepositoryFromSpec: aMetacelloRepositorySpec on: anIceMetacelloPharoPlatform [ - ^ anIceMetacelloPharoPlatform createGiteaRepository: aMetacelloRepositorySpec -] - -{ #category : #accessing } -MCGiteabRepository class >> isAvailableFor: type [ - ^ type = 'gitea' -] - -{ #category : #private } -MCGiteabRepository class >> projectZipUrlFor: projectPath versionString: versionString [ - ^ 'https://' , projectPath , '/archive/' , versionString , '.zip' -] - -{ #category : #accessing } -MCGiteabRepository class >> urlSchemes [ - ^ #(gitea) -] - -{ #category : #accessing } -MCGiteabRepository >> branches [ - "IMPORTANT! This requires the installation of the external multiplatform binary dependency - restify at: https://github.com/itzg/restify/. - - This should be installed independiently." - | response | - response := OrderedDictionary new. - OSSUnixSubprocess new - shellCommand: 'restify --class="gt-ellipsis" ', 'https://', self projectPath, '/', self repoPath, '/branches'; - redirectStdout; - runAndWaitOnExitDo: [ :command :outString | - outString ifEmpty: [^ command ]. - (STON fromString: outString) do: [:each | - response at: (each at: 'text') put: (each at: 'href') - ] - ]. - ^ response -] - -{ #category : #accessing } -MCGiteabRepository >> calculateRepositoryDirectory [ - | directory | - - directory := self class - projectDirectoryFrom: self projectPath, '/', self repoPath - version: self projectVersion. - self repoPath isEmpty ifFalse: [ - directory := directory parent ]. - - ^ directory -] - -{ #category : #accessing } -MCGiteabRepository >> location: aString [ -] - -{ #category : #accessing } -MCGiteabRepository >> projectVersion [ - (projectVersion == nil or: [ projectVersion isEmpty ]) - ifTrue: [ projectVersion := self branches keys first ]. - ^ projectVersion -] +Class { + #name : #MCGiteabRepository, + #superclass : #MCGitBasedNetworkRepository, + #category : #ExoRepo +} + +{ #category : #accessing } +MCGiteabRepository class >> basicDescription [ + ^ 'gitea' +] + +{ #category : #'as yet unclassified' } +MCGiteabRepository class >> basicFromUrl: aZnUrl [ + ^ self location: aZnUrl asString +] + +{ #category : #'*ExoRepo' } +MCGiteabRepository class >> createRepositoryFromSpec: aMetacelloRepositorySpec on: anIceMetacelloPharoPlatform [ + ^ anIceMetacelloPharoPlatform createGiteaRepository: aMetacelloRepositorySpec +] + +{ #category : #accessing } +MCGiteabRepository class >> isAvailableFor: type [ + ^ type = 'gitea' +] + +{ #category : #private } +MCGiteabRepository class >> projectZipUrlFor: projectPath versionString: versionString [ + ^ 'https://' , projectPath , '/archive/' , versionString , '.zip' +] + +{ #category : #accessing } +MCGiteabRepository class >> urlSchemes [ + ^ #(gitea) +] + +{ #category : #accessing } +MCGiteabRepository >> branches [ + "IMPORTANT! This requires the installation of the external multiplatform binary dependency + restify at: https://github.com/itzg/restify/. + + This should be installed independiently." + | response | + response := OrderedDictionary new. + OSSUnixSubprocess new + shellCommand: 'restify --class="gt-ellipsis" ', 'https://', self projectPath, '/', self repoPath, '/branches'; + redirectStdout; + runAndWaitOnExitDo: [ :command :outString | + outString ifEmpty: [^ command ]. + (STON fromString: outString) do: [:each | + response at: (each at: 'text') put: (each at: 'href') + ] + ]. + ^ response +] + +{ #category : #accessing } +MCGiteabRepository >> calculateRepositoryDirectory [ + | directory | + + directory := self class + projectDirectoryFrom: self projectPath, '/', self repoPath + version: self projectVersion. + self repoPath isEmpty ifFalse: [ + directory := directory parent ]. + + ^ directory +] + +{ #category : #accessing } +MCGiteabRepository >> location: aString [ +] + +{ #category : #accessing } +MCGiteabRepository >> projectVersion [ + (projectVersion == nil or: [ projectVersion isEmpty ]) + ifTrue: [ projectVersion := self branches keys first ]. + ^ projectVersion +] diff --git a/src/ExoRepo/MCGiteabRepository.extension.st b/src/ExoRepo/MCGiteabRepository.extension.st index bda51c8..ea1e9b6 100644 --- a/src/ExoRepo/MCGiteabRepository.extension.st +++ b/src/ExoRepo/MCGiteabRepository.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #MCGiteabRepository } - -{ #category : #'*ExoRepo' } -MCGiteabRepository class >> createRepositoryFromSpec: aMetacelloRepositorySpec on: anIceMetacelloPharoPlatform [ - ^ anIceMetacelloPharoPlatform createGiteaRepository: aMetacelloRepositorySpec -] +Extension { #name : #MCGiteabRepository } + +{ #category : #'*ExoRepo' } +MCGiteabRepository class >> createRepositoryFromSpec: aMetacelloRepositorySpec on: anIceMetacelloPharoPlatform [ + ^ anIceMetacelloPharoPlatform createGiteaRepository: aMetacelloRepositorySpec +] diff --git a/src/ExoRepo/MetacelloCommonMCSpecLoader.extension.st b/src/ExoRepo/MetacelloCommonMCSpecLoader.extension.st index eebbc9b..ed7302b 100644 --- a/src/ExoRepo/MetacelloCommonMCSpecLoader.extension.st +++ b/src/ExoRepo/MetacelloCommonMCSpecLoader.extension.st @@ -1,15 +1,15 @@ -Extension { #name : #MetacelloCommonMCSpecLoader } - -{ #category : #'*ExoRepo' } -MetacelloCommonMCSpecLoader >> linearLoadPackageSpecs: packageSpecs repositories: repositories [ - - | gofer sanitizedRepos | - gofer := MetacelloGofer new. - sanitizedRepos := OrderedCollection withAll: repositories. - sanitizedRepos := sanitizedRepos collect: [:each | - (each class = MCHttpRepository and: [each location beginsWith: 'gitea']) - ifTrue: [ MCRepository fromUrl: each location ] ifFalse: [ each ] - ]. - sanitizedRepos do: [:repo | gofer repository: repo ]. - packageSpecs do: [:pkg | pkg loadUsing: self gofer: gofer ]. -] +Extension { #name : #MetacelloCommonMCSpecLoader } + +{ #category : #'*ExoRepo' } +MetacelloCommonMCSpecLoader >> linearLoadPackageSpecs: packageSpecs repositories: repositories [ + + | gofer sanitizedRepos | + gofer := MetacelloGofer new. + sanitizedRepos := OrderedCollection withAll: repositories. + sanitizedRepos := sanitizedRepos collect: [:each | + (each class = MCHttpRepository and: [each location beginsWith: 'gitea']) + ifTrue: [ MCRepository fromUrl: each location ] ifFalse: [ each ] + ]. + sanitizedRepos do: [:repo | gofer repository: repo ]. + packageSpecs do: [:pkg | pkg loadUsing: self gofer: gofer ]. +] diff --git a/src/ExoRepo/MetacelloPlatform.extension.st b/src/ExoRepo/MetacelloPlatform.extension.st index 03dada2..008ba3f 100644 --- a/src/ExoRepo/MetacelloPlatform.extension.st +++ b/src/ExoRepo/MetacelloPlatform.extension.st @@ -1,32 +1,32 @@ -Extension { #name : #MetacelloPlatform } - -{ #category : #'*ExoRepo' } -MetacelloPlatform >> createGiteaRepository: aRepositorySpec [ - | cl | - - cl := MCGiteabRepository. - ^ cl location: aRepositorySpec description -] - -{ #category : #'*ExoRepo' } -MetacelloPlatform >> extractTypeFromDescription: description [ - description == nil - ifTrue: [ ^ nil ]. - ((description beginsWith: '/') or: [ description second = $: ]) - ifTrue: [ ^ 'directory' ]. - (description beginsWith: 'dictionary://') - ifTrue: [ ^ 'dictionary' ]. - (description beginsWith: 'filetree://') - ifTrue: [ ^ 'filetree' ]. - (description beginsWith: 'tonel://') - ifTrue: [ ^ 'tonel' ]. - (description beginsWith: 'github://') - ifTrue: [ ^ 'github' ]. - (description beginsWith: 'gitorious://') - ifTrue: [ ^ 'gitorious' ]. - (description beginsWith: 'gitea://') - ifTrue: [ ^ 'gitea' ]. - (description beginsWith: 'bitbucket://') - ifTrue: [ ^ 'bitbucket' ]. - ^ 'http' -] +Extension { #name : #MetacelloPlatform } + +{ #category : #'*ExoRepo' } +MetacelloPlatform >> createGiteaRepository: aRepositorySpec [ + | cl | + + cl := MCGiteabRepository. + ^ cl location: aRepositorySpec description +] + +{ #category : #'*ExoRepo' } +MetacelloPlatform >> extractTypeFromDescription: description [ + description == nil + ifTrue: [ ^ nil ]. + ((description beginsWith: '/') or: [ description second = $: ]) + ifTrue: [ ^ 'directory' ]. + (description beginsWith: 'dictionary://') + ifTrue: [ ^ 'dictionary' ]. + (description beginsWith: 'filetree://') + ifTrue: [ ^ 'filetree' ]. + (description beginsWith: 'tonel://') + ifTrue: [ ^ 'tonel' ]. + (description beginsWith: 'github://') + ifTrue: [ ^ 'github' ]. + (description beginsWith: 'gitorious://') + ifTrue: [ ^ 'gitorious' ]. + (description beginsWith: 'gitea://') + ifTrue: [ ^ 'gitea' ]. + (description beginsWith: 'bitbucket://') + ifTrue: [ ^ 'bitbucket' ]. + ^ 'http' +] diff --git a/src/ExoRepo/MultiPack.class.st b/src/ExoRepo/MultiPack.class.st index 25cef66..a1b5d2e 100644 --- a/src/ExoRepo/MultiPack.class.st +++ b/src/ExoRepo/MultiPack.class.st @@ -1,27 +1,27 @@ -" -I'm a a front-end to use multiple package managers like [Scoop](https://scoop.sh/) on Windows and [Brew](https://brew.sh/) on MacOS and Gnu/Linux -" -Class { - #name : #MultiPack, - #superclass : #Object, - #instVars : [ - 'requirements', - 'recommendations', - 'repository' - ], - #category : #ExoRepo -} - -{ #category : #accessing } -MultiPack >> recommendations: aDictionary [ - recommendations := aDictionary -] - -{ #category : #accessing } -MultiPack >> repository: anObject [ -] - -{ #category : #accessing } -MultiPack >> requirements: aDictionary [ - requirements := aDictionary -] +" +I'm a a front-end to use multiple package managers like [Scoop](https://scoop.sh/) on Windows and [Brew](https://brew.sh/) on MacOS and Gnu/Linux +" +Class { + #name : #MultiPack, + #superclass : #Object, + #instVars : [ + 'requirements', + 'recommendations', + 'repository' + ], + #category : #ExoRepo +} + +{ #category : #accessing } +MultiPack >> recommendations: aDictionary [ + recommendations := aDictionary +] + +{ #category : #accessing } +MultiPack >> repository: anObject [ +] + +{ #category : #accessing } +MultiPack >> requirements: aDictionary [ + requirements := aDictionary +] diff --git a/src/ExoRepo/NanoID.class.st b/src/ExoRepo/NanoID.class.st index 5839c03..2b21cad 100644 --- a/src/ExoRepo/NanoID.class.st +++ b/src/ExoRepo/NanoID.class.st @@ -1,66 +1,66 @@ -" -I'm run an implementation of the [Nano ID](https://github.com/ai/nanoid) tiny, secure URL-friendly unique string ID generator via its [Nim implementation](https://github.com/icyphox/nanoid.nim). - -The Nim script has hard coded: - - * a [base 58 encoding](https://medium.com/concerning-pharo/understanding-base58-encoding-23e673e37ff6) alphabet to avoid similar looking letter and the use of non-alphanumeric characters. - * a 12 characters length output, which gives [a pretty low probability collision](https://zelark.github.io/nano-id-cc/) for the previous alphabet: - ~616 years needed, in order to have a 1% probability of at least one collision at a speed of 1000 IDs per hour. - This is more than enough for our unique IDs applications, mostly in the documentation context, - which consists of hand crafted and/or programmatically produced notes , - for example in data narratives, book(lets) and TiddlyWiki tiddlers of tens or hundreds of notes at most, - unevenly produced between hours, days and/or weeks.. - -The `External` tag is related on its dependency on other programming languages and frameworks, -though the dependency should be loaded by just loading a small binary with no dependencies. -" -Class { - #name : #NanoID, - #superclass : #Object, - #category : #'ExoRepo-External' -} - -{ #category : #accessing } -NanoID class >> binaryFile [ - Smalltalk os isWindows - ifFalse: [ ^ MiniDocs appFolder / self scriptSourceCode basenameWithoutExtension ] - ifTrue: [ ^ ExoRepo userDataFolder / 'NanoId' / 'nanoid' ] -] - -{ #category : #accessing } -NanoID class >> generate [ - self binaryFile exists ifFalse: [ NanoID install]. - Smalltalk os isWindows - ifTrue: [ ^ (LibC resultOfCommand:self binaryFile fullName) copyWithoutAll: (Character lf asString) ]. - OSSUnixSubprocess new - command: self binaryFile fullName; - redirectStdout; - redirectStdout; - runAndWaitOnExitDo: [ :process :outString | ^ outString copyWithoutAll: (Character lf asString) ] -] - -{ #category : #accessing } -NanoID class >> install [ - "For the moment, only Gnu/Linux and Mac are supported. - IMPORTANT: Nimble, Nim's package manager should be installed, as this process doesn't verify its proper installation." - self binaryFile exists ifTrue: [ ^ MiniDocs appFolder ]. - Nimble install: 'nanoid'. - Smalltalk os isWindows - ifTrue: [ ^ LibC resultOfCommand: 'nanoid c ',self scriptSourceCode fullName ]. - OSSUnixSubprocess new - command: 'nim'; - arguments: {'c'. self scriptSourceCode fullName}; - runAndWaitOnExitDo: [ :process :outString | - (self scriptSourceCode parent / (self scriptSourceCode) basenameWithoutExtension) moveToPageTitled: MiniDocs appFolder asFileReference. - ^ MiniDocs appFolder ] -] - -{ #category : #accessing } -NanoID class >> isInstalled [ - ^ self binaryFile exists -] - -{ #category : #accessing } -NanoID class >> scriptSourceCode [ - ^ FileLocator image parent / 'pharo-local/iceberg/Offray/MiniDocs/src/nanoIdGen.nim' -] +" +I'm run an implementation of the [Nano ID](https://github.com/ai/nanoid) tiny, secure URL-friendly unique string ID generator via its [Nim implementation](https://github.com/icyphox/nanoid.nim). + +The Nim script has hard coded: + + * a [base 58 encoding](https://medium.com/concerning-pharo/understanding-base58-encoding-23e673e37ff6) alphabet to avoid similar looking letter and the use of non-alphanumeric characters. + * a 12 characters length output, which gives [a pretty low probability collision](https://zelark.github.io/nano-id-cc/) for the previous alphabet: + ~616 years needed, in order to have a 1% probability of at least one collision at a speed of 1000 IDs per hour. + This is more than enough for our unique IDs applications, mostly in the documentation context, + which consists of hand crafted and/or programmatically produced notes , + for example in data narratives, book(lets) and TiddlyWiki tiddlers of tens or hundreds of notes at most, + unevenly produced between hours, days and/or weeks.. + +The `External` tag is related on its dependency on other programming languages and frameworks, +though the dependency should be loaded by just loading a small binary with no dependencies. +" +Class { + #name : #NanoID, + #superclass : #Object, + #category : #'ExoRepo-External' +} + +{ #category : #accessing } +NanoID class >> binaryFile [ + Smalltalk os isWindows + ifFalse: [ ^ MiniDocs appFolder / self scriptSourceCode basenameWithoutExtension ] + ifTrue: [ ^ ExoRepo userDataFolder / 'NanoId' / 'nanoid' ] +] + +{ #category : #accessing } +NanoID class >> generate [ + self binaryFile exists ifFalse: [ NanoID install]. + Smalltalk os isWindows + ifTrue: [ ^ (LibC resultOfCommand:self binaryFile fullName) copyWithoutAll: (Character lf asString) ]. + OSSUnixSubprocess new + command: self binaryFile fullName; + redirectStdout; + redirectStdout; + runAndWaitOnExitDo: [ :process :outString | ^ outString copyWithoutAll: (Character lf asString) ] +] + +{ #category : #accessing } +NanoID class >> install [ + "For the moment, only Gnu/Linux and Mac are supported. + IMPORTANT: Nimble, Nim's package manager should be installed, as this process doesn't verify its proper installation." + self binaryFile exists ifTrue: [ ^ MiniDocs appFolder ]. + Nimble install: 'nanoid'. + Smalltalk os isWindows + ifTrue: [ ^ LibC resultOfCommand: 'nanoid c ',self scriptSourceCode fullName ]. + OSSUnixSubprocess new + command: 'nim'; + arguments: {'c'. self scriptSourceCode fullName}; + runAndWaitOnExitDo: [ :process :outString | + (self scriptSourceCode parent / (self scriptSourceCode) basenameWithoutExtension) moveToPageTitled: MiniDocs appFolder asFileReference. + ^ MiniDocs appFolder ] +] + +{ #category : #accessing } +NanoID class >> isInstalled [ + ^ self binaryFile exists +] + +{ #category : #accessing } +NanoID class >> scriptSourceCode [ + ^ FileLocator image parent / 'pharo-local/iceberg/Offray/MiniDocs/src/nanoIdGen.nim' +] diff --git a/src/ExoRepo/Nimble.class.st b/src/ExoRepo/Nimble.class.st index 0fe17e8..b661653 100644 --- a/src/ExoRepo/Nimble.class.st +++ b/src/ExoRepo/Nimble.class.st @@ -1,89 +1,89 @@ -" -I'm a helper class modelling the common uses of the Nim's [Nimble package manager](https://github.com/nim-lang/nimble). -This was evolved in the context of the [Grafoscopio](mutabit.com/grafoscopio/en.html) community exploration and prototyping of interactive documentation. -" -Class { - #name : #Nimble, - #superclass : #Object, - #category : #'ExoRepo-External' -} - -{ #category : #accessing } -Nimble class >> detect: packageName [ - ^ self installed - detect: [ :dependency | dependency beginsWith: packageName ] - ifFound: [ ^ true ] - ifNone: [ ^ false ] -] - -{ #category : #accessing } -Nimble class >> install: packageName [ - (self detect: packageName) ifTrue: [ ^ self ]. - self installPackagesList. - Smalltalk os isWindows - ifTrue: [ ^ LibC runCommand: 'nimble install ', packageName ]. - OSSUnixSubprocess new - command: 'nimble'; - arguments: {'install'. - packageName}; - redirectStdout; - redirectStderr; - runAndWaitOnExitDo: [ :process :outString :errString | - process isSuccess - ifTrue: [ Transcript show: 'Command exited correctly with output: ', outString. ] - ifFalse: [ - ^ 'Command exit with error status: ', process exitStatusInterpreter printString, String cr, - 'Stderr contents: ', errString. - ] - ] -] - -{ #category : #accessing } -Nimble class >> installPackagesList [ - - (FileLocator home / '.nimble' / 'packages_official.json') exists - ifTrue: [ ^ self ]. - (Smalltalk os isUnix or: [ Smalltalk os isMacOS ]) - ifTrue: [ - OSSUnixSubprocess new - command: 'nimble'; - arguments: #('refresh'); - redirectStdout; - runAndWaitOnExitDo: [ :process :outString | ^ outString ]. - ]. - Smalltalk os isWindows - ifTrue: [ ^ LibC resultOfCommand: 'nimble refresh' ] -] - -{ #category : #accessing } -Nimble class >> installed [ - - Smalltalk os isWindows - ifTrue: [ | process | - process := GtExternalProcessBuilder new - command: 'nimble.exe'; - args: #('list' '--installed'); - output. - ^ process stdout lines ]. - - OSSUnixSubprocess new - command: 'nimble'; - arguments: #('list' '--installed'); - redirectStdout; - redirectStderr; - runAndWaitOnExitDo: [ :process :outString :errString | - process isSuccess - ifTrue: [ ^ outString lines ]; - ifFalse: [ ^ nil ] - ] -] - -{ #category : #accessing } -Nimble class >> version [ - - OSSUnixSubprocess new - command: 'nimble'; - arguments: #('--version'); - redirectStdout; - runAndWaitOnExitDo: [ :process :outString | ^ outString ] -] +" +I'm a helper class modelling the common uses of the Nim's [Nimble package manager](https://github.com/nim-lang/nimble). +This was evolved in the context of the [Grafoscopio](mutabit.com/grafoscopio/en.html) community exploration and prototyping of interactive documentation. +" +Class { + #name : #Nimble, + #superclass : #Object, + #category : #'ExoRepo-External' +} + +{ #category : #accessing } +Nimble class >> detect: packageName [ + ^ self installed + detect: [ :dependency | dependency beginsWith: packageName ] + ifFound: [ ^ true ] + ifNone: [ ^ false ] +] + +{ #category : #accessing } +Nimble class >> install: packageName [ + (self detect: packageName) ifTrue: [ ^ self ]. + self installPackagesList. + Smalltalk os isWindows + ifTrue: [ ^ LibC runCommand: 'nimble install ', packageName ]. + OSSUnixSubprocess new + command: 'nimble'; + arguments: {'install'. + packageName}; + redirectStdout; + redirectStderr; + runAndWaitOnExitDo: [ :process :outString :errString | + process isSuccess + ifTrue: [ Transcript show: 'Command exited correctly with output: ', outString. ] + ifFalse: [ + ^ 'Command exit with error status: ', process exitStatusInterpreter printString, String cr, + 'Stderr contents: ', errString. + ] + ] +] + +{ #category : #accessing } +Nimble class >> installPackagesList [ + + (FileLocator home / '.nimble' / 'packages_official.json') exists + ifTrue: [ ^ self ]. + (Smalltalk os isUnix or: [ Smalltalk os isMacOS ]) + ifTrue: [ + OSSUnixSubprocess new + command: 'nimble'; + arguments: #('refresh'); + redirectStdout; + runAndWaitOnExitDo: [ :process :outString | ^ outString ]. + ]. + Smalltalk os isWindows + ifTrue: [ ^ LibC resultOfCommand: 'nimble refresh' ] +] + +{ #category : #accessing } +Nimble class >> installed [ + + Smalltalk os isWindows + ifTrue: [ | process | + process := GtExternalProcessBuilder new + command: 'nimble.exe'; + args: #('list' '--installed'); + output. + ^ process stdout lines ]. + + OSSUnixSubprocess new + command: 'nimble'; + arguments: #('list' '--installed'); + redirectStdout; + redirectStderr; + runAndWaitOnExitDo: [ :process :outString :errString | + process isSuccess + ifTrue: [ ^ outString lines ]; + ifFalse: [ ^ nil ] + ] +] + +{ #category : #accessing } +Nimble class >> version [ + + OSSUnixSubprocess new + command: 'nimble'; + arguments: #('--version'); + redirectStdout; + runAndWaitOnExitDo: [ :process :outString | ^ outString ] +] diff --git a/src/ExoRepo/YQ.class.st b/src/ExoRepo/YQ.class.st index ae831fc..a06d174 100644 --- a/src/ExoRepo/YQ.class.st +++ b/src/ExoRepo/YQ.class.st @@ -1,60 +1,56 @@ -" -The `External` tag is related on its dependency on other programming languages and frameworks, -though the dependency should be loaded by just loading a small binary with no dependencies. -" -Class { - #name : #YQ, - #superclass : #Object, - #category : #'ExoRepo-External' -} - -{ #category : #accessing } -YQ class >> binaryDownloadLinkFor: operativeSystem on: processor [ - | binaryName binaryDownloadData | - binaryName := 'yq_', operativeSystem , '_', processor. - binaryDownloadData := ((self lastReleaseData at: 'assets') - select: [:each | (each at: 'name') beginsWith: binaryName ]) first. - ^ binaryDownloadData at: 'browser_download_url' -] - -{ #category : #accessing } -YQ class >> binaryFile [ - "Starting with location on Arch Linux and its derivates. Multidistro and multiOS support should be added." - Smalltalk os isWindows ifFalse: [^ FileLocator root / 'usr/bin/yq']. - ^ FileLocator home / 'scoop/shims/yq.exe' -] - -{ #category : #accessing } -YQ class >> exoPackage [ - ^ ExoPackage new - repository: self repository -] - -{ #category : #accessing } -YQ class >> install [ - ^ ExoPackage new - repository: self repository; - lastReleaseData -] - -{ #category : #accessing } -YQ class >> jsonToYaml: aDictionary [ - | jsonFile | - self binaryFile exists ifFalse: [ YQ install]. - jsonFile := MarkupFile exportAsFileOn: FileLocator temp / 'data.json' containing: aDictionary. - (Smalltalk os isUnix or: [ Smalltalk os isMacOS ]) - ifTrue: [ - OSSUnixSubprocess new - shellCommand: 'cat ', jsonFile fullName,' | yq -y'; - redirectStdout; - runAndWaitOnExitDo: [ :command :outString | - ^ outString - ]]. - Smalltalk os isWindows - ifTrue: [ ^ LibC resultOfCommand: 'yq -p=json ', jsonFile fullName ]. -] - -{ #category : #accessing } -YQ class >> repository [ - ^ 'https://github.com/mikefarah/yq' -] +" +The `External` tag is related on its dependency on other programming languages and frameworks, +though the dependency should be loaded by just loading a small binary with no dependencies. +" +Class { + #name : #YQ, + #superclass : #Object, + #category : #'ExoRepo-External' +} + +{ #category : #accessing } +YQ class >> binaryDownloadLinkFor: operativeSystem on: processor [ + | binaryName binaryDownloadData | + binaryName := 'yq_', operativeSystem , '_', processor. + binaryDownloadData := ((self lastReleaseData at: 'assets') + select: [:each | (each at: 'name') beginsWith: binaryName ]) first. + ^ binaryDownloadData at: 'browser_download_url' +] + +{ #category : #accessing } +YQ class >> binaryFile [ + "Starting with location on Arch Linux and its derivates. Multidistro and multiOS support should be added." + Smalltalk os isWindows ifFalse: [^ FileLocator root / 'usr/bin/yq']. + ^ FileLocator home / 'scoop/shims/yq.exe' +] + +{ #category : #accessing } +YQ class >> exoPackage [ + ^ ExoPackage new + repository: self repository +] + +{ #category : #accessing } +YQ class >> install [ + ^ ExoPackage new + repository: self repository; + lastReleaseData +] + +{ #category : #accessing } +YQ class >> jsonToYaml: aDictionary [ + | jsonFile | + self binaryFile exists ifFalse: [ YQ install]. + jsonFile := MarkupFile exportAsFileOn: FileLocator temp / 'data.json' containing: aDictionary. + Smalltalk os isWindows + ifTrue: [ ^ LibC resultOfCommand: 'yq -p=json ', jsonFile fullName ]. + ^ GtSubprocessWithInMemoryOutput new + shellCommand: 'cat ', jsonFile fullName,' | yq -y'; + runAndWait; + stdout +] + +{ #category : #accessing } +YQ class >> repository [ + ^ 'https://github.com/mikefarah/yq' +] diff --git a/src/ExoRepo/package.st b/src/ExoRepo/package.st index 4b53883..6c76baf 100644 --- a/src/ExoRepo/package.st +++ b/src/ExoRepo/package.st @@ -1 +1 @@ -Package { #name : #ExoRepo } +Package { #name : #ExoRepo }