theseion / libgit2-pharo-bindings Goto Github PK
View Code? Open in Web Editor NEWlibgit2 bindings for Pharo
Home Page: http://theseion.github.io/libgit2-pharo-bindings
libgit2 bindings for Pharo
Home Page: http://theseion.github.io/libgit2-pharo-bindings
@npasserini Do you want to create a pull request? Then I can merge everything into this repo (I've just merged @jvdsandt's changes back and removed the meta data).
In Pharo 40583, the load raises an error. I don't know of NB, but I find suspicious that in NBFFICallout>>generateCall:module:
, the argument moduleNameOrHandle
is 0.
Stack trace:
NativeBoostMac32(Object)>>error:
NativeBoostMac32(NativeBoostLinux32)>>getGlobalSymbolPointer:
NativeBoostMac32(NativeBoostLinux32)>>loadSymbol:fromModule:
NativeBoost class>>loadSymbol:fromModule:
Metaclass(Object)>>nbGetSymbolAddress:module:
NBFFICallout>>generateCall:module:
[ :gen |
gen
callType: conv;
sender: context;
parseOptions: options;
generateCall: functionSignature module: moduleNameOrHandle ] in NBFFICalloutAPI>>function:module: in Block: [ :gen | ...
[ bytes := aBlock value: (self newForMethod: method) ] in NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry: in Block: [ bytes := aBlock value: (self newForMethod: metho...etc...
BlockClosure>>on:do:
NBRecursionDetect class>>in:during:
NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry:
NBFFICallout class(NBNativeCodeGen class)>>handleFailureIn:nativeCode:
NBFFICalloutAPI>>function:module:
[
LGitFunctionReturn
methodSelector: sender method selector
value:
((self nbCalloutIn: sender)
cdecl;
options: options;
function: fnSpec module: LGitGlobal libraryNameOrHandle) ] in LGitGlobal class>>call:options: in Block: [ ...
BlockClosure>>cull:
Context(ProtoObject)>>ifNotNil:
LGitGlobal class>>runSequence:
LGitGlobal class>>call:options:
LGitGlobal class>>libgit2_init
LGitGlobal class>>initializeLibGit2
[
self initializeLibGit2.
aBlock value ] in [
[
self initializeLibGit2.
aBlock value ]
ensure: [ self shutdownLibGit2 ] ] in LGitGlobal class>>runSequence: in Block: [ ...
BlockClosure>>ensure:
[
[
self initializeLibGit2.
aBlock value ]
ensure: [ self shutdownLibGit2 ] ] in LGitGlobal class>>runSequence: in Block: [ ...
[
p psValueAt: index put: anObject.
aBlock value ] in LGitActionSequence(DynamicVariable)>>value:during: in Block: [ ...
BlockClosure>>ensure:
LGitActionSequence(DynamicVariable)>>value:during:
LGitActionSequence class(DynamicVariable class)>>value:during:
LGitGlobal class>>runSequence:
MCGitRepository>>createCloneRepository
MCGitRepository>>ensureDirectory
The objects currently used in #packHead are not subclasses of LGitExternalObject and thus will not be garbage collected.
LGitWriteBackValue
for instance has no fields after load. Need to check initialization after loading.
Currently every function lookup is performed by passing the module name of the library first. Rather pass the handle after first use.
I have these one in my todo but I still didn't manage to commit to this repo:
typo in LGitTree>>#isEmtpy
missing #new in LGitCommit:
time
| time offset |
time := self commit_time: self.
offset := self commit_time_offset: self.
^ LGitTime
time: time;
offset: offset;
yourself
Gofer it
smalltalkhubUser: 'FileSystemGitDev' project: 'LibGit2';
configurationOf: 'LibGit';
loadBleedingEdge
in latest Pharo 4 signals error:
[ LGitNoReturnCodeHandlerDefined signal ] in LGitCallReturnHandler class>>for: in Block: [ LGitNoReturnCodeHandlerDefined signal ]
OrderedCollection(Collection)>>detect:ifFound:ifNone:
OrderedCollection(Collection)>>detect:ifNone:
LGitCallReturnHandler class>>for:
[ :assoc | assoc value -> (LGitCallReturnHandler for: assoc value) ] in LGitReturnCodeEnum class>>setUpHandlers in Block: [ :assoc | assoc value -> (LGitCallReturnHandler f...etc...
Array(SequenceableCollection)>>collect:
LGitReturnCodeEnum class>>setUpHandlers
LGitReturnCodeEnum class>>handlers
LGitReturnCodeEnum>>handlers
LGitReturnCodeEnum>>handleLGitReturnCode
LGitRepository(LGitExternalObject)>>withReturnHandlerDo:
LGitRepository>>defaultCloneOptions
[
self
clone: self
url: aString
local_path: self repositoryReference pathString
options: self defaultCloneOptions ] in LGitRepository>>clone: in Block: [ ...
LGitRepository(LGitExternalObject)>>withReturnHandlerDo:
LGitRepository>>clone:
[
| repo |
repo := LGitRepository on: self directory asFileReference.
repo
clone: url;
checkout: 'master'. "make sure 'origin' is set to the original url, not to the https one if we used that"
(LGitRemote of: repo named: 'origin')
load;
setUrl: self repoUrl;
save ] in MCGitRepository>>createCloneRepository in Block: [ ...
[
threads threads_init.
self value ] in BlockClosure>>asLibGitActionSequence in Block: [ ...
BlockClosure>>ensure:
BlockClosure>>asLibGitActionSequence
MCGitRepository>>createCloneRepository
MCGitRepository>>ensureDirectory
ConfigurationOfLibGit>>changeRepositoryType
[ self project configuration perform: selector ] in MetacelloMCVersionSpec(MetacelloSpec)>>doItBlock: in Block: [ self project configuration perform: selector ]
BlockClosure>>valueWithPossibleArgs:
[ block valueWithPossibleArgs: (Array with: aPostloadDirective loader with: aPostloadDirective spec) ] in MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadPostloadDirective: in Block: [ block valueWithPossibleArgs: (Array with: aPostl...etc...
MetacelloPostLoadDirective(MetacelloPrePostLoadDirective)>>evaluateSupplyingAnswers:
MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadPostloadDirective:
MetacelloPostLoadDirective>>loadUsing:gofer:
[ :directive | directive loadUsing: aLoaderDirective gofer: aGofer ] in MetacelloLinearLoadDirective(MetacelloVersionLoadDirective)>>loadLinearLoadDirective:gofer: in Block: [ :directive | directive loadUsing: aLoaderDirecti...etc...
OrderedCollection>>do:
There was something on the mailing list about making the VM handle OS signals. If we can intercept SIGABRT we'd be a lot safer with libgit2 and could stop with an exception instead of having to let the VM crash (also makes debugging a bit easier).
See LGitIndex>>updateAll and #addAll and #removeAll. Need to free the address of the struct and not use the provided free function of the struct.
Otherwise we'll see error messages on stdout.
Problem: this only frees the struct but does not tear down internals.
A while ago I sent this mail to the list (see https://pharo.fogbugz.com/f/cases/14479/Enable-nil-to-NULL-coercion-for-NBExternalObjectType):
Once again I’m struggling with NativeBoost. I’m trying to use optCoerceNilToNull with this function:
^self call: #(LGitReturnCodeEnum git_commit_create(
LGitId * theCommitId,
LGitRepository repo,
String update_ref,
LGitSignature * theAuthor,
LGitSignature * theCommitter,
String message_encoding,
String theMessage,
LGitTree theTree,
int parent_count,
LGitCommit * parentsPointer)) options: #( optCoerceNilToNull )The last argument can be NULL, per documentation, (no parents).
LGitCommit is a subclass of NBExternalObject and apparently NBExternalObjctType>>pushAsPointer: does not use the optCoerceNilToNull option (the super implementation in NBExternalType>>pushAsPointer: however does). The upshot of course is that the call fails with “an instance of LGitCommit expected”.My questions:
- The documentation says:
"#optCoerceNilToNull"
"passing nil as a pointer-type argument, converts it to C NULL “but apparently this doesn’t apply to every pointer type. Should the documentation be updated?
- Why does NBExternlObjectType not use optCoerceNilToNull? I don’t want to use tricks to pass null if I don’t have to.
- Related: there are instances where even non-pointer arguments are allowed to be NULL. Why does optCoerceNilToNull only work for pointer types?
Answer:
Yay! :) I have zero assembly skills… I’ve tried the following but then get an “undefined label done18” error:
if coerceNilToNull is set and the argument is indeed nil, you want to jump over all other operations on this argument (see below).
(and if coerceNilToNull is set, and the argument is not nil, you should still verify the class of the oop, this is missing
in your code!)NBExternalObject>>pushAsPointer: gen
"push a pointer to handle value"
| asm proxy oop notNil done |
proxy := gen proxy.
asm := gen asm.
<<<<<<<<<<<<<< new
done := asm uniqueLabelName: 'done’.
->>>>>>>>>>>>>>> new
oop := gen reserveTemp.
loader emitLoad: gen to: oop.
<<<<<<<<<<<<<< new
"handle nils, if we care"
gen optCoerceNilToNull
ifTrue: [
notNil := asm uniqueLabelName: 'notNil'.
proxy nilObject.
asm cmp: asm EAX with: oop;
jne: notNil;
xor: asm EAX with: asm EAX;
jmp: done;
label: notNil ]
ifFalse: [
"we can skip class verification, if loader loads receiver, since nothing to fear there"
loader isReceiver ifFalse: [
self verifyClassOf: oop is: objectClass generator: gen.
] ].
->>>>>>>>>>>>>>> new
proxy fetchPointer: (self handleIvarIndex) ofObject: oop. "handle ivar"
proxy varBytesFirstFieldOf: asm EAX. "handle value ptr"
"done label here:"
asm label: done.
The information that I need at the moment is for each commit from the history:
So, I would need the information as objects. Maybe something like this: Commit ->* DiffSegment (which holds, oldInterval, newInterval, newText).
I'm cleaning the lint issues for #initialize methods for the Pharo standard image
There will also be a release test to assure the quality status, see pharo-project/pharo#12074
For ibgit2-pharo-bindings/ there is a single lint issue to be fixed in LGitDiffHunk class>>#initialize
Can't load libgit2 on Linux yet because the library names on Linux are different.
There's a huge memory leak somewhere. Find it, fix it.
To reproduce:
git clone -b 3.0 [email protected]:pharo-project/pharo-core.git
cd pharo-core
git fetch --tags
| directory repository commit |
directory := './pharo-core' asFileReference.
repository := (LGitRepository on: directory) open; yourself.
commit := (repository lookup: 'refs/tags/30007') object.
"crashing:"
commit commit_time: commit.
commit_time: commit
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^self call: #(LGitTime git_commit_time(self)) options: #( )
My image was crashing when executing LGtBlob>>contents of a blob with binary content. (I checked that it answers true to LGtBlob>>isBinary)
My blob had this content:
'SUnit tests for fuel serializations, here signatures��$$'
Where $ is the ascii character 5 (i.e. insert).
Weird. I tried modifying the current #testBinary with my particular string and there is no problem. But in my scenario was 100% reproducible.
add a guard to repository access to prevent the image from crashing when the repository hasn't been opened yet.
yrupe needs to gc to prevent too much disk memory allocation. Implement compression of the loose objects.
I don't have any mechanism yet to free structs.
Hello,
At the PharoDays 2016 conference I learned that the new UnifiedFFI code of Pharo 5 is feature complete and pretty stable.
Are there already any plans to convert LibGit to Pharo 5? Can I help with the effort?
Jan.
See my comment in this commit:
libgit2/libgit2@217c029
e.g. LGitSignature
should have selectors like #prim_email
map to the field #email
, and a selector #email
that converts the external content from #prim_email
:
LGitSignature>>email
^ self prim_email readString
Got "An instance of LGitTree expected".
Basically, this code fails:
builder := LGitTreeBuilder of: repo.
builder createNew.
The error is already reproduced in:
LGitTreeBuilderTest>>#testAddEntry
@theseion if you were using a BaselineOf I think that things would be much cleaner ... there's not much advantage to using a ConfigurationOf for a GitHub-based project ...
I could give you a pull request with a BaselineOf, based on your current CofigurationOf if you'd like ...
NativeBoost can't load the libgit2 library on Linux. Should check if the library is being built / linked correctly.
libgit2 hold on to the file handle for the pack file. This becomes a problem on Windows, where a file can only be (completely) deleted after all handles have been closed.
This may be a problem with objects that aren't properly freed. However, the pack file seems to be the only file with this problem, so the error might actually lie with libgit2 itself.
See:
Need to fix up the Metacello patch to clone the repository after load
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.