Technical Articles
Data exchange with your github repository using abapGit
For a project idea I wanted to send plain text files to my github repository. With the help of Lars Hvam I managed to write a little program to download, change and upload a text file to github, namely an asciidoc file (extension .adoc).
Lars told me about an old report of him to transfer code inspector variants that needed some adaptions.
Report
In the first step I build a report where I could upload a raw file into my test repository. As I wanted to know a bit more about the abapgit mechanisms I build a small application to load single files and update or even create them.
Repository key
The abapGit repositories have a sequential numbering that can only be seen in table ZABAPGIT. But the information about the underlying repository is serialized and therefore hard to identify.
For proper usage I created two search helps:
- Search help for abapGit repositories
- Search help for files of selected repository
Selecting repositories
The repository list can be retrieved by one simple line of code:
DATA(lt_list) = zcl_abapgit_persist_factory=>get_repo( )->list( ).
Some useful data will be transferred to the search help result via a search help exit function module:
The files structure is divided in a main part and an embedded structure with local settings.
I first transferred the fields of the directory to the result list using function module F4UT_PARAMETER_RESULTS_PUT. Unfortunately this didn’t work for fields of the embedded structure local_settings. So I transferred the data into a local table that fits the fields of the search help and directly copied them.
Selecting a file from the repository
Once you know the internal key of the repository you can load the files of that repository:
DATA(lo_online) = CAST zcl_abapgit_repo_online(
zcl_abapgit_repo_srv=>get_instance( )->get( my_repokey ) ).
DATA(lt_files) = lo_online->get_files_remote( ).
In the follwing screenshot you can see the search help for the selected repository:
Get data from github
The main coding to get files from github consists of two lines of code:
DATA(lo_online) = CAST zcl_abapgit_repo_online(
zcl_abapgit_repo_srv=>get_instance( )->get( p_repo ) ).
DATA(lt_files) = lo_online->get_files_remote( ).
No user or password iis needed for this action.
Put data to github
Updating data into github is a bit more complex and I do not understand every detail of it, but it works.
One important detail I didn’t find out exactly is how to get the id of the parent parameter of the push command. Maybe someone can help here?
DATA(lo_online) = CAST zcl_abapgit_repo_online(
zcl_abapgit_repo_srv=>get_instance( )->get( p_repo ) ).
DATA(lt_files) = lo_online->get_files_remote( ).
DATA(lv_data) = zcl_abapgit_convert=>string_to_xstring_utf8( lv_adoc ).
DATA(lv_filename) = |{ file }|.
READ TABLE lt_files WITH KEY filename = lv_filename data = lv_data TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
DATA(ls_comment) = VALUE zif_abapgit_definitions=>ty_comment(
committer-name = sy-uname
committer-email = |{ sy-uname }@localhost|
comment = 'Updated' ).
ELSE.
ls_comment = VALUE zif_abapgit_definitions=>ty_comment(
committer-name = sy-uname
committer-email = |{ sy-uname }@localhost|
comment = 'Created' ).
ENDIF.
DATA(lo_stage) = NEW zcl_abapgit_stage(
iv_merge_source = lo_online->get_current_remote( ) ).
lo_stage->add(
iv_path = conv #( path )
iv_filename = lv_filename
iv_data = lv_data ).
DATA(lt_objects) = lo_online->get_objects( ).
DATA(lv_parent) = lt_objects[ type = 'commit' ]-sha1.
zcl_abapgit_git_porcelain=>push(
EXPORTING
is_comment = ls_comment
io_stage = lo_stage
it_old_objects = lt_objects
iv_parent = lv_parent
iv_url = lo_online->get_url( )
iv_branch_name = lo_online->get_selected_branch( ) ).
Old Dynpro stuff
to get the help value requests work properly I had to do some things that I didn’t to for many years: reading and updating field values of the dynpro and within the search help interface. This coding uses a lot of coding space.
In a normal project I would have defined a proper structure and set the search helps to the appropriate fields, what means much less coding.
Adding and changing files
Using the CL_GUI_TEXTEDIT control I am now capable of loading an existing file from my repository, change it and write it back. I can also create new files including new directories.
In this example I created a new file:
And this is the proof that it exists within my repository:
Conclusion
thanks to this great community and the wonderful work of all abapgit contributors the transfer of other files than repository data is easy and reliable. Thanks to all!
My proof of concept files can be found at github of course.
Have fun!
~Enno
Ahah, nice, I guess once you can write to GH, you're off to the races 🙂
I had a quick test using the development version of abapGit and I get this error:
activation error
FWIW I'm using AS ABAP 7.52 SP04; I haven't had a closer look at the error, just checking out cool stuff from dotAbap. If the error above is not a glitch and you'd like a proper bugreport, I can file an issue in GH, as you like.
Hey Andrea Borgia ! thanks for your comment. The exceptions come from an old repository of Lars Hvam that I used as template. I corrected it.
Another small change:
Â
Thanks Andrea Borgia ! I had an old version of abapGit... corrected.
Hi Enno,
Â
nice stuff as always
You don’t need the porcellain push. Just do a
instead and abapGit will take care of parent determination. Porcellain is the low level/internal API of abapGit (same principle as in git) which usually needn’t to be invoked directly.
Christian
Thanks Christian Guenter for your comment! Works perfectly...!
Btw. your program works also with other git hosting platforms like gitlab, bitbucket, ect. It isn’t restricted to github as the title and parameter labels might suggest
Hey Christian Guenter ! that's right! thanks for clarifying. I chose the most common platform. Otherwise the title would have been to long... 🙂