diff options
author | zeripath <art27@cantab.net> | 2022-02-09 21:28:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-09 21:28:55 +0100 |
commit | eb748f5f3c93e8e347309fc75ea8273c06a5489b (patch) | |
tree | fceec474a21fa35437bcf3e90bd549c11976b72e /templates | |
parent | C preprocessor colors improvement (#18671) (diff) | |
download | forgejo-eb748f5f3c93e8e347309fc75ea8273c06a5489b.tar.xz forgejo-eb748f5f3c93e8e347309fc75ea8273c06a5489b.zip |
Add apply-patch, basic revert and cherry-pick functionality (#17902)
This code adds a simple endpoint to apply patches to repositories and
branches on gitea. This is then used along with the conflicting checking
code in #18004 to provide a basic implementation of cherry-pick revert.
Now because the buttons necessary for cherry-pick and revert have
required us to create a dropdown next to the Browse Source button
I've also implemented Create Branch and Create Tag operations.
Fix #3880
Fix #17986
Signed-off-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'templates')
-rw-r--r-- | templates/repo/branch_dropdown.tmpl | 50 | ||||
-rw-r--r-- | templates/repo/commit_page.tmpl | 123 | ||||
-rw-r--r-- | templates/repo/editor/cherry_pick.tmpl | 32 | ||||
-rw-r--r-- | templates/repo/editor/patch.tmpl | 59 | ||||
-rw-r--r-- | templates/repo/home.tmpl | 5 | ||||
-rw-r--r-- | templates/swagger/v1_json.tmpl | 44 |
6 files changed, 289 insertions, 24 deletions
diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index a6120483b5..0e263e8075 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -1,37 +1,51 @@ {{$release := .release}} +{{$defaultBranch := $.root.BranchName}}{{if and .root.IsViewTag (not .noTag)}}{{$defaultBranch = .root.TagName}}{{end}}{{if eq $defaultBranch ""}}{{$defaultBranch = $.root.Repository.DefaultBranch}}{{end}} {{$showBranchesInDropdown := not .root.HideBranchesInDropdown}} <div class="fitted item choose reference{{if not $release}} mr-1{{end}}"> - <div class="ui floating filter dropdown custom" data-can-create-branch="{{.root.CanCreateBranch}}" data-no-results="{{.root.i18n.Tr "repo.pulls.no_results"}}"> + <div class="ui floating filter dropdown custom" + data-branch-form="{{if $.branchForm}}{{$.branchForm}}{{end}}" + data-can-create-branch="{{if .canCreateBranch}}{{.canCreateBranch}}{{else}}{{.root.CanCreateBranch}}{{end}}" + data-no-results="{{.root.i18n.Tr "repo.pulls.no_results"}}" + data-set-action="{{.setAction}}" data-submit-form="{{.submitForm}}" + data-view-type="{{if and .root.IsViewTag (not .noTag)}}tag{{else if .root.IsViewBranch}}branch{{else}}tree{{end}}" + data-ref-name="{{if and .root.IsViewTag (not .noTag)}}{{.root.TagName}}{{else if .root.IsViewBranch}}{{.root.BranchName}}{{else}}{{ShortSha .root.CommitID}}{{end}}" + data-branch-url-prefix="{{if .branchURLPrefix}}{{.branchURLPrefix}}{{else}}{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/branch/{{end}}" + data-branch-url-suffix="{{if .branchURLSuffix}}{{.branchURLSuffix}}{{else}}{{if $.root.TreePath}}/{{PathEscapeSegments $.root.TreePath}}{{end}}{{end}}" + data-tag-url-prefix="{{if .tagURLPrefix}}{{.tagURLPrefix}}{{else if $release}}{{$.root.RepoLink}}/compare/{{else}}{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/tag/{{end}}" + data-tag-url-suffix="{{if .tagURLSuffix}}{{.tagURLSuffix}}{{else if $release}}...{{if $release.IsDraft}}{{PathEscapeSegments $release.Target}}{{else}}{{if $release.TagName}}{{PathEscapeSegments $release.TagName}}{{else}}{{PathEscapeSegments $release.Sha1}}{{end}}{{end}}{{else}}{{if $.root.TreePath}}/{{PathEscapeSegments $.root.TreePath}}{{end}}{{end}}"> <div class="ui basic small compact button" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible"> <span class="text"> {{if $release}} {{.root.i18n.Tr "repo.release.compare"}} {{else}} - {{if .root.IsViewTag}}{{svg "octicon-tag"}}{{else}}{{svg "octicon-git-branch"}}{{end}} - {{if .root.IsViewBranch}}{{.root.i18n.Tr "repo.branch"}}{{else if .root.IsViewTag}}{{.root.i18n.Tr "repo.tag"}}{{else}}{{.root.i18n.Tr "repo.tree"}}{{end}}: - <strong>{{if .root.IsViewBranch}}{{.root.BranchName}}{{else if .root.IsViewTag}}{{.root.TagName}}{{else}}{{ShortSha .root.CommitID}}{{end}}</strong> + <span :class="{visible: isViewTag}" v-if="isViewTag" v-cloak>{{svg "octicon-tag"}} {{.root.i18n.Tr "repo.tag"}}:</span> + <span :class="{visible: isViewBranch}" v-if="isViewBranch" v-cloak>{{svg "octicon-git-branch"}} {{.root.i18n.Tr "repo.branch"}}:</span> + <span :class="{visible: isViewTree}" v-if="isViewTree" v-cloak>{{svg "octicon-git-branch"}} {{.root.i18n.Tr "repo.tree"}}:</span> + <strong ref="dropdownRefName">{{if and .root.IsViewTag (not .noTag)}}{{.root.TagName}}{{else if .root.IsViewBranch}}{{.root.BranchName}}{{else}}{{ShortSha .root.CommitID}}{{end}}</strong> {{end}} </span> {{svg "octicon-triangle-down" 14 "dropdown icon"}} </div> - <div class="data" style="display: none" data-mode="{{if .root.IsViewTag}}tags{{else}}branches{{end}}"> + <div class="data" style="display: none" data-mode="{{if or .root.IsViewTag .isTag}}tags{{else}}branches{{end}}"> {{if $showBranchesInDropdown}} {{range .root.Branches}} - <div class="item branch {{if eq $.root.BranchName .}}selected{{end}}" data-url="{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/branch/{{PathEscapeSegments .}}{{if $.root.TreePath}}/{{PathEscapeSegments $.root.TreePath}}{{end}}">{{.}}</div> + <div class="item branch {{if eq $defaultBranch .}}selected{{end}}" data-url="{{PathEscapeSegments .}}">{{.}}</div> {{end}} {{end}} - {{range .root.Tags}} - {{if $release}} - <div class="item tag {{if eq $release.TagName .}}selected{{end}}" data-url="{{$.root.RepoLink}}/compare/{{PathEscapeSegments .}}...{{if $release.IsDraft}}{{PathEscapeSegments $release.Target}}{{else}}{{if $release.TagName}}{{PathEscapeSegments $release.TagName}}{{else}}{{PathEscapeSegments $release.Sha1}}{{end}}{{end}}">{{.}}</div> - {{else}} - <div class="item tag {{if eq $.root.BranchName .}}selected{{end}}" data-url="{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/tag/{{PathEscapeSegments .}}{{if $.root.TreePath}}/{{PathEscapeSegments $.root.TreePath}}{{end}}">{{.}}</div> + {{if (not .noTag)}} + {{range .root.Tags}} + {{if $release}} + <div class="item tag {{if eq $release.TagName .}}selected{{end}}" data-url="{{PathEscapeSegments .}}">{{.}}</div> + {{else}} + <div class="item tag {{if eq $defaultBranch .}}selected{{end}}" data-url="{{PathEscapeSegments .}}">{{.}}</div> + {{end}} {{end}} {{end}} </div> <div class="menu transition" :class="{visible: menuVisible}" v-if="menuVisible" v-cloak> <div class="ui icon search input"> <i class="icon df ac jc m-0">{{svg "octicon-filter" 16}}</i> - <input name="search" ref="searchField" autocomplete="off" v-model="searchTerm" @keydown="keydown($event)" placeholder="{{if $showBranchesInDropdown}}{{.root.i18n.Tr "repo.filter_branch_and_tag"}}{{else}}{{.root.i18n.Tr "repo.find_tag"}}{{end}}..."> + <input name="search" ref="searchField" autocomplete="off" v-model="searchTerm" @keydown="keydown($event)" placeholder="{{if $.noTag}}{{.root.i18n.Tr "repo.filter_branch"}}{{else if $showBranchesInDropdown}}{{.root.i18n.Tr "repo.filter_branch_and_tag"}}{{else}}{{.root.i18n.Tr "repo.find_tag"}}{{end}}..."> </div> {{if $showBranchesInDropdown}} <div class="header branch-tag-choice"> @@ -42,11 +56,13 @@ {{svg "octicon-git-branch" 16 "mr-2"}}{{.root.i18n.Tr "repo.branches"}} </span> </a> - <a class="reference column" href="#" @click="createTag = true; mode = 'tags'; focusSearchField()"> - <span class="text" :class="{black: mode == 'tags'}"> - {{svg "octicon-tag" 16 "mr-2"}}{{.root.i18n.Tr "repo.tags"}} - </span> - </a> + {{if not .noTag}} + <a class="reference column" href="#" @click="createTag = true; mode = 'tags'; focusSearchField()"> + <span class="text" :class="{black: mode == 'tags'}"> + {{svg "octicon-tag" 16 "mr-2"}}{{.root.i18n.Tr "repo.tags"}} + </span> + </a> + {{end}} </div> </div> </div> diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index 331c439c02..370cafa2e1 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -18,14 +18,123 @@ {{end}} {{end}} <div class="ui top attached header clearing segment pr {{$class}}"> - {{if not $.PageIsWiki}} - <a class="ui blue tiny button browse-button" href="{{.SourcePath}}"> - {{.i18n.Tr "repo.diff.browse_source"}} - </a> - {{end}} - <h3 class="mt-0"><span class="message-wrapper"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message $.RepoLink $.Repository.ComposeMetas}}</span></span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "root" $}}</h3> + <div class="df mb-4"> + <h3 class="mb-0 f1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message $.RepoLink $.Repository.ComposeMetas}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "root" $}}</h3> + {{if not $.PageIsWiki}} + <div class="ui"> + <a class="ui blue tiny button" href="{{.SourcePath}}"> + {{.i18n.Tr "repo.diff.browse_source"}} + </a> + {{if and ($.Permission.CanWrite $.UnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}{{- /* */ -}} + <div class="ui blue tiny floating dropdown icon button">{{.i18n.Tr "repo.commit.actions"}} + {{svg "octicon-triangle-down" 14 "dropdown icon"}}<span class="sr-mobile-only">{{.i18n.Tr "repo.commit.actions"}}</span> + <div class="menu"> + <div class="ui header">{{.i18n.Tr "repo.commit.actions"}}</div> + <div class="divider"></div> + <div class="item show-create-branch-modal" + data-content="{{$.i18n.Tr "repo.branch.new_branch_from" (.CommitID)}}" + data-branch-from="{{ShortSha .CommitID}}" + data-branch-from-urlcomponent="{{.CommitID}}" + data-modal="#create-branch-modal"> + {{.i18n.Tr "repo.branch.create_branch_operation"}} + </div> + <div class="item show-create-branch-modal" + data-content="{{$.i18n.Tr "repo.branch.new_branch_from" (.CommitID)}}" + data-branch-from="{{ShortSha .CommitID}}" + data-branch-from-urlcomponent="{{.CommitID}}" + data-modal="#create-tag-modal" + data-modal-from-span="#modal-create-tag-from-span" + data-modal-form="#create-tag-form"> + {{.i18n.Tr "repo.tag.create_tag_operation"}} + </div> + <div class="item show-modal revert-button" + data-modal="#cherry-pick-modal" + data-modal-cherry-pick-type="revert" + data-modal-cherry-pick-header="{{$.i18n.Tr "repo.commit.revert-header" (ShortSha .CommitID)}}" + data-modal-cherry-pick-content="{{$.i18n.Tr "repo.commit.revert-content"}}" + data-modal-cherry-pick-submit="{{.i18n.Tr "repo.commit.revert"}}">{{.i18n.Tr "repo.commit.revert"}}</a></div> + <div class="item cherry-pick-button show-modal" + data-modal="#cherry-pick-modal" + data-modal-cherry-pick-type="cherry-pick" + data-modal-cherry-pick-header="{{$.i18n.Tr "repo.commit.cherry-pick-header" (ShortSha .CommitID)}}" + data-modal-cherry-pick-content="{{$.i18n.Tr "repo.commit.cherry-pick-content"}}" + data-modal-cherry-pick-submit="{{.i18n.Tr "repo.commit.cherry-pick"}}">{{.i18n.Tr "repo.commit.cherry-pick"}}</a></div> + <div class="ui basic modal" id="cherry-pick-modal"> + <div class="ui icon header"> + <span id="cherry-pick-header"></span> + </div> + <div class="content center"> + <p id="cherry-pick-content" class="branch-dropdown"></p> + {{template "repo/branch_dropdown" dict "root" . + "noTag" "true" "canCreateBranch" "false" + "branchForm" "branch-dropdown-form" + "branchURLPrefix" (printf "%s/_cherrypick/%s/" $.RepoLink .CommitID) "branchURLSuffix" "" + "setAction" "true" "submitForm" "true"}} + <form method="GET" action="{{$.RepoLink}}/_cherrypick/{{.CommitID}}/{{if $.BranchName}}{{PathEscapeSegments $.BranchName}}{{else}}{{PathEscapeSegments $.Repository.DefaultBranch}}{{end}}" id="branch-dropdown-form"> + <input type="hidden" name="ref" value="{{if $.BranchName}}{{$.BranchName}}{{else}}{{$.Repository.DefaultBranch}}{{end}}"> + <input type="hidden" name="refType" value="branch"> + <input type="hidden" id="cherry-pick-type" name="cherry-pick-type"><br/> + <button type="submit" id="cherry-pick-submit" class="ui green button"></button> + </form> + </div> + </div> + <div class="ui small modal" id="create-branch-modal"> + <div class="header"> + {{.i18n.Tr "repo.branch.new_branch"}} + </div> + <div class="content"> + <form class="ui form" id="create-branch-form" action="" data-base-action="{{.RepoLink}}/branches/_new/commit/" method="post"> + {{.CsrfTokenHtml}} + <div class="field"> + <label> + {{.i18n.Tr "repo.branch.new_branch_from" "<span class=\"text\" id=\"modal-create-branch-from-span\"></span>" | Safe }} + </label> + </div> + <div class="required field"> + <label for="new_branch_name">{{.i18n.Tr "repo.branch.name"}}</label> + <input id="new_branch_name" name="new_branch_name" required> + </div> + + <div class="text right actions"> + <div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div> + <button class="ui green button">{{.i18n.Tr "repo.branch.confirm_create_branch"}}</button> + </div> + </form> + </div> + </div> + <div class="ui small modal" id="create-tag-modal"> + <div class="header"> + {{.i18n.Tr "repo.tag.create_tag_operation"}} + </div> + <div class="content"> + <form class="ui form" id="create-tag-form" action="" data-base-action="{{.RepoLink}}/branches/_new/commit/" method="post"> + {{.CsrfTokenHtml}} + <input type="hidden" name="create_tag" value="true"> + <div class="field"> + <label> + {{.i18n.Tr "repo.tag.create_tag_from" "<span class=\"text\" id=\"modal-create-tag-from-span\"></span>" | Safe }} + </label> + </div> + <div class="required field"> + <label for="new_branch_name">{{.i18n.Tr "repo.release.tag_name"}}</label> + <input id="new_branch_name" name="new_branch_name" required> + </div> + + <div class="text right actions"> + <div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div> + <button class="ui green button">{{.i18n.Tr "repo.tag.confirm_create_tag"}}</button> + </div> + </form> + </div> + </div> + </div> + </div> + {{end}} + </div> + {{end}} + </div> {{if IsMultilineCommitMessage .Commit.Message}} - <pre class="commit-body">{{RenderCommitBody $.Context .Commit.Message $.RepoLink $.Repository.ComposeMetas}}</pre> + <pre class="commit-body mt-0">{{RenderCommitBody $.Context .Commit.Message $.RepoLink $.Repository.ComposeMetas}}</pre> {{end}} {{if .BranchName}} <span class="text grey mr-3">{{svg "octicon-git-branch" 16 "mr-2"}}{{.BranchName}}</span> diff --git a/templates/repo/editor/cherry_pick.tmpl b/templates/repo/editor/cherry_pick.tmpl new file mode 100644 index 0000000000..9cdda2ea83 --- /dev/null +++ b/templates/repo/editor/cherry_pick.tmpl @@ -0,0 +1,32 @@ +{{template "base/head" .}} +<div class="page-content repository file editor edit"> + {{template "repo/header" .}} + <div class="ui container"> + {{template "base/alert" .}} + <form class="ui edit form" method="post" action="{{.RepoLink}}/_cherrypick/{{.SHA}}/{{.BranchName | PathEscapeSegments}}"> + {{.CsrfTokenHtml}} + <input type="hidden" name="last_commit" value="{{.last_commit}}"> + <input type="hidden" name="page_has_posted" value="true"> + <input type="hidden" name="revert" value="{{if eq .CherryPickType "revert"}}true{{else}}false{{end}}"> + <div class="ui secondary menu"> + <div class="fitted item treepath"> + <div class="ui breadcrumb field {{if .Err_TreePath}}error{{end}}"> + {{$shaurl := printf "%s/commit/%s" $.RepoLink (PathEscape .SHA)}} + {{$shalink := printf "<a class=\"ui blue sha label\" href=\"%s\">%s</a>" (Escape $shaurl) (ShortSha .SHA)}} + {{if eq .CherryPickType "revert"}} + {{.i18n.Tr "repo.editor.revert" $shalink | Str2html}} + {{else}} + {{.i18n.Tr "repo.editor.cherry_pick" $shalink | Str2html}} + {{end}} + <a class="section" href="{{$.RepoLink}}">{{.Repository.FullName}}</a> + <div class="divider">:</div> + <a class="section" href="{{$.BranchLink}}">{{.BranchName}}</a> + <span>{{.i18n.Tr "repo.editor.or"}} <a href="{{$shaurl}}">{{.i18n.Tr "repo.editor.cancel_lower"}}</a></span> + </div> + </div> + </div> + {{template "repo/editor/commit_form" .}} + </form> + </div> +</div> +{{template "base/footer" .}} diff --git a/templates/repo/editor/patch.tmpl b/templates/repo/editor/patch.tmpl new file mode 100644 index 0000000000..cecda907a4 --- /dev/null +++ b/templates/repo/editor/patch.tmpl @@ -0,0 +1,59 @@ +{{template "base/head" .}} +<div class="page-content repository file editor edit"> + {{template "repo/header" .}} + <div class="ui container"> + {{template "base/alert" .}} + <form class="ui edit form" method="post" action="{{.RepoLink}}/_diffpatch/{{.BranchName | PathEscapeSegments}}"> + {{.CsrfTokenHtml}} + <input type="hidden" name="last_commit" value="{{.last_commit}}"> + <input type="hidden" name="page_has_posted" value="{{.PageHasPosted}}"> + <div class="ui secondary menu"> + <div class="fitted item treepath"> + <div class="ui breadcrumb field {{if .Err_TreePath}}error{{end}}"> + {{.i18n.Tr "repo.editor.patching"}} + <a class="section" href="{{$.RepoLink}}">{{.Repository.FullName}}</a> + <div class="divider">:</div> + <a class="section" href="{{$.BranchLink}}">{{.BranchName}}</a> + <span>{{.i18n.Tr "repo.editor.or"}} <a href="{{$.BranchLink}}">{{.i18n.Tr "repo.editor.cancel_lower"}}</a></span> + <input type="hidden" id="tree_path" name="tree_path" value="patch" required> + <input id="file-name" type="hidden" value="diff.patch"> + </div> + </div> + </div> + <div class="field"> + <div class="ui top attached tabular menu" data-write="write"> + <a class="active item" data-tab="write">{{svg "octicon-code" 16 "mr-2"}}{{.i18n.Tr "repo.editor.new_patch"}}</a> + </div> + <div class="ui bottom attached active tab segment" data-tab="write"> + <textarea id="edit_area" name="content" class="hide" data-id="repo-{{.Repository.Name}}-patch" + data-context="{{.RepoLink}}" + data-line-wrap-extensions="{{.LineWrapExtensions}}"> +{{.FileContent}}</textarea> + <div class="editor-loading is-loading"></div> + </div> + </div> + {{template "repo/editor/commit_form" .}} + </form> + </div> + + <div class="ui small basic modal" id="edit-empty-content-modal"> + <div class="ui icon header"> + <i class="file icon"></i> + {{.i18n.Tr "repo.editor.commit_empty_file_header"}} + </div> + <div class="center content"> + <p>{{.i18n.Tr "repo.editor.commit_empty_file_text"}}</p> + </div> + <div class="actions"> + <div class="ui red basic cancel inverted button"> + <i class="remove icon"></i> + {{.i18n.Tr "repo.editor.cancel"}} + </div> + <div class="ui green basic ok inverted button"> + <i class="save icon"></i> + {{.i18n.Tr "repo.editor.commit_changes"}} + </div> + </div> + </div> +</div> +{{template "base/footer" .}} diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 6d525c24da..30f1471c16 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -89,6 +89,11 @@ {{.i18n.Tr "repo.editor.upload_file"}} </a> {{end}} + {{if .CanAddFile}} + <a href="{{.RepoLink}}/_diffpatch/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}" class="ui button"> + {{.i18n.Tr "repo.editor.patch"}} + </a> + {{end}} {{end}} {{if and (ne $n 0) (not .IsViewFile) (not .IsBlame) }} <a href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}" class="ui button"> diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 497636e781..0b0b83ebbc 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3383,6 +3383,50 @@ } } }, + "/repos/{owner}/{repo}/diffpatch": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Apply diff patch to repository", + "operationId": "repoApplyDiffPatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateFileOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/FileResponse" + } + } + } + }, "/repos/{owner}/{repo}/editorconfig/{filepath}": { "get": { "produces": [ |