Compare commits

..

No commits in common. "master" and "multiplatfrom" have entirely different histories.

4 changed files with 51 additions and 357 deletions

View File

@ -1,13 +1,4 @@
# Fossil # Fossil
This repostory contains a set of utilities for using [Fossil SCM](https://fossil-scm.org/) within This repostory contains a set of utilities for using [Fossil SCM](https://fossil-scm.org/) within
[Pharo](https://pharo.org/)/[Grafoscopio](https://mutabit.com/grafoscopio/en.html) . [Pharo](https://pharo.org/)/[Grafoscopio](https://mutabit.com/grafoscopio/en.html).
To install this repository, *first* install [ExoRepo](https://code.sustrato.red/Offray/ExoRepo) and then run:
```
ExoRepo new
repository: 'https://code.sustrato.red/Offray/Fossil';
load.
```

View File

@ -15,17 +15,17 @@ BaselineOfFossil >> baseline: spec [
for: #common for: #common
do: [ do: [
"Dependencies" "Dependencies"
"As NeoJSON is included in Pharo and GT, it is not declared as an extra dependency, so it uses the one already defined on the system" spec
spec baseline: 'NeoJSON' with: [ spec repository: 'github://svenvc/NeoJSON/repository' ];
baseline: 'OSSubprocess' with: [ spec repository: 'github://pharo-contributions/OSSubprocess/repository']"; baseline: 'OSSubprocess' with: [ spec repository: 'github://pharo-contributions/OSSubprocess:master/repository'];
baseline: 'ProcessWrapper' with: [ spec repository: 'github://hernanmd/ProcessWrapper/repository' ]". baseline: 'ProcessWrapper' with: [ spec repository: 'github://hernanmd/ProcessWrapper/repository' ].
"Packages" "Packages"
spec package: 'Fossil' with: [ spec requires: #('NeoJSON') ]. spec package: 'Fossil' with: [ spec requires: #('NeoJSON') ].
spec for: #(#'MacOS' #'Unix') do: [ spec for: #(#'MacOS' #'Unix') do: [
spec package: 'Fossil' with: [ spec requires: #('OSSubprocess') ] ]. spec package: 'Fossil' with: [ spec requires: #('OSSubprocess') ] ].
"spec for: #'Windows' do: [ spec for: #'Windows' do: [
spec package: 'Fossil' with: [ spec requires: #('ProcessWrapper') ] ]". spec package: 'Fossil' with: [ spec requires: #('OSSubprocess') ] ].
] ]

View File

@ -1,16 +0,0 @@
Class {
#name : #Fossil,
#superclass : #Object,
#category : #Fossil
}
{ #category : #accessing }
Fossil class >> all: subcommand [
Smalltalk os isWindows ifTrue: [ ^ self shouldBeImplemented ].
^ GtSubprocessWithInMemoryOutput new
shellCommand: 'fossil all ', subcommand;
runAndWait;
stdout
]

View File

@ -13,8 +13,7 @@ Class {
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'local', 'local',
'remote', 'remote'
'repository'
], ],
#classInstVars : [ #classInstVars : [
'executable' 'executable'
@ -33,26 +32,15 @@ FossilRepo class >> executable: aPathString [
executable := aPathString executable := aPathString
] ]
{ #category : #'instance creation' }
FossilRepo class >> local: aFilePath repository: aFossilFilePath [
| repo |
repo := self new
local: aFilePath;
repository: aFossilFilePath.
repo remote = 'off'
ifTrue: [ repo remote: nil ]
ifFalse: [ repo remote: repo remote ].
^ repo
]
{ #category : #accessing } { #category : #accessing }
FossilRepo class >> locateExecutable [ FossilRepo class >> locateExecutable [
Smalltalk os isWindows ifTrue: [ ^ MiniDocs shouldBeImplemented ]. Smalltalk os isWindows ifTrue: [ ^ self ].
^ (GtSubprocessWithInMemoryOutput new OSSUnixSubprocess new
shellCommand: 'which fossil'; command: 'which';
runAndWait; arguments: #('fossil') ;
stdout) lines first redirectStdout;
runAndWaitOnExitDo: [ :process :outString |
^ outString allButLast ]
] ]
{ #category : #operation } { #category : #operation }
@ -62,25 +50,12 @@ FossilRepo >> add: fileRelativePath [
OSSUnixSubprocess new OSSUnixSubprocess new
command: self class locateExecutable; command: self class locateExecutable;
workingDirectory: self localRoot; workingDirectory: self localFolderName;
arguments: { 'add' . fileRelativePath }; arguments: { 'add' . fileRelativePath };
redirectStdout; redirectStdout;
runAndWaitOnExitDo: [ :process :outString | ^ outString ] runAndWaitOnExitDo: [ :process :outString | ^ outString ]
] ]
{ #category : #accessing }
FossilRepo >> addFiles: aCollection [
aCollection do: [ :each | self add: each ].
]
{ #category : #accessing }
FossilRepo >> addUnversioned: aFileRelativePathFullname [
^ self fossilUv: 'add' and: aFileRelativePathFullname
]
{ #category : #authentication } { #category : #authentication }
FossilRepo >> authTokenFor: anUserName withPassword: passwordString [ FossilRepo >> authTokenFor: anUserName withPassword: passwordString [
^ ((self loginAs: anUserName withPassword: passwordString) at: 'payload') at: 'authToken' ^ ((self loginAs: anUserName withPassword: passwordString) at: 'payload') at: 'authToken'
@ -110,28 +85,6 @@ FossilRepo >> checkinsFor: relativeFilePath [
^ payload at: 'checkins' ^ payload at: 'checkins'
] ]
{ #category : #accessing }
FossilRepo >> checkoutDateAndTime [
| date time splitedCheckout |
splitedCheckout := (self status at: 'checkout') splitOn: ' '.
date := splitedCheckout at: 2.
time := splitedCheckout at: 3.
^ (date, time) asZTimestamp
]
{ #category : #accessing }
FossilRepo >> command: aCommandArgument [
OSSUnixSubprocess new
command: 'fossil';
arguments: { aCommandArgument };
workingDirectory: self localRoot;
redirectStdout;
redirectStderr;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
]
{ #category : #operation } { #category : #operation }
FossilRepo >> commit: message [ FossilRepo >> commit: message [
"I add a file to the working Fossil repository, given that both, the file and the repositor, "I add a file to the working Fossil repository, given that both, the file and the repositor,
@ -140,7 +93,7 @@ FossilRepo >> commit: message [
OSSUnixSubprocess new OSSUnixSubprocess new
command: self class locateExecutable; command: self class locateExecutable;
arguments: { 'commit' . '--no-warnings' . '-m' . message }; arguments: { 'commit' . '--no-warnings' . '-m' . message };
workingDirectory: self localRoot; workingDirectory: self localFolderName;
redirectStdout; redirectStdout;
runAndWaitOnExitDo: [ :process :outString | ^ outString ] runAndWaitOnExitDo: [ :process :outString | ^ outString ]
] ]
@ -161,7 +114,7 @@ FossilRepo >> commit: message withEnabledWarnings: aBoolean [
warningCommand. warningCommand.
'-m'. '-m'.
message}; message};
workingDirectory: self localRoot; workingDirectory: self localFolderName;
redirectStdout; redirectStdout;
runAndWaitOnExitDo: [ :process :outString | ^ outString ] runAndWaitOnExitDo: [ :process :outString | ^ outString ]
] ]
@ -171,61 +124,21 @@ FossilRepo >> createPage: pageName [
^ NeoJSONReader fromString: (self jsonWikiDataFor: 'create/', pageName) ^ NeoJSONReader fromString: (self jsonWikiDataFor: 'create/', pageName)
] ]
{ #category : #accessing } { #category : #operation }
FossilRepo >> delete: fileRelativePath [ FossilRepo >> downloadZippedInto: aFolder [
"I delete a file to the working Fossil repository, given that both, the file and the repositor, | zippedFileName zippedFile |
share the same root directory/folder." self remote ifNil: [ ^ self ].
zippedFileName := self remoteName , '.zip'.
zippedFile := FileLocator temp / zippedFileName.
GrafoscopioUtils
downloadingFrom: self remote / 'zip'
withMessage: 'Downloading zipped repository...'
into: aFolder.
aFolder / 'zip' renameTo: zippedFileName.
^ zippedFile
OSSUnixSubprocess new
command: self class locateExecutable;
workingDirectory: self localRoot;
arguments: { 'delete' . fileRelativePath };
redirectStdout;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
]
{ #category : #accessing }
FossilRepo >> diff [
^ self command: 'diff'
]
{ #category : #accessing }
FossilRepo >> exportHTMLUnversioned [
| htmlFileReferenceFullName |
htmlFileReferenceFullName := (self listUnversioned)
select: [ :each | each endsWith: '.html' ].
htmlFileReferenceFullName do: [ :each | self exportUnversioned: each ].
^ htmlFileReferenceFullName
]
{ #category : #accessing }
FossilRepo >> exportSTONUnversioned [
| stonFileReferenceFullName |
stonFileReferenceFullName := (self listUnversioned)
select: [ :each | each endsWith: '.ston' ].
stonFileReferenceFullName do: [ :each | self exportUnversioned: each ].
^ stonFileReferenceFullName
]
{ #category : #accessing }
FossilRepo >> exportUnversioned: fileReferenceFullName [
OSSUnixSubprocess new
command: 'fossil';
arguments: { 'uv' . 'export' . fileReferenceFullName . fileReferenceFullName };
workingDirectory: self localRoot;
redirectStdout;
redirectStderr;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
]
{ #category : #accessing }
FossilRepo >> extra [
^ self command: 'extra'
] ]
{ #category : #wiki } { #category : #wiki }
@ -233,25 +146,6 @@ FossilRepo >> fetchPage: pageName [
^ NeoJSONReader fromString: (self jsonWikiDataFor: 'get/', pageName) ^ NeoJSONReader fromString: (self jsonWikiDataFor: 'get/', pageName)
] ]
{ #category : #accessing }
FossilRepo >> firstCheckinFor: testRepoFile [
"Checkins are in reverse order"
^ (self checkinsFor: testRepoFile) last
]
{ #category : #accessing }
FossilRepo >> fossilUv: anArgument and: aSecondArgument [
OSSUnixSubprocess new
command: 'fossil';
arguments: { 'uv' . anArgument . aSecondArgument };
workingDirectory: self localRoot;
redirectStdout;
redirectStderr;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
FossilRepo >> getFileContentsFor: anEmbeddedDocUrl [ FossilRepo >> getFileContentsFor: anEmbeddedDocUrl [
"Given the web page contents for a file, hosted in Fossil, I detect all the standard "Given the web page contents for a file, hosted in Fossil, I detect all the standard
@ -295,18 +189,11 @@ FossilRepo >> init: absolutePathString [
OSSUnixSubprocess new OSSUnixSubprocess new
command: self class locateExecutable; command: self class locateExecutable;
arguments: { 'init' . absolutePathString }; arguments: { 'init' . absolutePathString };
workingDirectory: self localRoot; workingDirectory: self localFolderName;
redirectStdout; redirectStdout;
runAndWaitOnExitDo: [ :process :outString | ^ outString ] runAndWaitOnExitDo: [ :process :outString | ^ outString ]
] ]
{ #category : #testing }
FossilRepo >> isOpen [
self status ifEmpty: [ ^ false ].
^ true
]
{ #category : #utilities } { #category : #utilities }
FossilRepo >> isUnversioned: aFileNameWithRelativePath [ FossilRepo >> isUnversioned: aFileNameWithRelativePath [
@ -322,7 +209,7 @@ FossilRepo >> jsonDataFor: anUrlSegment [
{ #category : #querying } { #category : #querying }
FossilRepo >> jsonStringFor: aFileName [ FossilRepo >> jsonStringFor: aFileName [
| baseUrl queryForJSONData | | baseUrl queryForJSONData |
baseUrl := self remote copy addPathSegments: #('json' 'finfo'). baseUrl := self remote addPathSegments: #('json' 'finfo').
queryForJSONData := baseUrl queryAt: 'name' put: aFileName. queryForJSONData := baseUrl queryAt: 'name' put: aFileName.
^ (ZnEasy get: queryForJSONData) contents. ^ (ZnEasy get: queryForJSONData) contents.
] ]
@ -352,41 +239,6 @@ FossilRepo >> lastVersionPath: aFileNameWithRelativePath [
ifFalse: [ ^ '/doc/tip/', aFileNameWithRelativePath ] ifFalse: [ ^ '/doc/tip/', aFileNameWithRelativePath ]
] ]
{ #category : #accessing }
FossilRepo >> list [
^ (self command: 'ls') lines collect: [:line | line accentedCharactersCorrection ].
]
{ #category : #accessing }
FossilRepo >> listSeparatingMardeepFiles [
| lines output markdeepFiles otherFiles |
output := OrderedDictionary new.
lines := (self command: 'ls') lines.
markdeepFiles := lines select: [ :line | line endsWith: '.md.html' ].
otherFiles := lines reject: [ :line | line endsWith: '.md.html'].
output
at: 'markdeep files'
put: {'file reference' -> markdeepFiles .
'url' -> (markdeepFiles collect: [ :ref |
('https://', ((self remote splitOn: '@' )
at: 2), '/doc/trunk/', ref)asUrl ])
} asDictionary.
output
at: 'other files'
put: otherFiles.
^ output
]
{ #category : #accessing }
FossilRepo >> listUnversioned [
^ (self fossilUv: 'ls' and: '') lines
]
{ #category : #accessing } { #category : #accessing }
FossilRepo >> local [ FossilRepo >> local [
^ local ^ local
@ -397,11 +249,9 @@ FossilRepo >> local: aLocalFilePath [
local := aLocalFilePath local := aLocalFilePath
] ]
{ #category : #accessing } { #category : #'as yet unclassified' }
FossilRepo >> localRoot [ FossilRepo >> localFolderName [
^ self local parent fullName
local ifNotNil: [ ^ self local fullName ].
^ self status at: 'local-root:'
] ]
{ #category : #authentication } { #category : #authentication }
@ -422,36 +272,11 @@ FossilRepo >> loginUrlWithName: aUser andPassword: passwd [
queryAt: 'password' put: passwd. queryAt: 'password' put: passwd.
] ]
{ #category : #accessing }
FossilRepo >> open [
OSSUnixSubprocess new
command: 'fossil';
arguments: { 'open' . self repository. '-f' };
workingDirectory: self localRoot;
redirectStdout;
redirectStderr;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
]
{ #category : #accessing }
FossilRepo >> openAndUpdate [
^ self open; update
]
{ #category : #wiki } { #category : #wiki }
FossilRepo >> pageList [ FossilRepo >> pageList [
^ NeoJSONReader fromString: (self jsonWikiDataFor: 'list') ^ NeoJSONReader fromString: (self jsonWikiDataFor: 'list')
] ]
{ #category : #accessing }
FossilRepo >> printOn: aStream [
super initialize.
aStream
nextPutAll: 'Repository: ', self remote asString
]
{ #category : #authentication } { #category : #authentication }
FossilRepo >> rawCapabilities [ FossilRepo >> rawCapabilities [
^ NeoJSONReader fromString: (self jsonDataFor: 'cap') ^ NeoJSONReader fromString: (self jsonDataFor: 'cap')
@ -459,79 +284,18 @@ FossilRepo >> rawCapabilities [
{ #category : #accessing } { #category : #accessing }
FossilRepo >> remote [ FossilRepo >> remote [
^ remote
^ remote
"TO DEBUG: Capture the context of this assignation without damaging the generaly of the accessor for other cases."
":= (self command: 'remote') copyWithout: Character lf"
] ]
{ #category : #accessing } { #category : #accessing }
FossilRepo >> remote: anUrlString [ FossilRepo >> remote: anUrlString [
remote := anUrlString asUrl
anUrlString
ifNil: [ remote := anUrlString ]
ifNotNil: [ remote := anUrlString asUrl ]
] ]
{ #category : #accessing } { #category : #utilities }
FossilRepo >> renameFrom: currentName to: newName [ FossilRepo >> remoteName [
self remote ifNil: [ ^ self ].
^ self renameFrom: currentName to: newName inSubfolder: self localRoot ^ self remote asUrl segments last
]
{ #category : #accessing }
FossilRepo >> renameFrom: currentName to: newName inSubfolder: aFolder [
OSSUnixSubprocess new
command: 'fossil';
arguments: {
'rename'.
currentName basename.
newName basename};
workingDirectory: aFolder fullName;
redirectStdout;
redirectStderr;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
]
{ #category : #accessing }
FossilRepo >> repository [
repository ifNotNil: [ ^ repository ].
self isOpen ifFalse: [ ^ nil ].
^ repository := self status at: 'repository'.
]
{ #category : #accessing }
FossilRepo >> repository: aFossilRepoFile [
repository := aFossilRepoFile "fullName"
]
{ #category : #operation }
FossilRepo >> revert: aRelativeFilePath [
"I add a file to the working Fossil repository, given that both, the file and the repositor,
share the same root directory/folder."
OSSUnixSubprocess new
command: self class locateExecutable;
arguments: { 'revert' . aRelativeFilePath };
workingDirectory: self localRoot;
redirectStdout;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
]
{ #category : #accessing }
FossilRepo >> revertRemoteUnversioned [
OSSUnixSubprocess new
command: 'fossil';
arguments: { 'uv' . 'revert' };
workingDirectory: self localRoot;
redirectStdout;
redirectStderr;
runAndWaitOnExitDo: [ :process :outString | ^ outString ]
] ]
{ #category : #utilities } { #category : #utilities }
@ -544,60 +308,15 @@ FossilRepo >> sanitize: aFileNameWithRelativePath [
ifTrue: [ ^ (aFileNameWithRelativePath copyFrom: 4 to: aFileNameWithRelativePath size) ] ifTrue: [ ^ (aFileNameWithRelativePath copyFrom: 4 to: aFileNameWithRelativePath size) ]
] ]
{ #category : #accessing } { #category : #'as yet unclassified' }
FossilRepo >> status [ FossilRepo >> status [
| status output missing edited added | OSSUnixSubprocess new
status := self command: 'status'. command: '/usr/bin/fossil';
output := OrderedDictionary new. arguments: #('status');
workingDirectory: self localFolderName;
status linesDo: [ :line | | k v temp commitLog | redirectStdout;
commitLog := OrderedCollection new. redirectStderr;
temp := line splitOn: ': '. runAndWaitOnExitDo: [ :process :outString | ^ outString ]
temp size = 2
ifTrue: [
k := temp first.
v := temp second trimmed.
output at: k put: v
]
ifFalse: [ commitLog add: line ].
output at: 'commitLog' put: commitLog
].
edited := status lines select: [ :line | line beginsWith: 'EDITED' ].
output
at: 'edited'
put: (edited collect:
[ :line | (line withoutPrefix: 'EDITED') trimmed accentedCharactersCorrection ]).
added := status lines select: [ :line | line beginsWith: 'ADDED' ].
output
at: 'added'
put: (added collect:
[ :line | (line withoutPrefix: 'ADDED') trimmed accentedCharactersCorrection ]).
missing := status lines select: [ :line | line beginsWith: 'MISSING' ].
output
at: 'missing'
put: (missing collect:
[ :line | (line withoutPrefix: 'MISSING') trimmed accentedCharactersCorrection ]).
^ output
]
{ #category : #accessing }
FossilRepo >> syncUnversioned [
^ self fossilUv: 'sync' and: '-v'
]
{ #category : #accessing }
FossilRepo >> update [
^ self command: 'update'
]
{ #category : #accessing }
FossilRepo >> uuidFor: relativeFilePath [
^ (self firstCheckinFor: relativeFilePath) at: 'uuid'
] ]
{ #category : #authentication } { #category : #authentication }