Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 1 | #ifndef BUNDLE_URI_H |
| 2 | #define BUNDLE_URI_H |
| 3 | |
Derrick Stolee | 0634f71 | 2022-10-12 12:52:29 +0000 | [diff] [blame] | 4 | #include "hashmap.h" |
| 5 | #include "strbuf.h" |
| 6 | |
Ævar Arnfjörð Bjarmason | 8b8d9a2 | 2022-12-22 15:14:07 +0000 | [diff] [blame] | 7 | struct packet_reader; |
Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 8 | struct repository; |
Derrick Stolee | 0634f71 | 2022-10-12 12:52:29 +0000 | [diff] [blame] | 9 | struct string_list; |
| 10 | |
| 11 | /** |
| 12 | * The remote_bundle_info struct contains information for a single bundle |
| 13 | * URI. This may be initialized simply by a given URI or might have |
| 14 | * additional metadata associated with it if the bundle was advertised by |
| 15 | * a bundle list. |
| 16 | */ |
| 17 | struct remote_bundle_info { |
| 18 | struct hashmap_entry ent; |
| 19 | |
| 20 | /** |
| 21 | * The 'id' is a name given to the bundle for reference |
| 22 | * by other bundle infos. |
| 23 | */ |
| 24 | char *id; |
| 25 | |
| 26 | /** |
| 27 | * The 'uri' is the location of the remote bundle so |
| 28 | * it can be downloaded on-demand. This will be NULL |
| 29 | * if there was no table of contents. |
| 30 | */ |
| 31 | char *uri; |
Derrick Stolee | c23f592 | 2022-10-12 12:52:36 +0000 | [diff] [blame] | 32 | |
| 33 | /** |
| 34 | * If the bundle has been downloaded, then 'file' is a |
| 35 | * filename storing its contents. Otherwise, 'file' is |
| 36 | * NULL. |
| 37 | */ |
| 38 | char *file; |
| 39 | |
| 40 | /** |
| 41 | * If the bundle has been unbundled successfully, then |
| 42 | * this boolean is true. |
| 43 | */ |
| 44 | unsigned unbundled:1; |
Derrick Stolee | 512fccf | 2023-01-31 13:29:13 +0000 | [diff] [blame] | 45 | |
| 46 | /** |
| 47 | * If the bundle is part of a list with the creationToken |
| 48 | * heuristic, then we use this member for sorting the bundles. |
| 49 | */ |
| 50 | uint64_t creationToken; |
Derrick Stolee | 0634f71 | 2022-10-12 12:52:29 +0000 | [diff] [blame] | 51 | }; |
| 52 | |
| 53 | #define REMOTE_BUNDLE_INFO_INIT { 0 } |
| 54 | |
| 55 | enum bundle_list_mode { |
| 56 | BUNDLE_MODE_NONE = 0, |
| 57 | BUNDLE_MODE_ALL, |
| 58 | BUNDLE_MODE_ANY |
| 59 | }; |
| 60 | |
Derrick Stolee | c93c3d2 | 2023-01-31 13:29:12 +0000 | [diff] [blame] | 61 | enum bundle_list_heuristic { |
| 62 | BUNDLE_HEURISTIC_NONE = 0, |
| 63 | BUNDLE_HEURISTIC_CREATIONTOKEN, |
| 64 | |
| 65 | /* Must be last. */ |
| 66 | BUNDLE_HEURISTIC__COUNT |
| 67 | }; |
| 68 | |
Derrick Stolee | 0634f71 | 2022-10-12 12:52:29 +0000 | [diff] [blame] | 69 | /** |
| 70 | * A bundle_list contains an unordered set of remote_bundle_info structs, |
| 71 | * as well as information about the bundle listing, such as version and |
| 72 | * mode. |
| 73 | */ |
| 74 | struct bundle_list { |
| 75 | int version; |
| 76 | enum bundle_list_mode mode; |
| 77 | struct hashmap bundles; |
Derrick Stolee | ebc3947 | 2022-12-22 15:14:15 +0000 | [diff] [blame] | 78 | |
| 79 | /** |
| 80 | * The baseURI of a bundle_list is the URI that provided the list. |
| 81 | * |
| 82 | * In the case of the 'bundle-uri' protocol v2 command, the base |
| 83 | * URI is the URI of the Git remote. |
| 84 | * |
| 85 | * Otherwise, the bundle list was downloaded over HTTP from some |
| 86 | * known URI. 'baseURI' is set to that value. |
| 87 | * |
| 88 | * The baseURI is used as the base for any relative URIs |
| 89 | * advertised by the bundle list at that location. |
| 90 | */ |
| 91 | char *baseURI; |
Derrick Stolee | c93c3d2 | 2023-01-31 13:29:12 +0000 | [diff] [blame] | 92 | |
| 93 | /** |
| 94 | * A list can have a heuristic, which helps reduce the number of |
| 95 | * downloaded bundles. |
| 96 | */ |
| 97 | enum bundle_list_heuristic heuristic; |
Derrick Stolee | 0634f71 | 2022-10-12 12:52:29 +0000 | [diff] [blame] | 98 | }; |
| 99 | |
| 100 | void init_bundle_list(struct bundle_list *list); |
| 101 | void clear_bundle_list(struct bundle_list *list); |
| 102 | |
| 103 | typedef int (*bundle_iterator)(struct remote_bundle_info *bundle, |
| 104 | void *data); |
| 105 | |
| 106 | int for_all_bundles_in_list(struct bundle_list *list, |
| 107 | bundle_iterator iter, |
| 108 | void *data); |
Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 109 | |
Ævar Arnfjörð Bjarmason | d796ced | 2022-10-12 12:52:32 +0000 | [diff] [blame] | 110 | struct FILE; |
| 111 | void print_bundle_list(FILE *fp, struct bundle_list *list); |
| 112 | |
Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 113 | /** |
Derrick Stolee | 738e524 | 2022-10-12 12:52:33 +0000 | [diff] [blame] | 114 | * A bundle URI may point to a bundle list where the key=value |
| 115 | * pairs are provided in config file format. This method is |
| 116 | * exposed publicly for testing purposes. |
| 117 | */ |
| 118 | int bundle_uri_parse_config_format(const char *uri, |
| 119 | const char *filename, |
| 120 | struct bundle_list *list); |
| 121 | |
| 122 | /** |
Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 123 | * Fetch data from the given 'uri' and unbundle the bundle data found |
| 124 | * based on that information. |
| 125 | * |
| 126 | * Returns non-zero if no bundle information is found at the given 'uri'. |
Derrick Stolee | 4074d3c | 2023-01-31 13:29:15 +0000 | [diff] [blame] | 127 | * |
| 128 | * If the pointer 'has_heuristic' is non-NULL, then the value it points to |
| 129 | * will be set to be non-zero if and only if the fetched list has a |
| 130 | * heuristic value. Such a value indicates that the list was designed for |
| 131 | * incremental fetches. |
Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 132 | */ |
Derrick Stolee | 4074d3c | 2023-01-31 13:29:15 +0000 | [diff] [blame] | 133 | int fetch_bundle_uri(struct repository *r, const char *uri, |
| 134 | int *has_heuristic); |
Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 135 | |
Ævar Arnfjörð Bjarmason | 9424e37 | 2022-10-12 12:52:31 +0000 | [diff] [blame] | 136 | /** |
Derrick Stolee | 12b0a14 | 2022-12-22 15:14:16 +0000 | [diff] [blame] | 137 | * Given a bundle list that was already advertised (likely by the |
| 138 | * bundle-uri protocol v2 verb) at the given uri, fetch and unbundle the |
| 139 | * bundles according to the bundle strategy of that list. |
| 140 | * |
| 141 | * It is expected that the given 'list' is initialized, including its |
| 142 | * 'baseURI' value. |
| 143 | * |
| 144 | * Returns non-zero if there was an error trying to download the list |
| 145 | * or any of its advertised bundles. |
| 146 | */ |
| 147 | int fetch_bundle_list(struct repository *r, |
| 148 | struct bundle_list *list); |
| 149 | |
| 150 | /** |
Ævar Arnfjörð Bjarmason | 8b8d9a2 | 2022-12-22 15:14:07 +0000 | [diff] [blame] | 151 | * API for serve.c. |
| 152 | */ |
| 153 | int bundle_uri_advertise(struct repository *r, struct strbuf *value); |
| 154 | int bundle_uri_command(struct repository *r, struct packet_reader *request); |
| 155 | |
| 156 | /** |
Ævar Arnfjörð Bjarmason | 9424e37 | 2022-10-12 12:52:31 +0000 | [diff] [blame] | 157 | * General API for {transport,connect}.c etc. |
| 158 | */ |
| 159 | |
| 160 | /** |
| 161 | * Parse a "key=value" packet line from the bundle-uri verb. |
| 162 | * |
| 163 | * Returns 0 on success and non-zero on error. |
| 164 | */ |
| 165 | int bundle_uri_parse_line(struct bundle_list *list, |
| 166 | const char *line); |
| 167 | |
Derrick Stolee | 53a5089 | 2022-08-09 13:11:40 +0000 | [diff] [blame] | 168 | #endif |