From b51962eb66ca9097be266390f9f31f67ca7ed900 Mon Sep 17 00:00:00 2001 From: larshp Date: Sun, 15 May 2016 13:39:30 +0000 Subject: [PATCH] folder push support #5 push support with subpackagesrm support #168add package in overview --- zabapgit.prog.abap | 281 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 211 insertions(+), 70 deletions(-) diff --git a/zabapgit.prog.abap b/zabapgit.prog.abap index 8b8fcc733..1b1742f6f 100644 --- a/zabapgit.prog.abap +++ b/zabapgit.prog.abap @@ -12574,9 +12574,9 @@ CLASS lcl_file_status IMPLEMENTATION. METHOD compare_files. - READ TABLE it_repo WITH KEY path = is_gen-path - filename = is_gen-filename - data = is_gen-data + READ TABLE it_repo WITH KEY + filename = is_gen-filename + data = is_gen-data TRANSPORTING NO FIELDS. IF sy-subrc <> 0. rv_match = abap_false. @@ -13660,6 +13660,10 @@ CLASS lcl_git_pack IMPLEMENTATION. SORT lt_nodes BY name ASCENDING. LOOP AT lt_nodes ASSIGNING . + ASSERT NOT -chmod IS INITIAL. + ASSERT NOT -name IS INITIAL. + ASSERT NOT -sha1 IS INITIAL. + CONCATENATE -chmod -name INTO lv_string SEPARATED BY space. lv_xstring = lcl_convert=>string_to_xstring_utf8( lv_string ). @@ -14849,6 +14853,27 @@ CLASS lcl_git_porcelain DEFINITION FINAL. RAISING lcx_exception. PRIVATE SECTION. + TYPES: BEGIN OF ty_expanded, + path TYPE string, + name TYPE string, + sha1 TYPE ty_sha1, + END OF ty_expanded. + + TYPES: ty_expanded_tt TYPE STANDARD TABLE OF ty_expanded WITH DEFAULT KEY. + + TYPES: BEGIN OF ty_tree, + path TYPE string, + data TYPE xstring, + sha1 TYPE ty_sha1, + END OF ty_tree. + + TYPES: ty_trees_tt TYPE STANDARD TABLE OF ty_tree WITH DEFAULT KEY. + + CLASS-METHODS build_trees + IMPORTING it_expanded TYPE ty_expanded_tt + RETURNING VALUE(rt_trees) TYPE ty_trees_tt + RAISING lcx_exception. + CLASS-METHODS walk IMPORTING it_objects TYPE lcl_git_pack=>ty_objects_tt iv_sha1 TYPE ty_sha1 @@ -14856,17 +14881,24 @@ CLASS lcl_git_porcelain DEFINITION FINAL. CHANGING ct_files TYPE ty_files_tt RAISING lcx_exception. - CLASS-METHODS root_tree - IMPORTING it_objects TYPE lcl_git_pack=>ty_objects_tt - iv_branch TYPE ty_sha1 - RETURNING VALUE(rt_nodes) TYPE lcl_git_pack=>ty_nodes_tt + CLASS-METHODS walk_tree + IMPORTING it_objects TYPE lcl_git_pack=>ty_objects_tt + iv_tree TYPE ty_sha1 + iv_base TYPE string + RETURNING VALUE(rt_expanded) TYPE ty_expanded_tt + RAISING lcx_exception. + + CLASS-METHODS full_tree + IMPORTING it_objects TYPE lcl_git_pack=>ty_objects_tt + iv_branch TYPE ty_sha1 + RETURNING VALUE(rt_expanded) TYPE ty_expanded_tt RAISING lcx_exception. CLASS-METHODS receive_pack IMPORTING is_comment TYPE ty_comment io_repo TYPE REF TO lcl_repo_online - it_nodes TYPE lcl_git_pack=>ty_nodes_tt - it_files TYPE ty_files_tt + it_trees TYPE ty_trees_tt + it_blobs TYPE ty_files_tt iv_branch TYPE ty_sha1 RETURNING VALUE(rv_branch) TYPE ty_sha1 RAISING lcx_exception. @@ -16604,22 +16636,24 @@ CLASS lcl_git_porcelain IMPLEMENTATION. METHOD receive_pack. - DATA: lv_tree TYPE xstring, - lv_time TYPE lcl_time=>ty_unixtime, + DATA: lv_time TYPE lcl_time=>ty_unixtime, lv_commit TYPE xstring, lt_objects TYPE lcl_git_pack=>ty_objects_tt, lv_pack TYPE xstring, ls_object LIKE LINE OF lt_objects, ls_commit TYPE lcl_git_pack=>ty_commit. - FIELD-SYMBOLS: LIKE LINE OF it_files. + FIELD-SYMBOLS: LIKE LINE OF it_trees, + LIKE LINE OF it_blobs. - lv_tree = lcl_git_pack=>encode_tree( it_nodes ). + lv_time = lcl_time=>get( ). + + READ TABLE it_trees ASSIGNING WITH KEY path = '/'. + ASSERT sy-subrc = 0. * new commit - lv_time = lcl_time=>get( ). - ls_commit-tree = lcl_hash=>sha1( iv_type = gc_type-tree iv_data = lv_tree ). + ls_commit-tree = -sha1. ls_commit-parent = iv_branch. CONCATENATE is_comment-username space '<' is_comment-email '>' space lv_time INTO ls_commit-author RESPECTING BLANKS. @@ -16632,16 +16666,20 @@ CLASS lcl_git_porcelain IMPLEMENTATION. ls_object-type = gc_type-commit. ls_object-data = lv_commit. APPEND ls_object TO lt_objects. - CLEAR ls_object. - ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-tree iv_data = lv_tree ). - ls_object-type = gc_type-tree. - ls_object-data = lv_tree. - APPEND ls_object TO lt_objects. - LOOP AT it_files ASSIGNING . + + LOOP AT it_trees ASSIGNING . CLEAR ls_object. - ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -data ). + ls_object-sha1 = -sha1. + ls_object-type = gc_type-tree. + ls_object-data = -data. + APPEND ls_object TO lt_objects. + ENDLOOP. + + LOOP AT it_blobs ASSIGNING . + CLEAR ls_object. + ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -data ). ls_object-type = gc_type-blob. - ls_object-data = -data. + ls_object-data = -data. APPEND ls_object TO lt_objects. ENDLOOP. @@ -16656,66 +16694,97 @@ CLASS lcl_git_porcelain IMPLEMENTATION. METHOD push. -* todo, only works with root files + DATA: lt_expanded TYPE ty_expanded_tt, + lt_blobs TYPE ty_files_tt, + lv_sha1 TYPE ty_sha1, + lt_trees TYPE ty_trees_tt, + lt_stage TYPE lcl_stage=>ty_stage_tt. - DATA: - lt_nodes TYPE lcl_git_pack=>ty_nodes_tt, - lt_files TYPE ty_files_tt, - lv_sha1 TYPE ty_sha1, - lt_stage TYPE lcl_stage=>ty_stage_tt, - lv_index TYPE i. - - FIELD-SYMBOLS: LIKE LINE OF lt_files, - LIKE LINE OF lt_stage, - LIKE LINE OF lt_nodes. + FIELD-SYMBOLS: LIKE LINE OF lt_stage, + LIKE LINE OF lt_expanded. - lt_nodes = root_tree( it_objects = io_repo->get_objects( ) - iv_branch = io_repo->get_sha1_remote( ) ). + lt_expanded = full_tree( it_objects = io_repo->get_objects( ) + iv_branch = io_repo->get_sha1_remote( ) ). -* todo, can only handle add lt_stage = io_stage->get_all( ). LOOP AT lt_stage ASSIGNING . CASE -method. WHEN lcl_stage=>c_method-add. - APPEND -file TO lt_files. + APPEND -file TO lt_blobs. + + READ TABLE lt_expanded ASSIGNING WITH KEY + name = -file-filename + path = -file-path. + IF sy-subrc <> 0. " new files + APPEND INITIAL LINE TO lt_expanded ASSIGNING . + -name = -file-filename. + -path = -file-path. + ENDIF. + + lv_sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -file-data ). + IF -sha1 <> lv_sha1. + -sha1 = lv_sha1. + ENDIF. + WHEN lcl_stage=>c_method-rm. + DELETE lt_expanded + WHERE name = -file-filename + AND path = -file-path. + ASSERT sy-subrc = 0. WHEN OTHERS. -* todo, work in progress see issue #5 on github _raise 'stage method not supported, todo'. ENDCASE. ENDLOOP. - LOOP AT lt_files ASSIGNING . - lv_index = sy-tabix. - READ TABLE lt_nodes ASSIGNING WITH KEY name = -filename. - IF sy-subrc <> 0. -* new files - APPEND INITIAL LINE TO lt_nodes ASSIGNING . - -chmod = gc_chmod-file. - -name = -filename. - ENDIF. - - lv_sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -data ). - IF -sha1 <> lv_sha1. - -sha1 = lv_sha1. - ELSE. - DELETE lt_files INDEX lv_index. - ENDIF. - ENDLOOP. - - IF lt_files[] IS INITIAL. - _raise 'no files'. - ENDIF. + lt_trees = build_trees( lt_expanded ). rv_branch = receive_pack( is_comment = is_comment io_repo = io_repo - it_nodes = lt_nodes - it_files = lt_files + it_trees = lt_trees + it_blobs = lt_blobs iv_branch = io_repo->get_sha1_remote( ) ). ENDMETHOD. "push - METHOD root_tree. + METHOD walk_tree. + + DATA: ls_object LIKE LINE OF it_objects, + lt_expanded LIKE rt_expanded, + lt_nodes TYPE lcl_git_pack=>ty_nodes_tt. + + FIELD-SYMBOLS: LIKE LINE OF rt_expanded, + LIKE LINE OF lt_nodes. + + + READ TABLE it_objects INTO ls_object + WITH KEY sha1 = iv_tree + type = gc_type-tree. + IF sy-subrc <> 0. + _raise 'tree not found'. + ENDIF. + lt_nodes = lcl_git_pack=>decode_tree( ls_object-data ). + + LOOP AT lt_nodes ASSIGNING . + CASE -chmod. + WHEN gc_chmod-file. + APPEND INITIAL LINE TO rt_expanded ASSIGNING . + -path = iv_base. + -name = -name. + -sha1 = -sha1. + WHEN gc_chmod-dir. + lt_expanded = walk_tree( + it_objects = it_objects + iv_tree = -sha1 + iv_base = iv_base && -name && '/' ). + APPEND LINES OF lt_expanded TO rt_expanded. + WHEN OTHERS. + _raise 'walk_tree: unknown chmod'. + ENDCASE. + ENDLOOP. + + ENDMETHOD. + + METHOD full_tree. DATA: ls_object LIKE LINE OF it_objects, ls_commit TYPE lcl_git_pack=>ty_commit. @@ -16727,12 +16796,9 @@ CLASS lcl_git_porcelain IMPLEMENTATION. ENDIF. ls_commit = lcl_git_pack=>decode_commit( ls_object-data ). - READ TABLE it_objects INTO ls_object - WITH KEY sha1 = ls_commit-tree type = gc_type-tree. - IF sy-subrc <> 0. - _raise 'tree not found'. - ENDIF. - rt_nodes = lcl_git_pack=>decode_tree( ls_object-data ). + rt_expanded = walk_tree( it_objects = it_objects + iv_tree = ls_commit-tree + iv_base = '/' ). ENDMETHOD. "root_tree @@ -16772,6 +16838,77 @@ CLASS lcl_git_porcelain IMPLEMENTATION. ENDMETHOD. "pull + METHOD build_trees. + + TYPES: BEGIN OF ty_folder, + path TYPE string, + count TYPE i, + sha1 TYPE ty_sha1, + END OF ty_folder. + + TYPES: ty_folders_tt TYPE STANDARD TABLE OF ty_folder WITH DEFAULT KEY. + + DATA: lt_nodes TYPE lcl_git_pack=>ty_nodes_tt, + ls_tree LIKE LINE OF rt_trees, + lv_sub TYPE string, + lv_len TYPE i, + lt_folders TYPE ty_folders_tt. + + FIELD-SYMBOLS: LIKE LINE OF lt_folders, + LIKE LINE OF lt_nodes, + LIKE LINE OF lt_folders, + LIKE LINE OF it_expanded. + + + LOOP AT it_expanded ASSIGNING . + READ TABLE lt_folders WITH KEY path = -path TRANSPORTING NO FIELDS. + IF sy-subrc <> 0. + APPEND INITIAL LINE TO lt_folders ASSIGNING . + -path = -path. + FIND ALL OCCURRENCES OF '/' IN -path MATCH COUNT -count. + ENDIF. + ENDLOOP. + +* start with the deepest folders + SORT lt_folders BY count DESCENDING. + + LOOP AT lt_folders ASSIGNING . + CLEAR lt_nodes. + +* files + LOOP AT it_expanded ASSIGNING WHERE path = -path. + APPEND INITIAL LINE TO lt_nodes ASSIGNING . + -chmod = gc_chmod-file. + -name = -name. + -sha1 = -sha1. + ENDLOOP. + +* folders + lv_sub = -path && '+*'. + LOOP AT lt_folders ASSIGNING WHERE count = -count + 1 AND path CP lv_sub. + APPEND INITIAL LINE TO lt_nodes ASSIGNING . + -chmod = gc_chmod-dir. + +* extract folder name, this can probably be done easier using regular expressions + lv_len = strlen( -path ). + -name = -path+lv_len. + lv_len = strlen( -name ) - 1. + -name = -name(lv_len). + + -sha1 = -sha1. + ENDLOOP. + + CLEAR ls_tree. + ls_tree-path = -path. + ls_tree-data = lcl_git_pack=>encode_tree( lt_nodes ). + ls_tree-sha1 = lcl_hash=>sha1( iv_type = gc_type-tree iv_data = ls_tree-data ). + APPEND ls_tree TO rt_trees. + + -sha1 = ls_tree-sha1. + ENDLOOP. + + ENDMETHOD. + METHOD walk. DATA: lv_path TYPE string, @@ -18933,13 +19070,17 @@ CLASS lcl_gui_page_main IMPLEMENTATION. ENDWHILE. IF -obj_type IS INITIAL. - lv_object = ' '. + lv_object = ' ' && + ''. lv_trclass = ' class="unsupported"'. ELSE. CLEAR lv_trclass. lv_object = '' && jump_link( iv_obj_type = -obj_type iv_obj_name = -obj_name ) && + '' && + '' && + -package && ''. ENDIF. ELSE.