Create a new /templates API namespace
The /licenses, /gitignores and /gitlab_ci_ymls endpoints are now also available under a new /templates namespace. Old endpoints will be deprecated when GitLab 9.0.0 is released.
This commit is contained in:
parent
d3a9838065
commit
b9b13ea801
11 changed files with 996 additions and 266 deletions
|
@ -18,6 +18,7 @@ v 8.13.0 (unreleased)
|
|||
- Replaced the check sign to arrow in the show build view. !6501
|
||||
- Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar)
|
||||
- Fix Error 500 when viewing old merge requests with bad diff data
|
||||
- Create a new /templates namespace for the /licenses, /gitignores and /gitlab_ci_ymls API endpoints. !5717 (tbalthazar)
|
||||
- Speed-up group milestones show page
|
||||
- Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps)
|
||||
- Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs)
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
groupProjectsPath: "/api/:version/groups/:id/projects.json",
|
||||
projectsPath: "/api/:version/projects.json?simple=true",
|
||||
labelsPath: "/:namespace_path/:project_path/labels",
|
||||
licensePath: "/api/:version/licenses/:key",
|
||||
gitignorePath: "/api/:version/gitignores/:key",
|
||||
gitlabCiYmlPath: "/api/:version/gitlab_ci_ymls/:key",
|
||||
licensePath: "/api/:version/templates/licenses/:key",
|
||||
gitignorePath: "/api/:version/templates/gitignores/:key",
|
||||
gitlabCiYmlPath: "/api/:version/templates/gitlab_ci_ymls/:key",
|
||||
issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key",
|
||||
|
||||
group: function(group_id, callback) {
|
||||
var url = Api.buildUrl(Api.groupPath)
|
||||
.replace(':id', group_id);
|
||||
|
|
|
@ -17,6 +17,8 @@ following locations:
|
|||
- [Commits](commits.md)
|
||||
- [Deployments](deployments.md)
|
||||
- [Deploy Keys](deploy_keys.md)
|
||||
- [Gitignores templates](templates/gitignores.md)
|
||||
- [GitLab CI Config templates](templates/gitlab_ci_ymls.md)
|
||||
- [Groups](groups.md)
|
||||
- [Group Access Requests](access_requests.md)
|
||||
- [Group Members](members.md)
|
||||
|
@ -25,7 +27,7 @@ following locations:
|
|||
- [Labels](labels.md)
|
||||
- [Merge Requests](merge_requests.md)
|
||||
- [Milestones](milestones.md)
|
||||
- [Open source license templates](licenses.md)
|
||||
- [Open source license templates](templates/licenses.md)
|
||||
- [Namespaces](namespaces.md)
|
||||
- [Notes](notes.md) (comments)
|
||||
- [Notification settings](notification_settings.md)
|
||||
|
|
579
doc/api/templates/gitignores.md
Normal file
579
doc/api/templates/gitignores.md
Normal file
|
@ -0,0 +1,579 @@
|
|||
# Gitignores
|
||||
|
||||
## List gitignore templates
|
||||
|
||||
Get all gitignore templates.
|
||||
|
||||
```
|
||||
GET /templates/gitignores
|
||||
```
|
||||
|
||||
```bash
|
||||
curl https://gitlab.example.com/api/v3/templates/gitignores
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "AppEngine"
|
||||
},
|
||||
{
|
||||
"name": "Laravel"
|
||||
},
|
||||
{
|
||||
"name": "Elisp"
|
||||
},
|
||||
{
|
||||
"name": "SketchUp"
|
||||
},
|
||||
{
|
||||
"name": "Ada"
|
||||
},
|
||||
{
|
||||
"name": "Ruby"
|
||||
},
|
||||
{
|
||||
"name": "Kohana"
|
||||
},
|
||||
{
|
||||
"name": "Nanoc"
|
||||
},
|
||||
{
|
||||
"name": "Erlang"
|
||||
},
|
||||
{
|
||||
"name": "OCaml"
|
||||
},
|
||||
{
|
||||
"name": "Lithium"
|
||||
},
|
||||
{
|
||||
"name": "Fortran"
|
||||
},
|
||||
{
|
||||
"name": "Scala"
|
||||
},
|
||||
{
|
||||
"name": "Node"
|
||||
},
|
||||
{
|
||||
"name": "Fancy"
|
||||
},
|
||||
{
|
||||
"name": "Perl"
|
||||
},
|
||||
{
|
||||
"name": "Zephir"
|
||||
},
|
||||
{
|
||||
"name": "WordPress"
|
||||
},
|
||||
{
|
||||
"name": "Symfony"
|
||||
},
|
||||
{
|
||||
"name": "FuelPHP"
|
||||
},
|
||||
{
|
||||
"name": "DM"
|
||||
},
|
||||
{
|
||||
"name": "Sdcc"
|
||||
},
|
||||
{
|
||||
"name": "Rust"
|
||||
},
|
||||
{
|
||||
"name": "C"
|
||||
},
|
||||
{
|
||||
"name": "Umbraco"
|
||||
},
|
||||
{
|
||||
"name": "Actionscript"
|
||||
},
|
||||
{
|
||||
"name": "Android"
|
||||
},
|
||||
{
|
||||
"name": "Grails"
|
||||
},
|
||||
{
|
||||
"name": "Composer"
|
||||
},
|
||||
{
|
||||
"name": "ExpressionEngine"
|
||||
},
|
||||
{
|
||||
"name": "Gcov"
|
||||
},
|
||||
{
|
||||
"name": "Qt"
|
||||
},
|
||||
{
|
||||
"name": "Phalcon"
|
||||
},
|
||||
{
|
||||
"name": "ArchLinuxPackages"
|
||||
},
|
||||
{
|
||||
"name": "TeX"
|
||||
},
|
||||
{
|
||||
"name": "SCons"
|
||||
},
|
||||
{
|
||||
"name": "Lilypond"
|
||||
},
|
||||
{
|
||||
"name": "CommonLisp"
|
||||
},
|
||||
{
|
||||
"name": "Rails"
|
||||
},
|
||||
{
|
||||
"name": "Mercury"
|
||||
},
|
||||
{
|
||||
"name": "Magento"
|
||||
},
|
||||
{
|
||||
"name": "ChefCookbook"
|
||||
},
|
||||
{
|
||||
"name": "GitBook"
|
||||
},
|
||||
{
|
||||
"name": "C++"
|
||||
},
|
||||
{
|
||||
"name": "Eagle"
|
||||
},
|
||||
{
|
||||
"name": "Go"
|
||||
},
|
||||
{
|
||||
"name": "OpenCart"
|
||||
},
|
||||
{
|
||||
"name": "Scheme"
|
||||
},
|
||||
{
|
||||
"name": "Typo3"
|
||||
},
|
||||
{
|
||||
"name": "SeamGen"
|
||||
},
|
||||
{
|
||||
"name": "Swift"
|
||||
},
|
||||
{
|
||||
"name": "Elm"
|
||||
},
|
||||
{
|
||||
"name": "Unity"
|
||||
},
|
||||
{
|
||||
"name": "Agda"
|
||||
},
|
||||
{
|
||||
"name": "CUDA"
|
||||
},
|
||||
{
|
||||
"name": "VVVV"
|
||||
},
|
||||
{
|
||||
"name": "Finale"
|
||||
},
|
||||
{
|
||||
"name": "LemonStand"
|
||||
},
|
||||
{
|
||||
"name": "Textpattern"
|
||||
},
|
||||
{
|
||||
"name": "Julia"
|
||||
},
|
||||
{
|
||||
"name": "Packer"
|
||||
},
|
||||
{
|
||||
"name": "Scrivener"
|
||||
},
|
||||
{
|
||||
"name": "Dart"
|
||||
},
|
||||
{
|
||||
"name": "Plone"
|
||||
},
|
||||
{
|
||||
"name": "Jekyll"
|
||||
},
|
||||
{
|
||||
"name": "Xojo"
|
||||
},
|
||||
{
|
||||
"name": "LabVIEW"
|
||||
},
|
||||
{
|
||||
"name": "Autotools"
|
||||
},
|
||||
{
|
||||
"name": "KiCad"
|
||||
},
|
||||
{
|
||||
"name": "Prestashop"
|
||||
},
|
||||
{
|
||||
"name": "ROS"
|
||||
},
|
||||
{
|
||||
"name": "Smalltalk"
|
||||
},
|
||||
{
|
||||
"name": "GWT"
|
||||
},
|
||||
{
|
||||
"name": "OracleForms"
|
||||
},
|
||||
{
|
||||
"name": "SugarCRM"
|
||||
},
|
||||
{
|
||||
"name": "Nim"
|
||||
},
|
||||
{
|
||||
"name": "SymphonyCMS"
|
||||
},
|
||||
{
|
||||
"name": "Maven"
|
||||
},
|
||||
{
|
||||
"name": "CFWheels"
|
||||
},
|
||||
{
|
||||
"name": "Python"
|
||||
},
|
||||
{
|
||||
"name": "ZendFramework"
|
||||
},
|
||||
{
|
||||
"name": "CakePHP"
|
||||
},
|
||||
{
|
||||
"name": "Concrete5"
|
||||
},
|
||||
{
|
||||
"name": "PlayFramework"
|
||||
},
|
||||
{
|
||||
"name": "Terraform"
|
||||
},
|
||||
{
|
||||
"name": "Elixir"
|
||||
},
|
||||
{
|
||||
"name": "CMake"
|
||||
},
|
||||
{
|
||||
"name": "Joomla"
|
||||
},
|
||||
{
|
||||
"name": "Coq"
|
||||
},
|
||||
{
|
||||
"name": "Delphi"
|
||||
},
|
||||
{
|
||||
"name": "Haskell"
|
||||
},
|
||||
{
|
||||
"name": "Yii"
|
||||
},
|
||||
{
|
||||
"name": "Java"
|
||||
},
|
||||
{
|
||||
"name": "UnrealEngine"
|
||||
},
|
||||
{
|
||||
"name": "AppceleratorTitanium"
|
||||
},
|
||||
{
|
||||
"name": "CraftCMS"
|
||||
},
|
||||
{
|
||||
"name": "ForceDotCom"
|
||||
},
|
||||
{
|
||||
"name": "ExtJs"
|
||||
},
|
||||
{
|
||||
"name": "MetaProgrammingSystem"
|
||||
},
|
||||
{
|
||||
"name": "D"
|
||||
},
|
||||
{
|
||||
"name": "Objective-C"
|
||||
},
|
||||
{
|
||||
"name": "RhodesRhomobile"
|
||||
},
|
||||
{
|
||||
"name": "R"
|
||||
},
|
||||
{
|
||||
"name": "EPiServer"
|
||||
},
|
||||
{
|
||||
"name": "Yeoman"
|
||||
},
|
||||
{
|
||||
"name": "VisualStudio"
|
||||
},
|
||||
{
|
||||
"name": "Processing"
|
||||
},
|
||||
{
|
||||
"name": "Leiningen"
|
||||
},
|
||||
{
|
||||
"name": "Stella"
|
||||
},
|
||||
{
|
||||
"name": "Opa"
|
||||
},
|
||||
{
|
||||
"name": "Drupal"
|
||||
},
|
||||
{
|
||||
"name": "TurboGears2"
|
||||
},
|
||||
{
|
||||
"name": "Idris"
|
||||
},
|
||||
{
|
||||
"name": "Jboss"
|
||||
},
|
||||
{
|
||||
"name": "CodeIgniter"
|
||||
},
|
||||
{
|
||||
"name": "Qooxdoo"
|
||||
},
|
||||
{
|
||||
"name": "Waf"
|
||||
},
|
||||
{
|
||||
"name": "Sass"
|
||||
},
|
||||
{
|
||||
"name": "Lua"
|
||||
},
|
||||
{
|
||||
"name": "Clojure"
|
||||
},
|
||||
{
|
||||
"name": "IGORPro"
|
||||
},
|
||||
{
|
||||
"name": "Gradle"
|
||||
},
|
||||
{
|
||||
"name": "Archives"
|
||||
},
|
||||
{
|
||||
"name": "SynopsysVCS"
|
||||
},
|
||||
{
|
||||
"name": "Ninja"
|
||||
},
|
||||
{
|
||||
"name": "Tags"
|
||||
},
|
||||
{
|
||||
"name": "OSX"
|
||||
},
|
||||
{
|
||||
"name": "Dreamweaver"
|
||||
},
|
||||
{
|
||||
"name": "CodeKit"
|
||||
},
|
||||
{
|
||||
"name": "NotepadPP"
|
||||
},
|
||||
{
|
||||
"name": "VisualStudioCode"
|
||||
},
|
||||
{
|
||||
"name": "Mercurial"
|
||||
},
|
||||
{
|
||||
"name": "BricxCC"
|
||||
},
|
||||
{
|
||||
"name": "DartEditor"
|
||||
},
|
||||
{
|
||||
"name": "Eclipse"
|
||||
},
|
||||
{
|
||||
"name": "Cloud9"
|
||||
},
|
||||
{
|
||||
"name": "TortoiseGit"
|
||||
},
|
||||
{
|
||||
"name": "NetBeans"
|
||||
},
|
||||
{
|
||||
"name": "GPG"
|
||||
},
|
||||
{
|
||||
"name": "Espresso"
|
||||
},
|
||||
{
|
||||
"name": "Redcar"
|
||||
},
|
||||
{
|
||||
"name": "Xcode"
|
||||
},
|
||||
{
|
||||
"name": "Matlab"
|
||||
},
|
||||
{
|
||||
"name": "LyX"
|
||||
},
|
||||
{
|
||||
"name": "SlickEdit"
|
||||
},
|
||||
{
|
||||
"name": "Dropbox"
|
||||
},
|
||||
{
|
||||
"name": "CVS"
|
||||
},
|
||||
{
|
||||
"name": "Calabash"
|
||||
},
|
||||
{
|
||||
"name": "JDeveloper"
|
||||
},
|
||||
{
|
||||
"name": "Vagrant"
|
||||
},
|
||||
{
|
||||
"name": "IPythonNotebook"
|
||||
},
|
||||
{
|
||||
"name": "TextMate"
|
||||
},
|
||||
{
|
||||
"name": "Ensime"
|
||||
},
|
||||
{
|
||||
"name": "WebMethods"
|
||||
},
|
||||
{
|
||||
"name": "VirtualEnv"
|
||||
},
|
||||
{
|
||||
"name": "Emacs"
|
||||
},
|
||||
{
|
||||
"name": "Momentics"
|
||||
},
|
||||
{
|
||||
"name": "JetBrains"
|
||||
},
|
||||
{
|
||||
"name": "SublimeText"
|
||||
},
|
||||
{
|
||||
"name": "Kate"
|
||||
},
|
||||
{
|
||||
"name": "ModelSim"
|
||||
},
|
||||
{
|
||||
"name": "Redis"
|
||||
},
|
||||
{
|
||||
"name": "KDevelop4"
|
||||
},
|
||||
{
|
||||
"name": "Bazaar"
|
||||
},
|
||||
{
|
||||
"name": "Linux"
|
||||
},
|
||||
{
|
||||
"name": "Windows"
|
||||
},
|
||||
{
|
||||
"name": "XilinxISE"
|
||||
},
|
||||
{
|
||||
"name": "Lazarus"
|
||||
},
|
||||
{
|
||||
"name": "EiffelStudio"
|
||||
},
|
||||
{
|
||||
"name": "Anjuta"
|
||||
},
|
||||
{
|
||||
"name": "Vim"
|
||||
},
|
||||
{
|
||||
"name": "Otto"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftOffice"
|
||||
},
|
||||
{
|
||||
"name": "LibreOffice"
|
||||
},
|
||||
{
|
||||
"name": "SBT"
|
||||
},
|
||||
{
|
||||
"name": "MonoDevelop"
|
||||
},
|
||||
{
|
||||
"name": "SVN"
|
||||
},
|
||||
{
|
||||
"name": "FlexBuilder"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Single gitignore template
|
||||
|
||||
Get a single gitignore template.
|
||||
|
||||
```
|
||||
GET /templates/gitignores/:key
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ---------- | ------ | -------- | ----------- |
|
||||
| `key` | string | yes | The key of the gitignore template |
|
||||
|
||||
```bash
|
||||
curl https://gitlab.example.com/api/v3/templates/gitignores/Ruby
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Ruby",
|
||||
"content": "*.gem\n*.rbc\n/.config\n/coverage/\n/InstalledFiles\n/pkg/\n/spec/reports/\n/spec/examples.txt\n/test/tmp/\n/test/version_tmp/\n/tmp/\n\n# Used by dotenv library to load environment variables.\n# .env\n\n## Specific to RubyMotion:\n.dat*\n.repl_history\nbuild/\n*.bridgesupport\nbuild-iPhoneOS/\nbuild-iPhoneSimulator/\n\n## Specific to RubyMotion (use of CocoaPods):\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\n# vendor/Pods/\n\n## Documentation cache and generated files:\n/.yardoc/\n/_yardoc/\n/doc/\n/rdoc/\n\n## Environment normalization:\n/.bundle/\n/vendor/bundle\n/lib/bundler/man/\n\n# for a library or gem, you might want to ignore these files since the code is\n# intended to run in multiple environments; otherwise, check them in:\n# Gemfile.lock\n# .ruby-version\n# .ruby-gemset\n\n# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:\n.rvmrc\n"
|
||||
}
|
||||
```
|
120
doc/api/templates/gitlab_ci_ymls.md
Normal file
120
doc/api/templates/gitlab_ci_ymls.md
Normal file
|
@ -0,0 +1,120 @@
|
|||
# GitLab CI YMLs
|
||||
|
||||
## List GitLab CI YML templates
|
||||
|
||||
Get all GitLab CI YML templates.
|
||||
|
||||
```
|
||||
GET /templates/gitlab_ci_ymls
|
||||
```
|
||||
|
||||
```bash
|
||||
curl https://gitlab.example.com/api/v3/templates/gitlab_ci_ymls
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "C++"
|
||||
},
|
||||
{
|
||||
"name": "Docker"
|
||||
},
|
||||
{
|
||||
"name": "Elixir"
|
||||
},
|
||||
{
|
||||
"name": "LaTeX"
|
||||
},
|
||||
{
|
||||
"name": "Grails"
|
||||
},
|
||||
{
|
||||
"name": "Rust"
|
||||
},
|
||||
{
|
||||
"name": "Nodejs"
|
||||
},
|
||||
{
|
||||
"name": "Ruby"
|
||||
},
|
||||
{
|
||||
"name": "Scala"
|
||||
},
|
||||
{
|
||||
"name": "Maven"
|
||||
},
|
||||
{
|
||||
"name": "Harp"
|
||||
},
|
||||
{
|
||||
"name": "Pelican"
|
||||
},
|
||||
{
|
||||
"name": "Hyde"
|
||||
},
|
||||
{
|
||||
"name": "Nanoc"
|
||||
},
|
||||
{
|
||||
"name": "Octopress"
|
||||
},
|
||||
{
|
||||
"name": "JBake"
|
||||
},
|
||||
{
|
||||
"name": "HTML"
|
||||
},
|
||||
{
|
||||
"name": "Hugo"
|
||||
},
|
||||
{
|
||||
"name": "Metalsmith"
|
||||
},
|
||||
{
|
||||
"name": "Hexo"
|
||||
},
|
||||
{
|
||||
"name": "Lektor"
|
||||
},
|
||||
{
|
||||
"name": "Doxygen"
|
||||
},
|
||||
{
|
||||
"name": "Brunch"
|
||||
},
|
||||
{
|
||||
"name": "Jekyll"
|
||||
},
|
||||
{
|
||||
"name": "Middleman"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Single GitLab CI YML template
|
||||
|
||||
Get a single GitLab CI YML template.
|
||||
|
||||
```
|
||||
GET /templates/gitlab_ci_ymls/:key
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ---------- | ------ | -------- | ----------- |
|
||||
| `key` | string | yes | The key of the GitLab CI YML template |
|
||||
|
||||
```bash
|
||||
curl https://gitlab.example.com/api/v3/templates/gitlab_ci_ymls/Ruby
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Ruby",
|
||||
"content": "# This file is a template, and might need editing before it works on your project.\n# Official language image. Look for the different tagged releases at:\n# https://hub.docker.com/r/library/ruby/tags/\nimage: \"ruby:2.3\"\n\n# Pick zero or more services to be used on all builds.\n# Only needed when using a docker container to run your tests in.\n# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service\nservices:\n - mysql:latest\n - redis:latest\n - postgres:latest\n\nvariables:\n POSTGRES_DB: database_name\n\n# Cache gems in between builds\ncache:\n paths:\n - vendor/ruby\n\n# This is a basic example for a gem or script which doesn't use\n# services such as redis or postgres\nbefore_script:\n - ruby -v # Print out ruby version for debugging\n # Uncomment next line if your rails app needs a JS runtime:\n # - apt-get update -q && apt-get install nodejs -yqq\n - gem install bundler --no-ri --no-rdoc # Bundler is not installed with the image\n - bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby\n\n# Optional - Delete if not using `rubocop`\nrubocop:\n script:\n - rubocop\n\nrspec:\n script:\n - rspec spec\n\nrails:\n variables:\n DATABASE_URL: \"postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB\"\n script:\n - bundle exec rake db:migrate\n - bundle exec rake db:seed\n - bundle exec rake test\n"
|
||||
}
|
||||
```
|
|
@ -5,7 +5,7 @@
|
|||
Get all license templates.
|
||||
|
||||
```
|
||||
GET /licenses
|
||||
GET /templates/licenses
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|
@ -13,7 +13,7 @@ GET /licenses
|
|||
| `popular` | boolean | no | If passed, returns only popular licenses |
|
||||
|
||||
```bash
|
||||
curl https://gitlab.example.com/api/v3/licenses?popular=1
|
||||
curl https://gitlab.example.com/api/v3/templates/licenses?popular=1
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
@ -102,7 +102,7 @@ Get a single license template. You can pass parameters to replace the license
|
|||
placeholder.
|
||||
|
||||
```
|
||||
GET /licenses/:key
|
||||
GET /templates/licenses/:key
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|
@ -116,7 +116,7 @@ If you omit the `fullname` parameter but authenticate your request, the name of
|
|||
the authenticated user will be used to replace the copyright holder placeholder.
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/licenses/mit?project=My+Cool+Project
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/templates/licenses/mit?project=My+Cool+Project
|
||||
```
|
||||
|
||||
Example response:
|
|
@ -46,7 +46,6 @@ module API
|
|||
mount ::API::Boards
|
||||
mount ::API::Keys
|
||||
mount ::API::Labels
|
||||
mount ::API::LicenseTemplates
|
||||
mount ::API::Lint
|
||||
mount ::API::Members
|
||||
mount ::API::MergeRequests
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
module API
|
||||
# License Templates API
|
||||
class LicenseTemplates < Grape::API
|
||||
PROJECT_TEMPLATE_REGEX =
|
||||
/[\<\{\[]
|
||||
(project|description|
|
||||
one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here
|
||||
[\>\}\]]/xi.freeze
|
||||
YEAR_TEMPLATE_REGEX = /[<{\[](year|yyyy)[>}\]]/i.freeze
|
||||
FULLNAME_TEMPLATE_REGEX =
|
||||
/[\<\{\[]
|
||||
(fullname|name\sof\s(author|copyright\sowner))
|
||||
[\>\}\]]/xi.freeze
|
||||
|
||||
# Get the list of the available license templates
|
||||
#
|
||||
# Parameters:
|
||||
# popular - Filter licenses to only the popular ones
|
||||
#
|
||||
# Example Request:
|
||||
# GET /licenses
|
||||
# GET /licenses?popular=1
|
||||
get 'licenses' do
|
||||
options = {
|
||||
featured: params[:popular].present? ? true : nil
|
||||
}
|
||||
present Licensee::License.all(options), with: Entities::RepoLicense
|
||||
end
|
||||
|
||||
# Get text for specific license
|
||||
#
|
||||
# Parameters:
|
||||
# key (required) - The key of a license
|
||||
# project - Copyrighted project name
|
||||
# fullname - Full name of copyright holder
|
||||
#
|
||||
# Example Request:
|
||||
# GET /licenses/mit
|
||||
#
|
||||
get 'licenses/:key', requirements: { key: /[\w\.-]+/ } do
|
||||
required_attributes! [:key]
|
||||
|
||||
not_found!('License') unless Licensee::License.find(params[:key])
|
||||
|
||||
# We create a fresh Licensee::License object since we'll modify its
|
||||
# content in place below.
|
||||
license = Licensee::License.new(params[:key])
|
||||
|
||||
license.content.gsub!(YEAR_TEMPLATE_REGEX, Time.now.year.to_s)
|
||||
license.content.gsub!(PROJECT_TEMPLATE_REGEX, params[:project]) if params[:project].present?
|
||||
|
||||
fullname = params[:fullname].presence || current_user.try(:name)
|
||||
license.content.gsub!(FULLNAME_TEMPLATE_REGEX, fullname) if fullname
|
||||
|
||||
present license, with: Entities::RepoLicense
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,39 +1,115 @@
|
|||
module API
|
||||
class Templates < Grape::API
|
||||
GLOBAL_TEMPLATE_TYPES = {
|
||||
gitignores: Gitlab::Template::GitignoreTemplate,
|
||||
gitlab_ci_ymls: Gitlab::Template::GitlabCiYmlTemplate
|
||||
gitignores: {
|
||||
klass: Gitlab::Template::GitignoreTemplate,
|
||||
gitlab_version: 8.8
|
||||
},
|
||||
gitlab_ci_ymls: {
|
||||
klass: Gitlab::Template::GitlabCiYmlTemplate,
|
||||
gitlab_version: 8.9
|
||||
}
|
||||
}.freeze
|
||||
PROJECT_TEMPLATE_REGEX =
|
||||
/[\<\{\[]
|
||||
(project|description|
|
||||
one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here
|
||||
[\>\}\]]/xi.freeze
|
||||
YEAR_TEMPLATE_REGEX = /[<{\[](year|yyyy)[>}\]]/i.freeze
|
||||
FULLNAME_TEMPLATE_REGEX =
|
||||
/[\<\{\[]
|
||||
(fullname|name\sof\s(author|copyright\sowner))
|
||||
[\>\}\]]/xi.freeze
|
||||
DEPRECATION_MESSAGE = ' This endpoint is deprecated and will be removed in GitLab 9.0.'.freeze
|
||||
|
||||
helpers do
|
||||
def parsed_license_template
|
||||
# We create a fresh Licensee::License object since we'll modify its
|
||||
# content in place below.
|
||||
template = Licensee::License.new(params[:name])
|
||||
|
||||
template.content.gsub!(YEAR_TEMPLATE_REGEX, Time.now.year.to_s)
|
||||
template.content.gsub!(PROJECT_TEMPLATE_REGEX, params[:project]) if params[:project].present?
|
||||
|
||||
fullname = params[:fullname].presence || current_user.try(:name)
|
||||
template.content.gsub!(FULLNAME_TEMPLATE_REGEX, fullname) if fullname
|
||||
template
|
||||
end
|
||||
|
||||
def render_response(template_type, template)
|
||||
not_found!(template_type.to_s.singularize) unless template
|
||||
present template, with: Entities::Template
|
||||
end
|
||||
end
|
||||
|
||||
GLOBAL_TEMPLATE_TYPES.each do |template_type, klass|
|
||||
# Get the list of the available template
|
||||
#
|
||||
# Example Request:
|
||||
# GET /gitignores
|
||||
# GET /gitlab_ci_ymls
|
||||
get template_type.to_s do
|
||||
present klass.all, with: Entities::TemplatesList
|
||||
{ "licenses" => :deprecated, "templates/licenses" => :ok }.each do |route, status|
|
||||
desc 'Get the list of the available license template' do
|
||||
detailed_desc = 'This feature was introduced in GitLab 8.7.'
|
||||
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
|
||||
detail detailed_desc
|
||||
success Entities::RepoLicense
|
||||
end
|
||||
params do
|
||||
optional :popular, type: Boolean, desc: 'If passed, returns only popular licenses'
|
||||
end
|
||||
get route do
|
||||
options = {
|
||||
featured: declared(params).popular.present? ? true : nil
|
||||
}
|
||||
present Licensee::License.all(options), with: Entities::RepoLicense
|
||||
end
|
||||
end
|
||||
|
||||
{ "licenses/:name" => :deprecated, "templates/licenses/:name" => :ok }.each do |route, status|
|
||||
desc 'Get the text for a specific license' do
|
||||
detailed_desc = 'This feature was introduced in GitLab 8.7.'
|
||||
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
|
||||
detail detailed_desc
|
||||
success Entities::RepoLicense
|
||||
end
|
||||
params do
|
||||
requires :name, type: String, desc: 'The name of the template'
|
||||
end
|
||||
get route, requirements: { name: /[\w\.-]+/ } do
|
||||
not_found!('License') unless Licensee::License.find(declared(params).name)
|
||||
|
||||
template = parsed_license_template
|
||||
|
||||
present template, with: Entities::RepoLicense
|
||||
end
|
||||
end
|
||||
|
||||
GLOBAL_TEMPLATE_TYPES.each do |template_type, properties|
|
||||
klass = properties[:klass]
|
||||
gitlab_version = properties[:gitlab_version]
|
||||
|
||||
{ template_type => :deprecated, "templates/#{template_type}" => :ok }.each do |route, status|
|
||||
desc 'Get the list of the available template' do
|
||||
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
|
||||
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
|
||||
detail detailed_desc
|
||||
success Entities::TemplatesList
|
||||
end
|
||||
get route do
|
||||
present klass.all, with: Entities::TemplatesList
|
||||
end
|
||||
end
|
||||
|
||||
# Get the text for a specific template present in local filesystem
|
||||
#
|
||||
# Parameters:
|
||||
# name (required) - The name of a template
|
||||
#
|
||||
# Example Request:
|
||||
# GET /gitignores/Elixir
|
||||
# GET /gitlab_ci_ymls/Ruby
|
||||
get "#{template_type}/:name" do
|
||||
required_attributes! [:name]
|
||||
new_template = klass.find(params[:name])
|
||||
render_response(template_type, new_template)
|
||||
{ "#{template_type}/:name" => :deprecated, "templates/#{template_type}/:name" => :ok }.each do |route, status|
|
||||
desc 'Get the text for a specific template present in local filesystem' do
|
||||
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
|
||||
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
|
||||
detail detailed_desc
|
||||
success Entities::Template
|
||||
end
|
||||
params do
|
||||
requires :name, type: String, desc: 'The name of the template'
|
||||
end
|
||||
get route do
|
||||
new_template = klass.find(declared(params).name)
|
||||
|
||||
render_response(template_type, new_template)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe API::API, api: true do
|
||||
include ApiHelpers
|
||||
|
||||
describe 'Entity' do
|
||||
before { get api('/licenses/mit') }
|
||||
|
||||
it { expect(json_response['key']).to eq('mit') }
|
||||
it { expect(json_response['name']).to eq('MIT License') }
|
||||
it { expect(json_response['nickname']).to be_nil }
|
||||
it { expect(json_response['popular']).to be true }
|
||||
it { expect(json_response['html_url']).to eq('http://choosealicense.com/licenses/mit/') }
|
||||
it { expect(json_response['source_url']).to eq('https://opensource.org/licenses/MIT') }
|
||||
it { expect(json_response['description']).to include('A permissive license that is short and to the point.') }
|
||||
it { expect(json_response['conditions']).to eq(%w[include-copyright]) }
|
||||
it { expect(json_response['permissions']).to eq(%w[commercial-use modifications distribution private-use]) }
|
||||
it { expect(json_response['limitations']).to eq(%w[no-liability]) }
|
||||
it { expect(json_response['content']).to include('The MIT License (MIT)') }
|
||||
end
|
||||
|
||||
describe 'GET /licenses' do
|
||||
it 'returns a list of available license templates' do
|
||||
get api('/licenses')
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(15)
|
||||
expect(json_response.map { |l| l['key'] }).to include('agpl-3.0')
|
||||
end
|
||||
|
||||
describe 'the popular parameter' do
|
||||
context 'with popular=1' do
|
||||
it 'returns a list of available popular license templates' do
|
||||
get api('/licenses?popular=1')
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(3)
|
||||
expect(json_response.map { |l| l['key'] }).to include('apache-2.0')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /licenses/:key' do
|
||||
context 'with :project and :fullname given' do
|
||||
before do
|
||||
get api("/licenses/#{license_type}?project=My+Awesome+Project&fullname=Anton+#{license_type.upcase}")
|
||||
end
|
||||
|
||||
context 'for the mit license' do
|
||||
let(:license_type) { 'mit' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('The MIT License (MIT)')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the agpl-3.0 license' do
|
||||
let(:license_type) { 'agpl-3.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('GNU AFFERO GENERAL PUBLIC LICENSE')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include('My Awesome Project')
|
||||
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the gpl-3.0 license' do
|
||||
let(:license_type) { 'gpl-3.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include('My Awesome Project')
|
||||
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the gpl-2.0 license' do
|
||||
let(:license_type) { 'gpl-2.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include('My Awesome Project')
|
||||
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the apache-2.0 license' do
|
||||
let(:license_type) { 'apache-2.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('Apache License')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include("Copyright #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for an uknown license' do
|
||||
let(:license_type) { 'muth-over9000' }
|
||||
|
||||
it 'returns a 404' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with no :fullname given' do
|
||||
context 'with an authenticated user' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'replaces the copyright owner placeholder with the name of the current user' do
|
||||
get api('/licenses/mit', user)
|
||||
|
||||
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} #{user.name}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,53 +3,201 @@ require 'spec_helper'
|
|||
describe API::Templates, api: true do
|
||||
include ApiHelpers
|
||||
|
||||
context 'global templates' do
|
||||
describe 'the Template Entity' do
|
||||
before { get api('/gitignores/Ruby') }
|
||||
shared_examples_for 'the Template Entity' do |path|
|
||||
before { get api(path) }
|
||||
|
||||
it { expect(json_response['name']).to eq('Ruby') }
|
||||
it { expect(json_response['content']).to include('*.gem') }
|
||||
it { expect(json_response['name']).to eq('Ruby') }
|
||||
it { expect(json_response['content']).to include('*.gem') }
|
||||
end
|
||||
|
||||
shared_examples_for 'the TemplateList Entity' do |path|
|
||||
before { get api(path) }
|
||||
|
||||
it { expect(json_response.first['name']).not_to be_nil }
|
||||
it { expect(json_response.first['content']).to be_nil }
|
||||
end
|
||||
|
||||
shared_examples_for 'requesting gitignores' do |path|
|
||||
it 'returns a list of available gitignore templates' do
|
||||
get api(path)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to be > 15
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'requesting gitlab-ci-ymls' do |path|
|
||||
it 'returns a list of available gitlab_ci_ymls' do
|
||||
get api(path)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.first['name']).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'requesting gitlab-ci-yml for Ruby' do |path|
|
||||
it 'adds a disclaimer on the top' do
|
||||
get api(path)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response['content']).to start_with("# This file is a template,")
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'the License Template Entity' do |path|
|
||||
before { get api(path) }
|
||||
|
||||
it 'returns a license template' do
|
||||
expect(json_response['key']).to eq('mit')
|
||||
expect(json_response['name']).to eq('MIT License')
|
||||
expect(json_response['nickname']).to be_nil
|
||||
expect(json_response['popular']).to be true
|
||||
expect(json_response['html_url']).to eq('http://choosealicense.com/licenses/mit/')
|
||||
expect(json_response['source_url']).to eq('https://opensource.org/licenses/MIT')
|
||||
expect(json_response['description']).to include('A permissive license that is short and to the point.')
|
||||
expect(json_response['conditions']).to eq(%w[include-copyright])
|
||||
expect(json_response['permissions']).to eq(%w[commercial-use modifications distribution private-use])
|
||||
expect(json_response['limitations']).to eq(%w[no-liability])
|
||||
expect(json_response['content']).to include('The MIT License (MIT)')
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'GET licenses' do |path|
|
||||
it 'returns a list of available license templates' do
|
||||
get api(path)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(15)
|
||||
expect(json_response.map { |l| l['key'] }).to include('agpl-3.0')
|
||||
end
|
||||
|
||||
describe 'the TemplateList Entity' do
|
||||
before { get api('/gitignores') }
|
||||
describe 'the popular parameter' do
|
||||
context 'with popular=1' do
|
||||
it 'returns a list of available popular license templates' do
|
||||
get api("#{path}?popular=1")
|
||||
|
||||
it { expect(json_response.first['name']).not_to be_nil }
|
||||
it { expect(json_response.first['content']).to be_nil }
|
||||
end
|
||||
|
||||
context 'requesting gitignores' do
|
||||
describe 'GET /gitignores' do
|
||||
it 'returns a list of available gitignore templates' do
|
||||
get api('/gitignores')
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to be > 15
|
||||
expect(json_response.size).to eq(3)
|
||||
expect(json_response.map { |l| l['key'] }).to include('apache-2.0')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'requesting gitlab-ci-ymls' do
|
||||
describe 'GET /gitlab_ci_ymls' do
|
||||
it 'returns a list of available gitlab_ci_ymls' do
|
||||
get api('/gitlab_ci_ymls')
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.first['name']).not_to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /gitlab_ci_ymls/Ruby' do
|
||||
it 'adds a disclaimer on the top' do
|
||||
get api('/gitlab_ci_ymls/Ruby')
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response['name']).not_to be_nil
|
||||
expect(json_response['content']).to start_with("# This file is a template,")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'GET licenses/:name' do |path|
|
||||
context 'with :project and :fullname given' do
|
||||
before do
|
||||
get api("#{path}/#{license_type}?project=My+Awesome+Project&fullname=Anton+#{license_type.upcase}")
|
||||
end
|
||||
|
||||
context 'for the mit license' do
|
||||
let(:license_type) { 'mit' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('The MIT License (MIT)')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the agpl-3.0 license' do
|
||||
let(:license_type) { 'agpl-3.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('GNU AFFERO GENERAL PUBLIC LICENSE')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include('My Awesome Project')
|
||||
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the gpl-3.0 license' do
|
||||
let(:license_type) { 'gpl-3.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include('My Awesome Project')
|
||||
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the gpl-2.0 license' do
|
||||
let(:license_type) { 'gpl-2.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include('My Awesome Project')
|
||||
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for the apache-2.0 license' do
|
||||
let(:license_type) { 'apache-2.0' }
|
||||
|
||||
it 'returns the license text' do
|
||||
expect(json_response['content']).to include('Apache License')
|
||||
end
|
||||
|
||||
it 'replaces placeholder values' do
|
||||
expect(json_response['content']).to include("Copyright #{Time.now.year} Anton")
|
||||
end
|
||||
end
|
||||
|
||||
context 'for an uknown license' do
|
||||
let(:license_type) { 'muth-over9000' }
|
||||
|
||||
it 'returns a 404' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with no :fullname given' do
|
||||
context 'with an authenticated user' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'replaces the copyright owner placeholder with the name of the current user' do
|
||||
get api('/templates/licenses/mit', user)
|
||||
|
||||
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} #{user.name}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with /templates namespace' do
|
||||
it_behaves_like 'the Template Entity', '/templates/gitignores/Ruby'
|
||||
it_behaves_like 'the TemplateList Entity', '/templates/gitignores'
|
||||
it_behaves_like 'requesting gitignores', '/templates/gitignores'
|
||||
it_behaves_like 'requesting gitlab-ci-ymls', '/templates/gitlab_ci_ymls'
|
||||
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/templates/gitlab_ci_ymls/Ruby'
|
||||
it_behaves_like 'the License Template Entity', '/templates/licenses/mit'
|
||||
it_behaves_like 'GET licenses', '/templates/licenses'
|
||||
it_behaves_like 'GET licenses/:name', '/templates/licenses'
|
||||
end
|
||||
|
||||
describe 'without /templates namespace' do
|
||||
it_behaves_like 'the Template Entity', '/gitignores/Ruby'
|
||||
it_behaves_like 'the TemplateList Entity', '/gitignores'
|
||||
it_behaves_like 'requesting gitignores', '/gitignores'
|
||||
it_behaves_like 'requesting gitlab-ci-ymls', '/gitlab_ci_ymls'
|
||||
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/gitlab_ci_ymls/Ruby'
|
||||
it_behaves_like 'the License Template Entity', '/licenses/mit'
|
||||
it_behaves_like 'GET licenses', '/licenses'
|
||||
it_behaves_like 'GET licenses/:name', '/licenses'
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue