├── .abapgit.xml ├── LICENSE ├── README.md ├── abaplint.json ├── package-lock.json ├── package.json └── src ├── package.devc.xml ├── zabapgit_api_rfc.fugr.lzabapgit_api_rfctop.abap ├── zabapgit_api_rfc.fugr.lzabapgit_api_rfctop.xml ├── zabapgit_api_rfc.fugr.saplzabapgit_api_rfc.abap ├── zabapgit_api_rfc.fugr.saplzabapgit_api_rfc.xml ├── zabapgit_api_rfc.fugr.xml ├── zabapgit_api_rfc.fugr.zabapgit_api_rfc_link.abap ├── zabapgit_api_rfc.fugr.zabapgit_api_rfc_pull.abap ├── zabapgit_api_rfc.fugr.zabapgit_api_rfc_switchbranch.abap └── zabapgit_api_rfc.fugr.zabapgit_api_rfc_unlink.abap /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | /src/ 7 | PREFIX 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 abapGit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abapGit API 2 | This API enables you to perform essential abapGit functions on a remote SAP system. 3 | 4 | ## Overview 5 | abapGit API can be used for building your CI tools and integrations. 6 | 7 | It allows you to perform the following actions: 8 | 1. Link the repository 9 | 2. Pull the repository 10 | 3. Switch the branch 11 | 4. Unlink the repository 12 | 13 | ## Requirements and installation 14 | 1. Install the [sapcli](https://github.com/jfilak/sapcli) 15 | 2. Install PyRFC 16 | 3. Add a configuration file (as documented in the sapcli repository) 17 | 4. The remote SAP system must have [abapGit developer version](https://github.com/abapGit/abapGit) and abapgit-api-rfc (this repo) installed 18 | 19 | ## Usage 20 | ### Create link 21 | ZABAPGIT_API_RFC_LINK 22 | - required 23 | - GIT_REPO_URL 24 | - GIT_USER 25 | - GIT_PASSWORD 26 | - optional 27 | - ABAP_PACKAGE 28 | - BRANCH 29 | - FOLDER_LOGIC 30 | - IGNORE_SUBPACKAGES 31 | - MAIN_LANG_ONLY 32 | - STARTING_FOLDER 33 | 34 | example: 35 | ``` 36 | sapcli startrfc -c bapi ZABAPGIT_API_RFC_LINK -S=GIT_REPO_URL:https://github.com/abapGit/background_modes -S=GIT_USER:filak-sap -S=GIT_PASSWORD:${MY_GH_TOKEN} -S=ABAP_PACKAGE:'$BACKGROUND_MODES' 37 | ``` 38 | 39 | ### Pull Repo 40 | ZABAPGIT_API_RFC_PULL 41 | - required 42 | - ABAP_PACKAGE 43 | - GIT_USER 44 | - GIT_PASSWORD 45 | - optional 46 | - CORRNR 47 | 48 | example: 49 | ``` 50 | sapcli startrfc -c bapi ZABAPGIT_API_RFC_PULL -S=ABAP_PACKAGE:'$BACKGROUND_MODES' -S=GIT_USER:filak-sap -S=GIT_PASSWORD:${MY_GH_TOKEN} 51 | ``` 52 | 53 | ### Switch branch 54 | ZABAPGIT_API_RFC_SWITCHBRANCH 55 | - required 56 | - ABAP_PACKAGE 57 | - GIT_USER 58 | - GIT_PASSWORD 59 | - optional 60 | - BRANCH_NAME 61 | 62 | example: 63 | ``` 64 | sapcli startrfc -c bapi ZABAPGIT_API_RFC_SWITCHBRANCH -S=ABAP_PACKAGE:'$BACKGROUND_MODES' -S=GIT_USER:filak-sap -S=GIT_PASSWORD:${MY_GH_TOKEN} -S=BRANCH_NAME:main 65 | ``` 66 | 67 | ### Unlink 68 | ZABAPGIT_API_RFC_UNLINK 69 | - required 70 | - ABAP_PACKAGE 71 | 72 | example: 73 | ``` 74 | sapcli startrfc -c bapi ZABAPGIT_API_RFC_UNLINK -S=ABAP_PACKAGE:'$BACKGROUND_MODES' 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /abaplint.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "files": "/src/**/*.*", 4 | "skipGeneratedGatewayClasses": true, 5 | "skipGeneratedPersistentClasses": true, 6 | "skipGeneratedFunctionGroups": true 7 | }, 8 | "dependencies": [ 9 | { 10 | "url": "https://github.com/abaplint/deps", 11 | "folder": "/deps_lint", 12 | "files": "/src/**/*.*" 13 | }, 14 | { 15 | "url": "https://github.com/abapGit/abapGit", 16 | "folder": "/deps_abapGit", 17 | "files": "/src/**/*.*" 18 | } 19 | ], 20 | "syntax": { 21 | "version": "v750", 22 | "errorNamespace": "^(Z|Y|LT?CL_|TY_|LIF_|.*ABAPGIT)", 23 | "globalConstants": [ 24 | "abap_func_exporting", 25 | "abap_func_tables", 26 | "cssf_formtype_text", 27 | "seoc_category_exception", 28 | "seoc_category_webdynpro_class", 29 | "seoc_exposure_private", 30 | "seoc_exposure_protected", 31 | "seoc_exposure_public", 32 | "seoc_version_active", 33 | "seoc_version_inactive", 34 | "seok_access_free", 35 | "seok_access_modify", 36 | "seok_pgmid_r3tr", 37 | "seop_ext_class_locals_def", 38 | "seop_ext_class_locals_imp", 39 | "seop_ext_class_macros", 40 | "seop_ext_class_testclasses", 41 | "seop_incextapp_definition", 42 | "seop_incextapp_implementation", 43 | "seop_incextapp_macros", 44 | "seop_incextapp_testclasses", 45 | "sews_c_vif_version", 46 | "skwfc_obtype_folder", 47 | "skwfc_obtype_loio", 48 | "so2_controller", 49 | "ststc_c_type_dialog", 50 | "ststc_c_type_object", 51 | "ststc_c_type_parameters", 52 | "ststc_c_type_report", 53 | "swbm_c_op_delete_no_dialog", 54 | "swbm_c_type_ddic_db_tabxinx", 55 | "swbm_c_type_wdy_application", 56 | "swbm_version_active", 57 | "swbm_version_inactive", 58 | "swfco_org_standard_task", 59 | "swfco_org_workflow_template", 60 | "wbmr_c_skwf_folder_class", 61 | "wdyn_limu_component_controller", 62 | "wdyn_limu_component_definition", 63 | "wdyn_limu_component_view" 64 | ], 65 | "globalMacros": [] 66 | }, 67 | "rules": { 68 | "align_parameters": false, 69 | "cds_parser_error": true, 70 | "constant_classes": true, 71 | "no_aliases": false, 72 | "nrob_consistency": true, 73 | "omit_preceding_zeros": true, 74 | "prefer_corresponding": true, 75 | "static_call_via_instance": false, 76 | "unnecessary_chaining": false, 77 | "unsecure_fae": false, 78 | "identical_descriptions": false, 79 | "modify_only_own_db_tables": false, 80 | "no_yoda_conditions": false, 81 | "no_chained_assignment": true, 82 | "select_add_order_by": false, 83 | "dangerous_statement": false, 84 | "db_operation_in_loop": false, 85 | "select_performance": false, 86 | "max_one_method_parameter_per_line": true, 87 | "unused_ddic": true, 88 | "prefer_raise_exception_new": true, 89 | "use_class_based_exceptions": true, 90 | "uncaught_exception": true, 91 | "intf_referencing_clas": false, 92 | "method_implemented_twice": true, 93 | "parser_702_chaining": true, 94 | "sy_modification": false, 95 | "call_transaction_authority_check": true, 96 | "function_module_recommendations": false, 97 | "method_overwrites_builtin": false, 98 | "omit_parameter_name": false, 99 | "omit_receiving": true, 100 | "unused_methods": true, 101 | "identical_contents": false, 102 | "many_parentheses": true, 103 | "prefer_xsdbool": true, 104 | "prefer_is_not": false, 105 | "use_bool_expression": true, 106 | "check_subrc": false, 107 | "cyclomatic_complexity": { 108 | "max": 25 109 | }, 110 | "identical_conditions": true, 111 | "use_line_exists": true, 112 | "line_break_style": true, 113 | "forbidden_pseudo_and_pragma": { 114 | "ignoreGlobalClassDefinition": true, 115 | "ignoreGlobalInterface": true, 116 | "pragmas": ["##NO_TEXT"], 117 | "pseudo": ["#EC NOTEXT"] 118 | }, 119 | "unused_types": true, 120 | "begin_single_include": true, 121 | "names_no_dash": true, 122 | "parser_missing_space": true, 123 | "prefer_inline": false, 124 | "reduce_string_templates": true, 125 | "downport": false, 126 | "line_break_multiple_parameters": true, 127 | "unknown_types": true, 128 | "forbidden_void_type": { 129 | "check": ["^stringtab$", "^SYCHAR01$", "^char2$", "^char20$", "^int4$", "^SYREPID$", 130 | "^flag$", "^char12$", "^char10$", "^char70$", "^char4$", "^sydatum$", "^syuzeit$", 131 | "^syst_title$", "^sychar70$", "^char30$", "^char50$", 132 | "^numc2$", "^sap_bool$", "^SYCHAR10$", "^sylangu$", 133 | "^cl_blue_wb_utility$", "^boole_d$", 134 | "^cl_srvd_wb_object_data$", "^cx_aff_", "^cl_aff_", "^if_aff_", 135 | "^cl_wb_object_operator_factory$", 136 | "^cl_aunit_assert$", 137 | "^cx_wb_object_operation_error$", 138 | "^if_srvd_types$", "^xubname$", 139 | "^if_wb_adt_plugin_resource_co$", 140 | "^if_wb_object_data_selection_co$", 141 | "^if_wb_object_operator$" 142 | ] 143 | }, 144 | "forbidden_identifier": true, 145 | "try_without_catch": true, 146 | "unused_variables": false, 147 | "prefix_is_current_class": true, 148 | "allowed_object_naming": true, 149 | "check_comments": false, 150 | "cyclic_oo": false, 151 | "fully_type_constants": true, 152 | "keep_single_parameter_on_one_line": true, 153 | "prefer_returning_to_exporting": true, 154 | "selection_screen_naming": true, 155 | "sicf_consistency": true, 156 | "sql_escape_host_variables": true, 157 | "xml_consistency": true, 158 | "newline_between_methods": false, 159 | "chain_mainly_declarations": { 160 | "definitions": true, 161 | "write": true, 162 | "move": true, 163 | "refresh": true, 164 | "unassign": true, 165 | "sort": true, 166 | "clear": true, 167 | "hide": true, 168 | "free": true, 169 | "include": true, 170 | "check": true 171 | }, 172 | "check_abstract": true, 173 | "check_text_elements": true, 174 | "types_naming": { 175 | "pattern": "^TY_.+$", 176 | "exclude": ["/json/"] 177 | }, 178 | "7bit_ascii": { 179 | "exclude": ["zcl_abapgit_utils.clas.testclasses.abap"] 180 | }, 181 | "abapdoc": false, 182 | "check_ddic": true, 183 | "check_include": true, 184 | "allowed_object_types": { 185 | "allowed": [ 186 | "PROG", 187 | "CLAS", 188 | "INTF", 189 | "FUGR", 190 | "DEVC", 191 | "TRAN", 192 | "W3MI" 193 | ] 194 | }, 195 | "ambiguous_statement": true, 196 | "avoid_use": { 197 | "define": true, 198 | "defaultKey": false, 199 | "testSeams": true, 200 | "describeLines": true, 201 | "break": true, 202 | "statics": true 203 | }, 204 | "begin_end_names": true, 205 | "check_transformation_exists": true, 206 | "check_syntax": true, 207 | "class_attribute_names": { 208 | "ignoreExceptions": true, 209 | "ignoreInterfaces": false, 210 | "statics": "^G._.*$", 211 | "ignoreLocal": false, 212 | "constants": "", 213 | "instance": "^M._.*$" 214 | }, 215 | "cloud_types": true, 216 | "colon_missing_space": true, 217 | "commented_code": { 218 | "allowIncludeInFugr": false, 219 | "exclude": ["otgr"] 220 | }, 221 | "constructor_visibility_public": true, 222 | "contains_tab": true, 223 | "definitions_top": { 224 | "exclude": ["/json/"] 225 | }, 226 | "description_empty": { 227 | "exclude": ["/test/"] 228 | }, 229 | "double_space": false, 230 | "empty_line_in_statement": { 231 | "allowChained": true 232 | }, 233 | "empty_statement": true, 234 | "empty_structure": { 235 | "loop": true, 236 | "if": false, 237 | "try": true, 238 | "while": true, 239 | "case": true, 240 | "select": true, 241 | "when": false, 242 | "do": true, 243 | "at": true 244 | }, 245 | "exit_or_check": true, 246 | "exporting": true, 247 | "form_tables_obsolete": false, 248 | "functional_writing": { 249 | "ignoreExceptions": true 250 | }, 251 | "global_class": true, 252 | "identical_form_names": true, 253 | "if_in_if": true, 254 | "implement_methods": true, 255 | "in_statement_indentation": false, 256 | "indentation": { 257 | "ignoreExceptions": true, 258 | "alignTryCatch": false, 259 | "selectionScreenBlockIndentation": false, 260 | "globalClassSkipFirst": false, 261 | "ignoreGlobalClassDefinition": false, 262 | "ignoreGlobalInterface": false 263 | }, 264 | "inline_data_old_versions": true, 265 | "keyword_case": { 266 | "style": "upper", 267 | "ignoreExceptions": true, 268 | "ignoreLowerClassImplmentationStatement": true, 269 | "ignoreGlobalClassDefinition": false, 270 | "ignoreGlobalInterface": false, 271 | "ignoreKeywords": [], 272 | "ignoreGlobalClassBoundaries": false, 273 | "ignoreFunctionModuleName": false 274 | }, 275 | "line_length": { 276 | "length": 120, 277 | "exclude": ["zcl_abapgit_object_pdts.clas.testclasses.abap"] 278 | }, 279 | "line_only_punc": { 280 | "ignoreExceptions": true 281 | }, 282 | "local_class_naming": { 283 | "exception": "^LCX_.*$", 284 | "local": "^LCL_.*$", 285 | "test": "^LT.+$" 286 | }, 287 | "main_file_contents": true, 288 | "max_one_statement": true, 289 | "message_exists": false, 290 | "method_length": { 291 | "statements": 100, 292 | "checkForms": true, 293 | "ignoreTestClasses": false, 294 | "errorWhenEmpty": false 295 | }, 296 | "mix_returning": true, 297 | "msag_consistency": true, 298 | "nesting": { 299 | "depth": 6 300 | }, 301 | "no_public_attributes": false, 302 | "object_naming": { 303 | "clas": "^ZC(L|X)\\_ABAPGIT\\_", 304 | "intf": "^ZIF\\_ABAPGIT\\_", 305 | "prog": "^ZABAPGIT", 306 | "fugr": "^ZABAPGIT", 307 | "tabl": "^Z", 308 | "ttyp": "^Z", 309 | "dtel": "^Z", 310 | "doma": "^Z", 311 | "msag": "^Z", 312 | "tran": "^Z", 313 | "enqu": "^EZ", 314 | "auth": "^Z", 315 | "pinf": "^Z", 316 | "idoc": "^Z", 317 | "ssfo": "^Z", 318 | "ssst": "^Z", 319 | "shlp": "^Z", 320 | "xslt": "^Z" 321 | }, 322 | "obsolete_statement": { 323 | "refresh": true, 324 | "compute": true, 325 | "clientSpecified": true, 326 | "add": true, 327 | "occurences": true, 328 | "selectWithoutInto": true, 329 | "ranges": true, 330 | "formDefinition": true, 331 | "formImplementation": true, 332 | "callTransformation": true, 333 | "regex": true, 334 | "sortByFS": true, 335 | "subtract": true, 336 | "freeMemory": true, 337 | "exitFromSQL": true, 338 | "multiply": true, 339 | "communication": true, 340 | "typePools": true, 341 | "load": true, 342 | "move": true, 343 | "divide": true, 344 | "fieldSymbolStructure": true, 345 | "requested": true, 346 | "pack": true, 347 | "setExtended": true, 348 | "withHeaderLine": true, 349 | "occurs": true, 350 | "parameter": true 351 | }, 352 | "parser_error": {}, 353 | "preferred_compare_operator": { 354 | "badOperators": [ 355 | "EQ", 356 | "><", 357 | "NE", 358 | "GE", 359 | "GT", 360 | "LT", 361 | "LE" 362 | ] 363 | }, 364 | "release_idoc": true, 365 | "remove_descriptions": { 366 | "ignoreWorkflow": false, 367 | "ignoreExceptions": false, 368 | "exclude": ["/json/"] 369 | }, 370 | "rfc_error_handling": false, 371 | "sequential_blank": { 372 | "lines": 4 373 | }, 374 | "short_case": { 375 | "length": 1, 376 | "allow": [ 377 | "iv_action", 378 | "sy" 379 | ] 380 | }, 381 | "space_before_colon": true, 382 | "space_before_dot": { 383 | "ignoreGlobalDefinition": true, 384 | "ignoreExceptions": true 385 | }, 386 | "start_at_tab": true, 387 | "superclass_final": true, 388 | "tabl_enhancement_category": true, 389 | "type_form_parameters": true, 390 | "unreachable_code": true, 391 | "use_new": true, 392 | "when_others_last": true, 393 | "whitespace_end": true 394 | } 395 | } 396 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "host", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "license": "MIT", 8 | "devDependencies": { 9 | "@abaplint/cli": "^2.87.0", 10 | "@abaplint/database-sqlite": "^2.0.0", 11 | "@abaplint/runtime": "^2.0.0", 12 | "@abaplint/transpiler-cli": "^2.0.0" 13 | } 14 | }, 15 | "node_modules/@abaplint/cli": { 16 | "version": "2.88.8", 17 | "resolved": "https://registry.npmjs.org/@abaplint/cli/-/cli-2.88.8.tgz", 18 | "integrity": "sha512-BACkIVyaiLLDxsCqUhpp3PYUk9IQ2pyQ5HH5nEmIgoeEpRWYuQ4SH/wVM1xF78NuvPC7JfnAJrSQFB2ZAfa70A==", 19 | "dev": true, 20 | "bin": { 21 | "abaplint": "abaplint" 22 | }, 23 | "engines": { 24 | "node": ">=12.0.0" 25 | } 26 | }, 27 | "node_modules/@abaplint/database-sqlite": { 28 | "version": "2.0.1", 29 | "resolved": "https://registry.npmjs.org/@abaplint/database-sqlite/-/database-sqlite-2.0.1.tgz", 30 | "integrity": "sha512-hXyyP4hk5+kJIbT51wjrrDSjvjMuzY41aXqDmO3p7ki7CzDxoDX2kronhGVxoiPknjDp0UT2blJDngLW+4U+AQ==", 31 | "dev": true, 32 | "dependencies": { 33 | "sql.js": "^1.6.2" 34 | } 35 | }, 36 | "node_modules/@abaplint/runtime": { 37 | "version": "2.0.7", 38 | "resolved": "https://registry.npmjs.org/@abaplint/runtime/-/runtime-2.0.7.tgz", 39 | "integrity": "sha512-9xEDacpcTz4CZFyMi+xgv7aZGp9Z1JW0QGKBkSa2/ufA2kPhN5iqI2jQdHCI0VmMEtV6YCx4x9PrW3OJ6u1KuQ==", 40 | "dev": true 41 | }, 42 | "node_modules/@abaplint/transpiler-cli": { 43 | "version": "2.0.7", 44 | "resolved": "https://registry.npmjs.org/@abaplint/transpiler-cli/-/transpiler-cli-2.0.7.tgz", 45 | "integrity": "sha512-KoIEttxVvRmavGsZaMQ9MX6IFY1upzVTcuyyIfBQHjEGyKINnvp6FHeaza4BQOd0FinspAFF7kVR4OucTLjSVA==", 46 | "dev": true, 47 | "bin": { 48 | "abap_transpile": "abap_transpile" 49 | } 50 | }, 51 | "node_modules/sql.js": { 52 | "version": "1.6.2", 53 | "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-1.6.2.tgz", 54 | "integrity": "sha512-9iucI5fXQa+Gspeqf/BNB20PxJIn5LhXDt4mjXoFPqXdR+NqtFs15SdKpSIJ6s529aGL9zFR9p2eSCIEiMsNGA==", 55 | "dev": true 56 | } 57 | }, 58 | "dependencies": { 59 | "@abaplint/cli": { 60 | "version": "2.88.8", 61 | "resolved": "https://registry.npmjs.org/@abaplint/cli/-/cli-2.88.8.tgz", 62 | "integrity": "sha512-BACkIVyaiLLDxsCqUhpp3PYUk9IQ2pyQ5HH5nEmIgoeEpRWYuQ4SH/wVM1xF78NuvPC7JfnAJrSQFB2ZAfa70A==", 63 | "dev": true 64 | }, 65 | "@abaplint/database-sqlite": { 66 | "version": "2.0.1", 67 | "resolved": "https://registry.npmjs.org/@abaplint/database-sqlite/-/database-sqlite-2.0.1.tgz", 68 | "integrity": "sha512-hXyyP4hk5+kJIbT51wjrrDSjvjMuzY41aXqDmO3p7ki7CzDxoDX2kronhGVxoiPknjDp0UT2blJDngLW+4U+AQ==", 69 | "dev": true, 70 | "requires": { 71 | "sql.js": "^1.6.2" 72 | } 73 | }, 74 | "@abaplint/runtime": { 75 | "version": "2.0.7", 76 | "resolved": "https://registry.npmjs.org/@abaplint/runtime/-/runtime-2.0.7.tgz", 77 | "integrity": "sha512-9xEDacpcTz4CZFyMi+xgv7aZGp9Z1JW0QGKBkSa2/ufA2kPhN5iqI2jQdHCI0VmMEtV6YCx4x9PrW3OJ6u1KuQ==", 78 | "dev": true 79 | }, 80 | "@abaplint/transpiler-cli": { 81 | "version": "2.0.7", 82 | "resolved": "https://registry.npmjs.org/@abaplint/transpiler-cli/-/transpiler-cli-2.0.7.tgz", 83 | "integrity": "sha512-KoIEttxVvRmavGsZaMQ9MX6IFY1upzVTcuyyIfBQHjEGyKINnvp6FHeaza4BQOd0FinspAFF7kVR4OucTLjSVA==", 84 | "dev": true 85 | }, 86 | "sql.js": { 87 | "version": "1.6.2", 88 | "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-1.6.2.tgz", 89 | "integrity": "sha512-9iucI5fXQa+Gspeqf/BNB20PxJIn5LhXDt4mjXoFPqXdR+NqtFs15SdKpSIJ6s529aGL9zFR9p2eSCIEiMsNGA==", 90 | "dev": true 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "MIT", 3 | "scripts": { 4 | "abaplint": "abaplint --format codeframe", 5 | "autoformat": "abaplint --format codeframe --fix" 6 | }, 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/abapGit/abapGit.git" 10 | }, 11 | "c8": { 12 | "all": true, 13 | "src": [ 14 | "src" 15 | ] 16 | }, 17 | "devDependencies": { 18 | "@abaplint/cli": "^2.87.0", 19 | "@abaplint/runtime": "^2.0.0", 20 | "@abaplint/transpiler-cli": "^2.0.0", 21 | "@abaplint/database-sqlite": "^2.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | abapGit operations wrapped in RFC Function Modules 7 | X 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.lzabapgit_api_rfctop.abap: -------------------------------------------------------------------------------- 1 | FUNCTION-POOL zabapgit_api_rfc. "MESSAGE-ID .. 2 | 3 | * INCLUDE LZABAPGIT_API_RFCD... " Local class definition 4 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.lzabapgit_api_rfctop.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | LZABAPGIT_API_RFCTOP 7 | S 8 | D$ 9 | I 10 | S 11 | X 12 | D$S 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.saplzabapgit_api_rfc.abap: -------------------------------------------------------------------------------- 1 | ******************************************************************* 2 | * System-defined Include-files. * 3 | ******************************************************************* 4 | INCLUDE lzabapgit_api_rfctop. " Global Declarations 5 | INCLUDE lzabapgit_api_rfcuxx. " Function Modules 6 | 7 | ******************************************************************* 8 | * User-defined Include-files (if necessary). * 9 | ******************************************************************* 10 | * INCLUDE LZABAPGIT_API_RFCF... " Subroutines 11 | * INCLUDE LZABAPGIT_API_RFCO... " PBO-Modules 12 | * INCLUDE LZABAPGIT_API_RFCI... " PAI-Modules 13 | * INCLUDE LZABAPGIT_API_RFCE... " Events 14 | * INCLUDE LZABAPGIT_API_RFCP... " Local class implement. 15 | * INCLUDE LZABAPGIT_API_RFCT99. " ABAP Unit tests 16 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.saplzabapgit_api_rfc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | SAPLZABAPGIT_API_RFC 7 | S 8 | D$ 9 | F 10 | S 11 | E 12 | X 13 | D$S 14 | X 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | abapGit RFC API 6 | 7 | LZABAPGIT_API_RFCTOP 8 | SAPLZABAPGIT_API_RFC 9 | 10 | 11 | 12 | ZABAPGIT_API_RFC_LINK 13 | R 14 | abapGit RFC linking a repo with a package 15 | 16 | 17 | ABAP_PACKAGE 18 | '' 19 | X 20 | DEVCLASS 21 | 22 | 23 | GIT_REPO_URL 24 | STRING 25 | 26 | 27 | GIT_USER 28 | STRING 29 | 30 | 31 | GIT_PASSWORD 32 | STRING 33 | 34 | 35 | BRANCH 36 | '' 37 | X 38 | STRING 39 | 40 | 41 | FOLDER_LOGIC 42 | 'PREFIX' 43 | X 44 | STRING 45 | 46 | 47 | IGNORE_SUBPACKAGES 48 | '' 49 | X 50 | XFELD 51 | 52 | 53 | MAIN_LANG_ONLY 54 | '' 55 | X 56 | XFELD 57 | 58 | 59 | STARTING_FOLDER 60 | '/src/' 61 | X 62 | STRING 63 | 64 | 65 | 66 | 67 | RETURN 68 | BAPIRET2 69 | 70 | 71 | 72 | 73 | ABAP_PACKAGE 74 | P 75 | 76 | 77 | GIT_REPO_URL 78 | P 79 | 80 | 81 | GIT_USER 82 | P 83 | 84 | 85 | GIT_PASSWORD 86 | P 87 | 88 | 89 | BRANCH 90 | P 91 | 92 | 93 | FOLDER_LOGIC 94 | P 95 | 96 | 97 | IGNORE_SUBPACKAGES 98 | P 99 | 100 | 101 | MAIN_LANG_ONLY 102 | P 103 | 104 | 105 | STARTING_FOLDER 106 | P 107 | 108 | 109 | RETURN 110 | P 111 | 112 | 113 | 114 | 115 | ZABAPGIT_API_RFC_PULL 116 | R 117 | abapGit RFC pulling a repo with a package 118 | 119 | 120 | ABAP_PACKAGE 121 | DEVCLASS 122 | 123 | 124 | GIT_USER 125 | STRING 126 | 127 | 128 | GIT_PASSWORD 129 | STRING 130 | 131 | 132 | CORRNR 133 | '' 134 | X 135 | TRKORR 136 | 137 | 138 | 139 | 140 | RETURN 141 | BAPIRET2 142 | 143 | 144 | 145 | 146 | ABAP_PACKAGE 147 | P 148 | 149 | 150 | GIT_USER 151 | P 152 | 153 | 154 | GIT_PASSWORD 155 | P 156 | 157 | 158 | CORRNR 159 | P 160 | 161 | 162 | RETURN 163 | P 164 | 165 | 166 | 167 | 168 | ZABAPGIT_API_RFC_SWITCHBRANCH 169 | R 170 | abapGit RFC checking out branch in a repo with a package 171 | 172 | 173 | ABAP_PACKAGE 174 | DEVCLASS 175 | 176 | 177 | BRANCH_NAME 178 | 'master' 179 | X 180 | STRING 181 | 182 | 183 | GIT_USER 184 | STRING 185 | 186 | 187 | GIT_PASSWORD 188 | STRING 189 | 190 | 191 | 192 | 193 | RETURN 194 | BAPIRET2 195 | 196 | 197 | 198 | 199 | ABAP_PACKAGE 200 | P 201 | 202 | 203 | BRANCH_NAME 204 | P 205 | 206 | 207 | GIT_USER 208 | P 209 | 210 | 211 | GIT_PASSWORD 212 | P 213 | 214 | 215 | RETURN 216 | P 217 | 218 | 219 | 220 | 221 | ZABAPGIT_API_RFC_UNLINK 222 | R 223 | abapGit RFC unlinking a package from a remote git repo 224 | 225 | 226 | ABAP_PACKAGE 227 | DEVCLASS 228 | 229 | 230 | 231 | 232 | RETURN 233 | BAPIRET2 234 | 235 | 236 | 237 | 238 | ABAP_PACKAGE 239 | P 240 | 241 | 242 | RETURN 243 | P 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.zabapgit_api_rfc_link.abap: -------------------------------------------------------------------------------- 1 | FUNCTION zabapgit_api_rfc_link. 2 | *"-------------------------------------------------------------------- 3 | *"*"Local Interface: 4 | *" IMPORTING 5 | *" VALUE(ABAP_PACKAGE) TYPE DEVCLASS DEFAULT '' 6 | *" VALUE(GIT_REPO_URL) TYPE STRING 7 | *" VALUE(GIT_USER) TYPE STRING 8 | *" VALUE(GIT_PASSWORD) TYPE STRING 9 | *" VALUE(BRANCH) TYPE STRING DEFAULT '' 10 | *" VALUE(FOLDER_LOGIC) TYPE STRING DEFAULT 'PREFIX' 11 | *" VALUE(IGNORE_SUBPACKAGES) TYPE XFELD DEFAULT '' 12 | *" VALUE(MAIN_LANG_ONLY) TYPE XFELD DEFAULT '' 13 | *" VALUE(STARTING_FOLDER) TYPE STRING DEFAULT '/src/' 14 | *" TABLES 15 | *" RETURN STRUCTURE BAPIRET2 16 | *"-------------------------------------------------------------------- 17 | IF abap_package IS INITIAL. 18 | " https://github.com/abapgit/abapgit.git -> [ 'https:', '', 'github.com', 'abapgit', 'abapgit.git'] 19 | SPLIT git_repo_url AT '/' INTO TABLE DATA(url_parts). 20 | " [ 'https:', '', 'github.com', 'abapgit', 'abapgit.git'] -> 'abapgit.git' 21 | DATA(repo_name_url_part) = url_parts[ lines( url_parts ) ]. 22 | 23 | " 'abapgit.git' -> [ 'abapgit', 'git' ] 24 | SPLIT repo_name_url_part AT '.' INTO TABLE DATA(repo_name_parts). 25 | " [ 'abapgit', 'git' ] -> 'abapgit' 26 | abap_package = repo_name_parts[ 1 ]. 27 | 28 | " make sure we use UPPER CASE 29 | TRANSLATE abap_package TO UPPER CASE. 30 | 31 | SELECT COUNT( * ) FROM tdevc WHERE devclass = @abap_package INTO @DATA(found). 32 | 33 | IF found = 0. 34 | APPEND VALUE #( type = 'I' message = |Did not find package: { abap_package }| ) TO return. 35 | 36 | " Try adding prefix $ which is often used for local packages. 37 | " Repository name cannot start with $ but ABAP package can. 38 | abap_package = |${ abap_package }|. 39 | SELECT COUNT( * ) FROM tdevc WHERE devclass = @abap_package INTO @found. 40 | 41 | IF found = 0. 42 | APPEND VALUE #( type = 'I' message = |Did not find local package: { abap_package }| ) TO return. 43 | APPEND VALUE #( type = 'E' message = |Cannot deduce ABAP package from Repository name| ) TO return. 44 | RETURN. 45 | ENDIF. 46 | ENDIF. 47 | 48 | APPEND VALUE #( type = 'I' message = |Parsed ABAP Package name: { abap_package }| ) TO return. 49 | ENDIF. 50 | 51 | TRY. 52 | APPEND VALUE #( type = 'I' message = |Running migrations| ) TO return. 53 | zcl_abapgit_migrations=>run( ). 54 | 55 | APPEND VALUE #( type = 'I' message = |Setting credentials of { git_user } for { git_repo_url }| ) TO return. 56 | zcl_abapgit_login_manager=>set( 57 | iv_uri = git_repo_url 58 | iv_username = git_user 59 | iv_password = git_password ). 60 | 61 | APPEND VALUE #( type = 'I' message = |Linking { git_repo_url } with { abap_package }| ) TO return. 62 | DATA(repo) = zcl_abapgit_repo_srv=>get_instance( )->new_online( 63 | iv_url = git_repo_url 64 | iv_branch_name = branch 65 | iv_package = abap_package 66 | iv_folder_logic = folder_logic 67 | iv_ign_subpkg = ignore_subpackages 68 | iv_main_lang_only = main_lang_only ). 69 | 70 | APPEND VALUE #( type = 'I' message = |Changing Folder logic| ) TO return. 71 | repo->get_dot_abapgit( )->set_starting_folder( starting_folder ). 72 | 73 | APPEND VALUE #( type = 'I' message = |Done| ) TO return. 74 | CATCH zcx_abapgit_exception INTO DATA(ex). 75 | APPEND VALUE #( type = 'E' message = ex->if_message~get_text( ) ) TO return. 76 | ENDTRY. 77 | 78 | ENDFUNCTION. 79 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.zabapgit_api_rfc_pull.abap: -------------------------------------------------------------------------------- 1 | FUNCTION zabapgit_api_rfc_pull. 2 | *"-------------------------------------------------------------------- 3 | *"*"Local Interface: 4 | *" IMPORTING 5 | *" VALUE(ABAP_PACKAGE) TYPE DEVCLASS 6 | *" VALUE(GIT_USER) TYPE STRING 7 | *" VALUE(GIT_PASSWORD) TYPE STRING 8 | *" VALUE(CORRNR) TYPE TRKORR DEFAULT '' 9 | *" TABLES 10 | *" RETURN STRUCTURE BAPIRET2 11 | *"-------------------------------------------------------------------- 12 | TRY. 13 | APPEND VALUE #( type = 'I' message = 'Run migration' ) TO return. 14 | zcl_abapgit_migrations=>run( ). 15 | 16 | APPEND VALUE #( type = 'I' message = |Find repo for package { abap_package }| ) TO return. 17 | zcl_abapgit_repo_srv=>get_instance( )->get_repo_from_package( 18 | EXPORTING 19 | iv_package = abap_package 20 | IMPORTING 21 | ei_repo = DATA(repo) ). 22 | 23 | IF repo IS INITIAL. 24 | zcx_abapgit_exception=>raise( |Unable to find repo for package { abap_package }! | ). 25 | ENDIF. 26 | 27 | APPEND VALUE #( type = 'I' message = |Setting credentials of { git_user } for { repo->ms_data-url }| ) TO return. 28 | zcl_abapgit_login_manager=>set( 29 | iv_uri = repo->ms_data-url 30 | iv_username = git_user 31 | iv_password = git_password ). 32 | 33 | APPEND VALUE #( type = 'I' message = |Deserialize checks| ) TO return. 34 | DATA(checks) = repo->deserialize_checks( ). 35 | 36 | APPEND VALUE #( type = 'I' message = |Overwrite| ) TO return. 37 | LOOP AT checks-overwrite ASSIGNING FIELD-SYMBOL(). 38 | " object has been modified locally 39 | " decision field must be filled with Y or N. Y overwrites the object 40 | -decision = zif_abapgit_definitions=>c_yes. 41 | ENDLOOP. 42 | 43 | APPEND VALUE #( type = 'I' message = |Correct packages| ) TO return. 44 | LOOP AT checks-warning_package ASSIGNING FIELD-SYMBOL(). 45 | " Y or N if object from unexpected package should be overwritten 46 | -decision = zif_abapgit_definitions=>c_yes. 47 | ENDLOOP. 48 | 49 | APPEND VALUE #( type = 'I' message = |Requirements| ) TO return. 50 | IF checks-requirements-met = zif_abapgit_definitions=>c_no. 51 | " code must decide if deserialization should continue or not 52 | checks-requirements-decision = zif_abapgit_definitions=>c_yes. 53 | ENDIF. 54 | 55 | APPEND VALUE #( type = 'I' message = |Transport| ) TO return. 56 | IF checks-transport-required = abap_true. 57 | checks-transport-transport = corrnr. 58 | ENDIF. 59 | 60 | APPEND VALUE #( type = 'I' message = |Log| ) TO return. 61 | DATA(log) = NEW zcl_abapgit_log( ). 62 | 63 | APPEND VALUE #( type = 'I' message = |Deserializing| ) TO return. 64 | repo->deserialize( 65 | is_checks = checks 66 | ii_log = log ). 67 | 68 | APPEND VALUE #( type = 'I' message = |Finished| ) TO return. 69 | CATCH zcx_abapgit_exception INTO DATA(err). 70 | APPEND VALUE #( type = 'E' message = err->if_message~get_text( ) ) TO return. 71 | ENDTRY. 72 | ENDFUNCTION. 73 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.zabapgit_api_rfc_switchbranch.abap: -------------------------------------------------------------------------------- 1 | FUNCTION zabapgit_api_rfc_switchbranch. 2 | *"-------------------------------------------------------------------- 3 | *"*"Local Interface: 4 | *" IMPORTING 5 | *" VALUE(ABAP_PACKAGE) TYPE DEVCLASS 6 | *" VALUE(BRANCH_NAME) TYPE STRING DEFAULT 'master' 7 | *" VALUE(GIT_USER) TYPE STRING 8 | *" VALUE(GIT_PASSWORD) TYPE STRING 9 | *" TABLES 10 | *" RETURN STRUCTURE BAPIRET2 11 | *"-------------------------------------------------------------------- 12 | TRY. 13 | APPEND VALUE #( type = 'I' message = 'Run migration' ) TO return. 14 | zcl_abapgit_migrations=>run( ). 15 | 16 | APPEND VALUE #( type = 'I' message = |Find repo for package { abap_package }| ) TO return. 17 | zcl_abapgit_repo_srv=>get_instance( )->get_repo_from_package( 18 | EXPORTING 19 | iv_package = abap_package 20 | IMPORTING 21 | ei_repo = DATA(repo) ). 22 | 23 | IF repo IS INITIAL. 24 | zcx_abapgit_exception=>raise( |Unable to find repo for package { abap_package }! | ). 25 | ENDIF. 26 | 27 | DATA(online_repo) = CAST zcl_abapgit_repo_online( repo ). 28 | DATA(url) = online_repo->get_url( ). 29 | 30 | APPEND VALUE #( type = 'I' message = |Setting credentials of { git_user } for { url }| ) TO return. 31 | zcl_abapgit_login_manager=>set( 32 | iv_uri = url 33 | iv_username = git_user 34 | iv_password = git_password ). 35 | 36 | APPEND VALUE #( type = 'I' message = |Checking out { branch_name } in { url }| ) TO return. 37 | 38 | IF substring( val = url 39 | off = strlen( url ) - 1 40 | len = 1 ) = '/'. 41 | url = substring( val = url 42 | off = 0 43 | len = strlen( url ) - 1 ). 44 | ENDIF. 45 | 46 | DATA(branch_list) = zcl_abapgit_git_transport=>branches( url ). 47 | DATA(branches) = branch_list->get_branches_only( ). 48 | 49 | IF strlen( branch_name ) < 5 OR NOT substring( val = branch_name 50 | off = 0 51 | len = 5 ) = 'refs/'. 52 | CONCATENATE 'refs/heads/' branch_name INTO branch_name. 53 | ENDIF. 54 | 55 | IF NOT line_exists( branches[ name = branch_name ] ). 56 | zcx_abapgit_exception=>raise( |Checkout failed: Branch { branch_name } does not exist! | ). 57 | ENDIF. 58 | 59 | online_repo->select_branch( branch_name ). 60 | 61 | APPEND VALUE #( type = 'I' message = |Finished| ) TO return. 62 | CATCH zcx_abapgit_exception INTO DATA(err). 63 | APPEND VALUE #( type = 'E' message = err->if_message~get_text( ) ) TO return. 64 | ENDTRY. 65 | ENDFUNCTION. 66 | -------------------------------------------------------------------------------- /src/zabapgit_api_rfc.fugr.zabapgit_api_rfc_unlink.abap: -------------------------------------------------------------------------------- 1 | FUNCTION zabapgit_api_rfc_unlink. 2 | *"-------------------------------------------------------------------- 3 | *"*"Local Interface: 4 | *" IMPORTING 5 | *" VALUE(ABAP_PACKAGE) TYPE DEVCLASS 6 | *" TABLES 7 | *" RETURN STRUCTURE BAPIRET2 8 | *"-------------------------------------------------------------------- 9 | TRY. 10 | APPEND VALUE #( type = 'I' message = |Running migrations| ) TO return. 11 | zcl_abapgit_migrations=>run( ). 12 | 13 | APPEND VALUE #( type = 'I' message = |Find repo for the package { abap_package }| ) TO return. 14 | zcl_abapgit_repo_srv=>get_instance( )->get_repo_from_package( 15 | EXPORTING 16 | iv_package = abap_package 17 | IMPORTING 18 | ei_repo = DATA(repo) ). 19 | 20 | IF repo IS INITIAL. 21 | zcx_abapgit_exception=>raise( |Unable to find repo for package { abap_package }! | ). 22 | ENDIF. 23 | 24 | APPEND VALUE #( type = 'I' message = |Unlinking the package { abap_package }| ) TO return. 25 | DATA(repo_svc) = zcl_abapgit_repo_srv=>get_instance( ). 26 | repo_svc->delete( repo ). 27 | 28 | APPEND VALUE #( type = 'I' message = |Done| ) TO return. 29 | CATCH zcx_abapgit_exception INTO DATA(ex). 30 | APPEND VALUE #( type = 'E' message = ex->if_message~get_text( ) ) TO return. 31 | ENDTRY. 32 | 33 | ENDFUNCTION. 34 | --------------------------------------------------------------------------------