├── .gitignore ├── LICENSE ├── README.md ├── composer.json └── src ├── Adamgoose └── Gitlab │ ├── Client.php │ ├── GitlabServiceProvider.php │ └── Models │ ├── BaseModel.php │ ├── Blob.php │ ├── Branch.php │ ├── Commit.php │ ├── Diff.php │ ├── Event.php │ ├── Group.php │ ├── Hook.php │ ├── Issue.php │ ├── Key.php │ ├── MergeRequest.php │ ├── Milestone.php │ ├── Note.php │ ├── Project.php │ ├── Snippet.php │ ├── Tag.php │ ├── Tree.php │ └── User.php └── config └── config.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /documentor 3 | composer.phar 4 | composer.lock 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Adam Engebretson 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 13 | all 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 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel API Wrapper for GitLab CE 2 | 3 | [GitLab](http://gitlab.org) offers git repository management, code reviews, issue tracking, activity feeds and wiki’s. Enterprises install GitLab on-premise and connect it with LDAP and Active Directory servers for secure authentication and authorization. A single GitLab server can handle more than 25,000 users but it is also possible to create a high availability setup with a multiple active servers. 4 | 5 | This Laravel API Wrapper allows users to plug into their own GitLab Instance's API seamlessly and in an Eloquent-like manner. 6 | 7 | API Documentation can be viewed [here](http://adamgoose.github.io/gitlab/master/), or for the develop branch [here](http://adamgoose.github.io/gitlab/develop/). 8 | 9 | - [Installation](#installation) 10 | - [Namespacing & Aliases](#namespacing) 11 | - [Usage](#usage) 12 | - [GitLab CE API](#api) 13 | - [Todo](#todo) 14 | 15 | 16 | ## Installation 17 | 18 | Add `adamgoose/gitlab` to your `composer.json` file. 19 | 20 | "require": { 21 | "laravel/framework": "4.1.*", 22 | ... 23 | "adamgoose/gitlab": "dev-master" 24 | }, 25 | 26 | Next, register the `GitlabServiceProvider` in `app/config/app.php`'s `providers` array: 27 | 28 | 'providers' => array( 29 | ... 30 | 'Adamgoose\Gitlab\GitlabServiceProvider', 31 | ), 32 | 33 | Finally, you'll need to configure the API Wrapper to access your instance. Just run the following command, then update the file found at `app/config/packages/adamgoose/gitlab/config.php`. 34 | 35 | php artisan config:publish adamgoose/gitlab 36 | 37 | Detailed information about the config settings can be found in the config file's comments. 38 | 39 | 40 | ## Namespacing & Aliases 41 | 42 | Since the API Wrapper uses an Eloquent Model-like synax, it may be useful to access some of the classes statically from the root namespace. Because of this, we have aliased all of the classes according to the default settings in the config file. You are free to change these however you wish, but use caution with common model names, such as `User`, to avoid conflict with your Eloquent models. 43 | 44 | As of now, the config file is the only source of these aliases. Thus, any classes or models that are added to the package in the future will not be aliased automatically. I will do my best to make reference to any updates that should be made to this array in the changelog. 45 | 46 | 47 | ## Usage 48 | 49 | Traversing through the API is quite simple. Eloquent users (which should be all of you!) should be quite familiar with this type of syntax. 50 | 51 | Since the majority of the API is centered around Projects, most of your API calls will be originated from the Project model. To find a project, simply use the `find($id)` method on the `Project` model. 52 | 53 | $project = Gitlab\Project::find(1); 54 | 55 | > *Note:* This documentation will use the default model aliases configured in the config file. However, if you have updated any of these aliases, you'll need to adjust the examples accordingly. See the [Namespacing & Aliases](#namespacing) section of this document. 56 | 57 | Casting the Project model to a string (or echoing it) will return a JSON object of all of the information provided by the [GitLab CE API](#api). 58 | 59 | From here, you can also obtain several of the relations associated with a Project. 60 | 61 | $events = $project->events; 62 | $members = $project->members; 63 | $hooks = $project->hooks; 64 | $branches = $project->branches; 65 | $tags = $project->tags; 66 | $tree = $project->tree; 67 | $commits = $project->commits; 68 | $snippets = $project->snippets; 69 | $keys = $project->keys; 70 | $issues = $project->issues; 71 | $milestones = $project->milestones; 72 | $merge_requests = $project->merge_requests; 73 | 74 | Each of these particular calls will return instances of [`Illuminate\Support\Collection`](https://github.com/laravel/framework/blob/4.1/src/Illuminate/Support/Collection.php) populated with te respective models. 75 | 76 | > *Note:* If you feel the urge to call these as methods, by all means. i.e. `$project->events()`. 77 | 78 | Many of these models are available for a single-fetch. 79 | 80 | $member = $project->member($id); 81 | $hook = $project->hook($id); 82 | $branch = $project->branch($name); 83 | $commit = $project->commit($sha); 84 | $snippet = $project->snippet($id); 85 | $key = $project->key($id); 86 | $issue = $project->issue($id); // Note that the $id passed to the issue() method is the global ID, not the project-specific ID that is presented to you in the web version 87 | $milestone = $project->milestone($id); 88 | $merge_request = $project->merge_request($id); 89 | 90 | These calls will return instances of the respective models. 91 | 92 | More documentation about each of these models will be availble in the Wiki of this repository (eventually). 93 | 94 | 95 | ## GitLab CE API 96 | 97 | The GitLab API documentation can be dound at [http://doc.gitlab.com/ce/api/README.html](http://doc.gitlab.com/ce/api/README.html), or by browsing to `/help/api/README` on your personal GitLab instance. 98 | 99 | 100 | ## Todo (before 1.0) 101 | 102 | > This list is NOT prioritized. 103 | 104 | - Enable recursive tree browsing 105 | - Enable file downloads 106 | - Enable archive downloads 107 | - Create 108 | - Update 109 | - Delete 110 | - Render API Documentation 111 | - Add Exceptions 112 | - Tests? -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "adamgoose/gitlab", 3 | "description": "Laravel API Wrapper for GitLab CE", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Adam Engebretson", 8 | "email": "adam@enge.me" 9 | } 10 | ], 11 | "require": { 12 | "php": ">=5.4.0", 13 | "illuminate/support": "4.1.*", 14 | "guzzlehttp/guzzle": "~4.0" 15 | }, 16 | "autoload": { 17 | "psr-0": { 18 | "Adamgoose\\Gitlab": "src/" 19 | } 20 | }, 21 | "minimum-stability": "stable" 22 | } 23 | -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Client.php: -------------------------------------------------------------------------------- 1 | api instanceof Http)) 24 | $this->setupHttpClient(); 25 | 26 | return $this->api->get($path, ['query' => $query])->json(); 27 | } 28 | 29 | /** 30 | * Instantiate HTTP Client 31 | * @return void 32 | */ 33 | private function setupHttpClient() 34 | { 35 | $this->api = new Http([ 36 | 'base_url' => [ 37 | 'http'.(Config::get('gitlab::secure') ? 's' : '').'://'.Config::get('gitlab::hostname').'/api/{version}/', 38 | [ 39 | 'version' => Config::get('gitlab::api_version') 40 | ] 41 | ], 42 | 'defaults' => [ 43 | 'query' => ['private_token' => Config::get('gitlab::private_token')], 44 | ], 45 | ]); 46 | } 47 | 48 | /** 49 | * Get filled model 50 | * @param string $model Which model to instantiate 51 | * @param array $attributes Generally, API response 52 | * @return BaseModel 53 | */ 54 | public function getModel($model, $attributes) 55 | { 56 | $model = 'Adamgoose\Gitlab\Models\\'.studly_case($model); 57 | 58 | return new $model($attributes, $this); 59 | } 60 | 61 | /** 62 | * Get a collection of filled models 63 | * @param string $model Which model to instantiate 64 | * @param array $instances Generally, API response 65 | * @return Collection 66 | */ 67 | public function getModels($model, $instances) 68 | { 69 | $collection = new Collection; 70 | 71 | foreach($instances as $instance) 72 | $collection->push($this->getModel($model, $instance)); 73 | 74 | return $collection; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/GitlabServiceProvider.php: -------------------------------------------------------------------------------- 1 | package('adamgoose/gitlab'); 33 | 34 | $aliases = $this->app['config']->get('gitlab::aliases'); 35 | 36 | foreach($aliases as $alias => $target) 37 | AliasLoader::getInstance()->alias($alias, $target); 38 | } 39 | 40 | /** 41 | * Get the services provided by the provider. 42 | * 43 | * @return array 44 | */ 45 | public function provides() 46 | { 47 | return array(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/BaseModel.php: -------------------------------------------------------------------------------- 1 | attributes = $attributes; 30 | $this->parent = $parent; 31 | } 32 | 33 | /** 34 | * Lookup by ID 35 | * @param int $id ID of desired model 36 | * @return BaseModel Model Instance 37 | */ 38 | public static function find($id) 39 | { 40 | $model = 'Adamgoose\Gitlab\Models\\'.class_basename(get_called_class()); 41 | 42 | return new $model(with(new Client)->fetch($model::$path.$id)); 43 | } 44 | 45 | /** 46 | * Get Parent 47 | * @return BaseModel Parent Model 48 | */ 49 | public function getParent() 50 | { 51 | return $this->parent; 52 | } 53 | 54 | /** 55 | * Dynamically Get Attributes 56 | * @param string $property Desired Attribute 57 | * @return mixed 58 | */ 59 | public function __get($property) 60 | { 61 | if(method_exists($this, $property)) { 62 | $method = new ReflectionMethod(get_called_class(), $property); 63 | if($method->getNumberOfParameters() == 0) 64 | return call_user_func([$this, $property]); 65 | } 66 | 67 | if(array_key_exists($property, $this->attributes)) 68 | return $this->attributes[$property]; 69 | 70 | return null; 71 | } 72 | 73 | /** 74 | * Cast Attributes to JSON 75 | * @param integer $options Options 76 | * @return string JSON Encoded Model 77 | */ 78 | public function toJson($options = 0) 79 | { 80 | return json_encode($this->attributes, $options); 81 | } 82 | 83 | /** 84 | * Cast Attributes to String (JSON) 85 | * @return string JSON Encoded Model 86 | */ 87 | public function __toString() 88 | { 89 | return $this->toJson(); 90 | } 91 | 92 | /** 93 | * Cast Attributes to Array 94 | * @return array Attributes 95 | */ 96 | public function toArray() 97 | { 98 | return $this->attributes; 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Blob.php: -------------------------------------------------------------------------------- 1 | getParent(); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Commit.php: -------------------------------------------------------------------------------- 1 | getParent(); 12 | } 13 | 14 | /** 15 | * Diff 16 | * @return Diff 17 | */ 18 | public function diff() 19 | { 20 | return $this->getModels('diff', $this->fetch('projects/'.$this->project->id.'/repository/commits/'.$this->id.'/diff')); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Diff.php: -------------------------------------------------------------------------------- 1 | getParent(); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Event.php: -------------------------------------------------------------------------------- 1 | getModels('user', $this->fetch('groups/'.$this->id.'/members')); 20 | } 21 | 22 | /** 23 | * Projects 24 | * @return Collection of Project objects 25 | */ 26 | public function projects() 27 | { 28 | $collection = new Collection; 29 | 30 | foreach($this->attributes['projects'] as $project) 31 | $collection->push($this->getModel('project', $project)); 32 | 33 | return $collection; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Hook.php: -------------------------------------------------------------------------------- 1 | getParent(); 12 | } 13 | 14 | /** 15 | * Comments 16 | * @return Collection of Note objects 17 | */ 18 | public function comments() 19 | { 20 | return $this->getModels('note', $this->fetch('projects/'.$this->project->id.'/issues/'.$this->id.'/notes')); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Key.php: -------------------------------------------------------------------------------- 1 | getParent(); 12 | } 13 | 14 | /** 15 | * From 16 | * @return Branch 17 | */ 18 | public function from() 19 | { 20 | return $this->getModel('branch', $this->fetch('projects/'.$this->project->id.'/repository/branches/'.$this->source_branch)); 21 | } 22 | 23 | /** 24 | * To 25 | * @return Branch 26 | */ 27 | public function to() 28 | { 29 | return $this->getModel('branch', $this->fetch('projects/'.$this->project->id.'/repository/branches/'.$this->target_branch)); 30 | } 31 | 32 | /** 33 | * Notes 34 | * @return Collection of Note objects 35 | */ 36 | public function notes() 37 | { 38 | return $this->getModels('note', $this->fetch('projects/'.$this->project->id.'/merge_requests/'.$this->id.'/notes')); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Milestone.php: -------------------------------------------------------------------------------- 1 | getModels('event', $this->fetch('projects/'.$this->id.'/events')); 21 | } 22 | 23 | /** 24 | * Members 25 | * @return Collection of Member objects 26 | */ 27 | public function members() 28 | { 29 | return $this->getModels('user', $this->fetch('projects/'.$this->id.'/members')); 30 | } 31 | 32 | /** 33 | * Member 34 | * @param int $id 35 | * @return Member 36 | */ 37 | public function member($id) 38 | { 39 | return $this->getModel('user', $this->fetch('projects/'.$this->id.'/members/'.$id)); 40 | } 41 | 42 | /** 43 | * Hooks 44 | * @return Collection of Hook objects 45 | */ 46 | public function hooks() 47 | { 48 | return $this->getModels('hook', $this->fetch('projects/'.$this->id.'/hooks')); 49 | } 50 | 51 | /** 52 | * Hook 53 | * @param int $id 54 | * @return Hook 55 | */ 56 | public function hook($id) 57 | { 58 | return $this->getModel('hook', $this->fetch('projects/'.$this->id.'/hooks/'.$id)); 59 | } 60 | 61 | /** 62 | * Branches 63 | * @return Collection of Branch objects 64 | */ 65 | public function branches() 66 | { 67 | return $this->getModels('branch', $this->fetch('projects/'.$this->id.'/repository/branches')); 68 | } 69 | 70 | /** 71 | * Branch 72 | * @param string $name 73 | * @return Branch 74 | */ 75 | public function branch($name) 76 | { 77 | return $this->getModel('branch', $this->fetch('projects/'.$this->id.'/repository/branches/'.$name)); 78 | } 79 | 80 | /** 81 | * Tags 82 | * @return Collection of Tag objects 83 | */ 84 | public function tags() 85 | { 86 | return $this->getModels('tag', $this->fetch('projects/'.$this->id.'/repository/tags')); 87 | } 88 | 89 | /** 90 | * Tree 91 | * @return Collection of Blob and Tree objects 92 | */ 93 | public function tree() 94 | { 95 | $collection = new Collection; 96 | 97 | foreach($this->fetch('projects/'.$this->id.'/repository/tree') as $asset) 98 | $collection->push($this->getModel($asset['type'], $asset)); 99 | 100 | return $collection; 101 | } 102 | 103 | /** 104 | * Commits 105 | * @return Collection of Commit objects 106 | */ 107 | public function commits() 108 | { 109 | return $this->getModels('commit', $this->fetch('projects/'.$this->id.'/repository/commits')); 110 | } 111 | 112 | /** 113 | * Commit 114 | * @param string $sha 115 | * @return Commit 116 | */ 117 | public function commit($sha) 118 | { 119 | return $this->getModel('commit', $this->fetch('projects/'.$this->id.'/repository/commits/'.$sha)); 120 | } 121 | 122 | /** 123 | * Snippets 124 | * @return Collection of Snippet objects 125 | */ 126 | public function snippets() 127 | { 128 | return $this->getModels('snippet', $this->fetch('projects/'.$this->id.'/snippets')); 129 | } 130 | 131 | /** 132 | * Snippet 133 | * @param int $id 134 | * @return Snippet 135 | */ 136 | public function snippet($id) 137 | { 138 | return $this->getModel('snippet', $this->fetch('projects/'.$this->id.'/snippets/'.$id)); 139 | } 140 | 141 | /** 142 | * Keys 143 | * @return Collection of Key objects 144 | */ 145 | public function keys() 146 | { 147 | return $this->getModels('key', $this->fetch('projects/'.$this->id.'/keys')); 148 | } 149 | 150 | /** 151 | * Key 152 | * @param int $id 153 | * @return Key 154 | */ 155 | public function key($id) 156 | { 157 | return $this->getModel('key', $this->fetch('projects/'.$this->id.'/keys/'.$id)); 158 | } 159 | 160 | /** 161 | * Issues 162 | * @return Collection of Issue objects 163 | */ 164 | public function issues() 165 | { 166 | return $this->getModels('issue', $this->fetch('projects/'.$this->id.'/issues')); 167 | } 168 | 169 | /** 170 | * Issue 171 | * @param int $id Global ID, not relative ID 172 | * @return Issue 173 | */ 174 | public function issue($id) 175 | { 176 | return $this->getModel('issue', $this->fetch('projects/'.$this->id.'/issues/'.$id)); 177 | } 178 | 179 | /** 180 | * Milestones 181 | * @return Collection of Milestone objects 182 | */ 183 | public function milestones() 184 | { 185 | return $this->getModels('milestone', $this->fetch('projects/'.$this->id.'/milestones')); 186 | } 187 | 188 | /** 189 | * Milestone 190 | * @param int $id 191 | * @return Milestone 192 | */ 193 | public function milestone($id) 194 | { 195 | return $this->getModel('milestone', $this->fetch('projects/'.$this->id.'/milestones/'.$id)); 196 | } 197 | 198 | /** 199 | * Merge Requests 200 | * @return Collection of MergeRequest objects 201 | */ 202 | public function merge_requests() 203 | { 204 | return $this->getModels('merge_request', $this->fetch('projects/'.$this->id.'/merge_requests')); 205 | } 206 | 207 | /** 208 | * Merge Request 209 | * @param int $id 210 | * @return MergeRequest 211 | */ 212 | public function merge_request($id) 213 | { 214 | return $this->getModel('merge_request', $this->fetch('projects/'.$this->id.'/merge_requests/'.$id)); 215 | } 216 | 217 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/Snippet.php: -------------------------------------------------------------------------------- 1 | getParent(); 14 | } 15 | 16 | /** 17 | * Tree 18 | * @return Collection of Blob and Tree objects 19 | */ 20 | public function tree() 21 | { 22 | $collection = new Collection; 23 | 24 | foreach($this->fetch('projects/'.$this->project->id.'/repository/tree', ['path' => $this->name]) as $asset) 25 | $collection->push($this->getModel($asset['type'], $asset)); 26 | 27 | return $collection; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/Adamgoose/Gitlab/Models/User.php: -------------------------------------------------------------------------------- 1 | 'YOUR_GITLAB_HOSTNAME', 16 | 17 | /* 18 | |-------------------------------------------------------------------------- 19 | | Use SSL 20 | |-------------------------------------------------------------------------- 21 | | 22 | | Depending on whether or not you have an SSL certificate installed 23 | | on your GitLab CE server, we need to access the API via either 24 | | http or https. Enter true to use https or false to use http 25 | | 26 | */ 27 | 'secure' => true, 28 | 29 | /* 30 | |-------------------------------------------------------------------------- 31 | | API Version 32 | |-------------------------------------------------------------------------- 33 | | 34 | | Your GitLab CE instance's API version can be revealed by 35 | | browsing to https://git.example.com/admin/. Enter the 36 | | proper API version here so we access the right API 37 | | 38 | */ 39 | 'api_version' => 'v3', 40 | 41 | /* 42 | |-------------------------------------------------------------------------- 43 | | Private Token 44 | |-------------------------------------------------------------------------- 45 | | 46 | | The GitLab API requires authentication by way of a private token in 47 | | order to access the API. A token can be generated by browsing to 48 | | https://git.example.com/profile/account when you're logged in 49 | | 50 | */ 51 | 'private_token' => 'YOUR_PRIVATE_TOKEN', 52 | 53 | /* 54 | |-------------------------------------------------------------------------- 55 | | Class Aliases 56 | |-------------------------------------------------------------------------- 57 | | 58 | | Since the API's classes have a long and annoying namespace, and since 59 | | you probably don't want to manually alias each all these yourself, 60 | | I've done it here, and made it simple for you to customize them 61 | | 62 | */ 63 | 'aliases' => [ 64 | // Alias (change) => Target (don't change) 65 | 'Gitlab' => 'Adamgoose\Gitlab\Client', 66 | 'Gitlab\Blob' => 'Adamgoose\Gitlab\Models\Blob', 67 | 'Gitlab\Branch' => 'Adamgoose\Gitlab\Models\Branch', 68 | 'Gitlab\Commit' => 'Adamgoose\Gitlab\Models\Commit', 69 | 'Gitlab\Diff' => 'Adamgoose\Gitlab\Models\Diff', 70 | 'Gitlab\Event' => 'Adamgoose\Gitlab\Models\Event', 71 | 'Gitlab\Group' => 'Adamgoose\Gitlab\Models\Group', 72 | 'Gitlab\Hook' => 'Adamgoose\Gitlab\Models\Hook', 73 | 'Gitlab\Issue' => 'Adamgoose\Gitlab\Models\Issue', 74 | 'Gitlab\Key' => 'Adamgoose\Gitlab\Models\Key', 75 | 'Gitlab\MergeRequest' => 'Adamgoose\Gitlab\Models\MergeRequest', 76 | 'Gitlab\Milestone' => 'Adamgoose\Gitlab\Models\Milestone', 77 | 'Gitlab\Note' => 'Adamgoose\Gitlab\Models\Note', 78 | 'Gitlab\Project' => 'Adamgoose\Gitlab\Models\Project', 79 | 'Gitlab\Snippet' => 'Adamgoose\Gitlab\Models\Snippet', 80 | 'Gitlab\Tag' => 'Adamgoose\Gitlab\Models\Tag', 81 | 'Gitlab\Tree' => 'Adamgoose\Gitlab\Models\Tree', 82 | 'Gitlab\User' => 'Adamgoose\Gitlab\Models\User', 83 | ], 84 | ]; --------------------------------------------------------------------------------