1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-23 02:38:35 +00:00

Add Package Registry (#16510)

* Added package store settings.

* Added models.

* Added generic package registry.

* Added tests.

* Added NuGet package registry.

* Moved service index to api file.

* Added NPM package registry.

* Added Maven package registry.

* Added PyPI package registry.

* Summary is deprecated.

* Changed npm name.

* Sanitize project url.

* Allow only scoped packages.

* Added user interface.

* Changed method name.

* Added missing migration file.

* Set page info.

* Added documentation.

* Added documentation links.

* Fixed wrong error message.

* Lint template files.

* Fixed merge errors.

* Fixed unit test storage path.

* Switch to json module.

* Added suggestions.

* Added package webhook.

* Add package api.

* Fixed swagger file.

* Fixed enum and comments.

* Fixed NuGet pagination.

* Print test names.

* Added api tests.

* Fixed access level.

* Fix User unmarshal.

* Added RubyGems package registry.

* Fix lint.

* Implemented io.Writer.

* Added support for sha256/sha512 checksum files.

* Improved maven-metadata.xml support.

* Added support for symbol package uploads.

* Added tests.

* Added overview docs.

* Added npm dependencies and keywords.

* Added no-packages information.

* Display file size.

* Display asset count.

* Fixed filter alignment.

* Added package icons.

* Formatted instructions.

* Allow anonymous package downloads.

* Fixed comments.

* Fixed postgres test.

* Moved file.

* Moved models to models/packages.

* Use correct error response format per client.

* Use simpler search form.

* Fixed IsProd.

* Restructured data model.

* Prevent empty filename.

* Fix swagger.

* Implemented user/org registry.

* Implemented UI.

* Use GetUserByIDCtx.

* Use table for dependencies.

* make svg

* Added support for unscoped npm packages.

* Add support for npm dist tags.

* Added tests for npm tags.

* Unlink packages if repository gets deleted.

* Prevent user/org delete if a packages exist.

* Use package unlink in repository service.

* Added support for composer packages.

* Restructured package docs.

* Added missing tests.

* Fixed generic content page.

* Fixed docs.

* Fixed swagger.

* Added missing type.

* Fixed ambiguous column.

* Organize content store by sha256 hash.

* Added admin package management.

* Added support for sorting.

* Add support for multiple identical versions/files.

* Added missing repository unlink.

* Added file properties.

* make fmt

* lint

* Added Conan package registry.

* Updated docs.

* Unify package names.

* Added swagger enum.

* Use longer TEXT column type.

* Removed version composite key.

* Merged package and container registry.

* Removed index.

* Use dedicated package router.

* Moved files to new location.

* Updated docs.

* Fixed JOIN order.

* Fixed GROUP BY statement.

* Fixed GROUP BY #2.

* Added symbol server support.

* Added more tests.

* Set NOT NULL.

* Added setting to disable package registries.

* Moved auth into service.

* refactor

* Use ctx everywhere.

* Added package cleanup task.

* Changed packages path.

* Added container registry.

* Refactoring

* Updated comparison.

* Fix swagger.

* Fixed table order.

* Use token auth for npm routes.

* Enabled ReverseProxy auth.

* Added packages link for orgs.

* Fixed anonymous org access.

* Enable copy button for setup instructions.

* Merge error

* Added suggestions.

* Fixed merge.

* Handle "generic".

* Added link for TODO.

* Added suggestions.

* Changed temporary buffer filename.

* Added suggestions.

* Apply suggestions from code review

Co-authored-by: Thomas Boerger <thomas@webhippie.de>

* Update docs/content/doc/packages/nuget.en-us.md

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Thomas Boerger <thomas@webhippie.de>
This commit is contained in:
KN4CK3R
2022-03-30 10:42:47 +02:00
committed by GitHub
parent 2bce1ea986
commit 1d332342db
197 changed files with 18563 additions and 55 deletions

View File

@@ -12,6 +12,9 @@
<a class="{{if .PageIsAdminRepositories}}active{{end}} item" href="{{AppSubUrl}}/admin/repos">
{{.i18n.Tr "admin.repositories"}}
</a>
<a class="{{if .PageIsAdminPackages}}active{{end}} item" href="{{AppSubUrl}}/admin/packages">
{{.i18n.Tr "packages.title"}}
</a>
{{if not DisableWebhooks}}
<a class="{{if or .PageIsAdminDefaultHooks .PageIsAdminSystemHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks">
{{.i18n.Tr "admin.hooks"}}

View File

@@ -0,0 +1,97 @@
{{template "base/head" .}}
<div class="page-content admin user">
{{template "admin/navbar" .}}
<div class="ui container">
{{template "base/alert" .}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.packages.package_manage_panel"}} ({{.i18n.Tr "admin.total" .Total}}, {{.i18n.Tr "admin.packages.total_size" (FileSize .TotalBlobSize)}})
</h4>
<div class="ui attached segment">
<form class="ui form ignore-dirty">
<div class="ui fluid action input">
<input name="q" value="{{.Query}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<select class="ui dropdown" name="type">
<option value="">{{.i18n.Tr "packages.filter.type"}}</option>
<option value="all">{{.i18n.Tr "packages.filter.type.all"}}</option>
<option value="composer" {{if eq .PackageType "composer"}}selected="selected"{{end}}>Composer</option>
<option value="conan" {{if eq .PackageType "conan"}}selected="selected"{{end}}>Conan</option>
<option value="container" {{if eq .PackageType "container"}}selected="selected"{{end}}>Container</option>
<option value="generic" {{if eq .PackageType "generic"}}selected="selected"{{end}}>Generic</option>
<option value="maven" {{if eq .PackageType "maven"}}selected="selected"{{end}}>Maven</option>
<option value="npm" {{if eq .PackageType "npm"}}selected="selected"{{end}}>npm</option>
<option value="nuget" {{if eq .PackageType "nuget"}}selected="selected"{{end}}>NuGet</option>
<option value="pypi" {{if eq .PackageType "pypi"}}selected="selected"{{end}}>PyPi</option>
<option value="rubygems" {{if eq .PackageType "rubygems"}}selected="selected"{{end}}>RubyGems</option>
</select>
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
</div>
</form>
</div>
<div class="ui attached table segment">
<table class="ui very basic striped table">
<thead>
<tr>
<th>ID</th>
<th>{{.i18n.Tr "admin.packages.owner"}}</th>
<th>{{.i18n.Tr "admin.packages.type"}}</th>
<th data-sortt-asc="alphabetically" data-sortt-desc="reversealphabetically">
{{.i18n.Tr "admin.packages.name"}}
{{SortArrow "alphabetically" "reversealphabetically" .SortType false}}
</th>
<th data-sortt-asc="highestversion" data-sortt-desc="lowestversion">
{{.i18n.Tr "admin.packages.version"}}
{{SortArrow "highestversion" "lowestversion" .SortType false}}
</th>
<th>{{.i18n.Tr "admin.packages.creator"}}</th>
<th>{{.i18n.Tr "admin.packages.repository"}}</th>
<th>{{.i18n.Tr "admin.packages.size"}}</th>
<th data-sortt-asc="oldest" data-sortt-desc="newest">
{{.i18n.Tr "admin.packages.published"}}
{{SortArrow "oldest" "newest" .SortType true}}
</th>
<th>{{.i18n.Tr "admin.notices.op"}}</th>
</tr>
</thead>
<tbody>
{{range .PackageDescriptors}}
<tr>
<td>{{.Version.ID}}</td>
<td>
<a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a>
{{if .Owner.Visibility.IsPrivate}}
<span class="text gold">{{svg "octicon-lock"}}</span>
{{end}}
</td>
<td>{{.Package.Type.Name}}</td>
<td class="text truncate email">{{.Package.Name}}</td>
<td><a href="{{.FullWebLink}}" class="text truncate email">{{.Version.Version}}</a></td>
<td><a href="{{.Creator.HomeLink}}">{{.Creator.Name}}</a></td>
<td>
{{if .Repository}}
<a href="{{.Repository.Link}}">{{.Repository.Name}}</a>
{{end}}
</td>
<td>{{FileSize .CalculateBlobSize}}</td>
<td><span title="{{.Version.CreatedUnix.FormatLong}}">{{.Version.CreatedUnix.FormatShort}}</span></td>
<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Paginater.Current}}&sort={{$.SortType}}" data-id="{{.Version.ID}}" data-name="{{.Package.Name}}" data-data-version="{{.Version.Version}}">{{svg "octicon-trash"}}</a></td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{template "base/paginate" .}}
</div>
</div>
<div class="ui small basic delete modal">
<div class="ui icon header">
{{svg "octicon-trash"}}
{{.i18n.Tr "packages.settings.delete"}}
</div>
<div class="content">
{{.i18n.Tr "packages.settings.delete.notice" `<span class="name"></span>` `<span class="dataVersion"></span>` | Safe}}
</div>
{{template "base/delete_modal_actions" .}}
</div>
{{template "base/footer" .}}

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Links for {{.PackageDescriptor.Package.Name}}</title>
</head>
<body>
<h1>Links for {{.PackageDescriptor.Package.Name}}</h1>
{{range .PackageDescriptors}}
{{$p := .}}
{{range .Files}}
<a href="{{$.RegistryURL}}/files/{{$p.Package.LowerName}}/{{$p.Version.Version}}/{{.File.Name}}#sha256-{{.Blob.HashSHA256}}"{{if $p.Metadata.RequiresPython}} data-requires-python="{{$p.Metadata.RequiresPython}}"{{end}}>{{.File.Name}}</a><br/>
{{end}}
{{end}}
</body>
</html>

View File

@@ -3,6 +3,9 @@
<a class="{{if .PageIsViewRepositories}}active{{end}} item" href="{{$.Org.HomeLink}}">
{{svg "octicon-repo"}} {{.i18n.Tr "user.repositories"}}
</a>
<a class="item" href="{{$.Org.HomeLink}}/-/packages">
{{svg "octicon-package"}} {{.i18n.Tr "packages.title"}}
</a>
{{if .IsOrganizationMember}}
<a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members">
{{svg "octicon-organization"}}&nbsp;{{$.i18n.Tr "org.people"}}

View File

@@ -0,0 +1,50 @@
{{if eq .PackageDescriptor.Package.Type "composer"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-code"}} {{.i18n.Tr "packages.composer.registry" | Safe}}</label>
<div class="markup"><pre class="code-block"><code>{
"repositories": [{
"type": "composer",
"url": "{{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/composer"
}
]
}</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.composer.install"}}</label>
<div class="markup"><pre class="code-block"><code>composer require {{.PackageDescriptor.Package.Name}}:{{.PackageDescriptor.Version.Version}}</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.composer.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if .PackageDescriptor.Metadata.Description}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">
{{.PackageDescriptor.Metadata.Description}}
</div>
{{end}}
{{if or .PackageDescriptor.Metadata.Require .PackageDescriptor.Metadata.RequireDev}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.dependencies"}}</h4>
<div class="ui attached segment">
<div class="ui list">
{{template "package/content/composer_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.Require "title" (.i18n.Tr "packages.composer.dependencies")}}
{{template "package/content/composer_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.RequireDev "title" (.i18n.Tr "packages.composer.dependencies.development")}}
</div>
</div>
{{end}}
{{if or .PackageDescriptor.Metadata.Keywords}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.keywords"}}</h4>
<div class="ui attached segment">
{{range .PackageDescriptor.Metadata.Keywords}}
{{.}}
{{end}}
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,19 @@
{{if .dependencies}}
<p><strong>{{.title}}</strong></p>
<table class="ui single line very basic table">
<thead>
<tr>
<th class="eleven wide">{{.root.i18n.Tr "packages.dependency.id"}}</th>
<th class="five wide">{{.root.i18n.Tr "packages.dependency.version"}}</th>
</tr>
</thead>
<tbody>
{{range $dependency, $version := .dependencies}}
<tr>
<td>{{$dependency}}</td>
<td>{{$version}}</td>
</tr>
{{end}}
</tbody>
</table>
{{end}}

View File

@@ -0,0 +1,34 @@
{{if eq .PackageDescriptor.Package.Type "conan"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.conan.registry"}}</label>
<div class="markup"><pre class="code-block"><code>conan remote add gitea {{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/conan</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.conan.install"}}</label>
<div class="markup"><pre class="code-block"><code>conan install --remote=gitea {{.PackageDescriptor.Package.Name}}/{{.PackageDescriptor.Version.Version}}</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.conan.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if .PackageDescriptor.Metadata.Description}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">
{{if .PackageDescriptor.Metadata.Description}}{{.PackageDescriptor.Metadata.Description}}{{end}}
</div>
{{end}}
{{if or .PackageDescriptor.Metadata.Keywords}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.keywords"}}</h4>
<div class="ui attached segment">
{{range .PackageDescriptor.Metadata.Keywords}}
{{.}}
{{end}}
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,78 @@
{{if eq .PackageDescriptor.Package.Type "container"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.container.pull"}}</label>
{{if eq .PackageDescriptor.Metadata.Type "helm"}}
<div class="markup"><pre class="code-block"><code>helm pull oci://{{.RegistryHost}}/{{.PackageDescriptor.Owner.LowerName}}/{{.PackageDescriptor.Package.LowerName}} --version {{.PackageDescriptor.Version.LowerVersion}}</code></pre></div>
{{else}}
{{$separator := ":"}}
{{if not .PackageDescriptor.Metadata.IsTagged}}
{{$separator = "@"}}
{{end}}
<div class="markup"><pre class="code-block"><code>docker pull {{.RegistryHost}}/{{.PackageDescriptor.Owner.LowerName}}/{{.PackageDescriptor.Package.LowerName}}{{$separator}}{{.PackageDescriptor.Version.LowerVersion}}</code></pre></div>
{{end}}
</div>
<div class="field">
<label>{{.i18n.Tr "packages.container.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if .PackageDescriptor.Metadata.MultiArch}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.container.multi_arch"}}</h4>
<div class="ui attached segment">
<div class="ui form">
{{range $arch, $digest := .PackageDescriptor.Metadata.MultiArch}}
<div class="field">
<label>{{svg "octicon-terminal"}} {{$arch}}</label>
{{if eq $.PackageDescriptor.Metadata.Type "oci"}}
<div class="markup"><pre class="code-block"><code>docker pull {{$.RegistryHost}}/{{$.PackageDescriptor.Owner.LowerName}}/{{$.PackageDescriptor.Package.LowerName}}@{{$digest}}</code></pre></div>
{{end}}
</div>
{{end}}
</div>
</div>
{{end}}
{{if .PackageDescriptor.Metadata.Description}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">
{{.PackageDescriptor.Metadata.Description}}
</div>
{{end}}
{{if .PackageDescriptor.Metadata.ImageLayers}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.container.layers"}}</h4>
<div class="ui attached segment">
<table id="notice-table" class="ui very basic compact table">
<tbody>
{{range .PackageDescriptor.Metadata.ImageLayers}}
<tr>
<td>{{.}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
{{if .PackageDescriptor.Metadata.Labels}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.container.labels"}}</h4>
<div class="ui attached segment">
<table id="notice-table" class="ui very basic compact table">
<thead>
<tr>
<th>{{.i18n.Tr "packages.container.labels.key"}}</th>
<th>{{.i18n.Tr "packages.container.labels.value"}}</th>
</tr>
</thead>
<tbody>
{{range $key, $value := .PackageDescriptor.Metadata.Labels}}
<tr>
<td>{{$key}}</td>
<td>{{$value}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,14 @@
{{if eq .PackageDescriptor.Package.Type "generic"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.generic.download"}}</label>
<div class="markup"><pre class="code-block"><code>curl {{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/generic/{{.PackageDescriptor.Package.Name}}/{{.PackageDescriptor.Version.Version}}/{{(index .PackageDescriptor.Files 0).File.Name}}</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.generic.documentation" | Safe}}</label>
</div>
</div>
</div>
{{end}}

View File

@@ -0,0 +1,71 @@
{{if eq .PackageDescriptor.Package.Type "maven"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-code"}} {{.i18n.Tr "packages.maven.registry" | Safe}}</label>
<div class="markup"><pre class="code-block"><code>&lt;repositories&gt;
&lt;repository&gt;
&lt;id&gt;gitea&lt;/id&gt;
&lt;url&gt;{{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/maven&lt;/url&gt;
&lt;/repository&gt;
&lt;/repositories&gt;
&lt;distributionManagement&gt;
&lt;repository&gt;
&lt;id&gt;gitea&lt;/id&gt;
&lt;url&gt;{{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/maven&lt;/url&gt;
&lt;/repository&gt;
&lt;snapshotRepository&gt;
&lt;id&gt;gitea&lt;/id&gt;
&lt;url&gt;{{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/maven&lt;/url&gt;
&lt;/snapshotRepository&gt;
&lt;/distributionManagement&gt;</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-code"}} {{.i18n.Tr "packages.maven.install" | Safe}}</label>
<div class="markup"><pre class="code-block"><code>&lt;dependency&gt;
&lt;groupId&gt;{{.PackageDescriptor.Metadata.GroupID}}&lt;/groupId&gt;
&lt;artifactId&gt;{{.PackageDescriptor.Metadata.ArtifactID}}&lt;/artifactId&gt;
&lt;version&gt;{{.PackageDescriptor.Version.Version}}&lt;/version&gt;
&lt;/dependency&gt;</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.maven.install2"}}</label>
<div class="markup"><pre class="code-block"><code>mvn install</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.maven.download"}}</label>
<div class="markup"><pre class="code-block"><code>mvn dependency:get -DremoteRepositories={{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/maven -Dartifact={{.PackageDescriptor.Metadata.GroupID}}:{{.PackageDescriptor.Metadata.ArtifactID}}:{{.PackageDescriptor.Version.Version}}</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.maven.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if .PackageDescriptor.Metadata.Description}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">
{{.PackageDescriptor.Metadata.Description}}
</div>
{{end}}
{{if .PackageDescriptor.Metadata.Dependencies}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.dependencies"}}</h4>
<div class="ui attached segment">
<div class="ui list">
{{range .PackageDescriptor.Metadata.Dependencies}}
<div class="item">
<i class="icon">{{svg "octicon-package-dependencies" 16 ""}}</i>
<div class="content">
<div class="header">{{.GroupID}}:{{.ArtifactID}}</div>
<div class="description text small">{{.Version}}</div>
</div>
</div>
{{end}}
</div>
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,56 @@
{{if eq .PackageDescriptor.Package.Type "npm"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-code"}} {{.i18n.Tr "packages.npm.registry" | Safe}}</label>
<div class="markup"><pre class="code-block"><code>{{if .PackageDescriptor.Metadata.Scope}}{{.PackageDescriptor.Metadata.Scope}}:{{end}}registry={{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/npm/</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.npm.install"}}</label>
<div class="markup"><pre class="code-block"><code>npm install {{.PackageDescriptor.Package.Name}}@{{.PackageDescriptor.Version.Version}}</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-code"}} {{.i18n.Tr "packages.npm.install2"}}</label>
<div class="markup"><pre class="code-block"><code>&quot;{{.PackageDescriptor.Package.Name}}&quot;: &quot;{{.PackageDescriptor.Version.Version}}&quot;</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.npm.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.Readme}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">
{{if .PackageDescriptor.Metadata.Readme}}
<div class="markup markdown">
{{RenderMarkdownToHtml .PackageDescriptor.Metadata.Readme}}
</div>
{{else if .PackageDescriptor.Metadata.Description}}
{{.PackageDescriptor.Metadata.Description}}
{{end}}
</div>
{{end}}
{{if or .PackageDescriptor.Metadata.Dependencies .PackageDescriptor.Metadata.DevelopmentDependencies .PackageDescriptor.Metadata.PeerDependencies .PackageDescriptor.Metadata.OptionalDependencies}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.dependencies"}}</h4>
<div class="ui attached segment">
<div class="ui list">
{{template "package/content/npm_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.Dependencies "title" (.i18n.Tr "packages.npm.dependencies")}}
{{template "package/content/npm_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.DevelopmentDependencies "title" (.i18n.Tr "packages.npm.dependencies.development")}}
{{template "package/content/npm_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.PeerDependencies "title" (.i18n.Tr "packages.npm.dependencies.peer")}}
{{template "package/content/npm_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.OptionalDependencies "title" (.i18n.Tr "packages.npm.dependencies.optional")}}
</div>
</div>
{{end}}
{{if or .PackageDescriptor.Metadata.Keywords}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.keywords"}}</h4>
<div class="ui attached segment">
{{range .PackageDescriptor.Metadata.Keywords}}
{{.}}
{{end}}
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,19 @@
{{if .dependencies}}
<p><strong>{{.title}}</strong></p>
<table class="ui single line very basic table">
<thead>
<tr>
<th class="eleven wide">{{.root.i18n.Tr "packages.dependency.id"}}</th>
<th class="five wide">{{.root.i18n.Tr "packages.dependency.version"}}</th>
</tr>
</thead>
<tbody>
{{range $dependency, $version := .dependencies}}
<tr>
<td>{{$dependency}}</td>
<td>{{$version}}</td>
</tr>
{{end}}
</tbody>
</table>
{{end}}

View File

@@ -0,0 +1,52 @@
{{if eq .PackageDescriptor.Package.Type "nuget"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.nuget.registry"}}</label>
<div class="markup"><pre class="code-block"><code>dotnet nuget add source --name Gitea --username your_username --password your_token {{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/nuget/index.json</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.nuget.install"}}</label>
<div class="markup"><pre class="code-block"><code>dotnet add package --source Gitea --version {{.PackageDescriptor.Version.Version}} {{.PackageDescriptor.Package.Name}}</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.nuget.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.ReleaseNotes}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">
{{if .PackageDescriptor.Metadata.Description}}{{.PackageDescriptor.Metadata.Description}}{{end}}
{{if .PackageDescriptor.Metadata.ReleaseNotes}}{{Str2html .PackageDescriptor.Metadata.ReleaseNotes}}{{end}}
</div>
{{end}}
{{if .PackageDescriptor.Metadata.Dependencies}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.dependencies"}}</h4>
<div class="ui attached segment">
<table class="ui single line very basic table">
<thead>
<tr>
<th class="ten wide">{{.i18n.Tr "packages.dependency.id"}}</th>
<th class="three wide">{{.i18n.Tr "packages.dependency.version"}}</th>
<th class="three wide">{{.i18n.Tr "packages.nuget.dependency.framework"}}</th>
</tr>
</thead>
<tbody>
{{range $framework, $dependencies := .PackageDescriptor.Metadata.Dependencies}}
{{range $dependencies}}
<tr>
<td>{{.ID}}</td>
<td>{{.Version}}</td>
<td>{{$framework}}</td>
</tr>
{{end}}
{{end}}
</tbody>
</table>
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,31 @@
{{if eq .PackageDescriptor.Package.Type "pypi"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.pypi.install"}}</label>
<div class="markup"><pre class="code-block"><code>pip install --extra-index-url {{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/pypi/simple {{.PackageDescriptor.Package.Name}}</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.pypi.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.LongDescription .PackageDescriptor.Metadata.Summary}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">
<p>{{if .PackageDescriptor.Metadata.Summary}}{{.PackageDescriptor.Metadata.Summary}}{{end}}</p>
{{if .PackageDescriptor.Metadata.LongDescription}}
{{RenderMarkdownToHtml .PackageDescriptor.Metadata.LongDescription}}
{{else if .PackageDescriptor.Metadata.Description}}
{{RenderMarkdownToHtml .PackageDescriptor.Metadata.Description}}
{{end}}
</div>
{{end}}
{{if .PackageDescriptor.Metadata.RequiresPython}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.requirements"}}</h4>
<div class="ui attached segment">
{{.i18n.Tr "packages.pypi.requires"}}: {{.PackageDescriptor.Metadata.RequiresPython}}
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,40 @@
{{if eq .PackageDescriptor.Package.Type "rubygems"}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.installation"}}</h4>
<div class="ui attached segment">
<div class="ui form">
<div class="field">
<label>{{svg "octicon-terminal"}} {{.i18n.Tr "packages.rubygems.install" | Safe}}:</label>
<div class="markup"><pre class="code-block"><code>gem install {{.PackageDescriptor.Package.Name}} --version &quot;{{.PackageDescriptor.Version.Version}}&quot; --source &quot;{{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/rubygems&quot;</code></pre></div>
</div>
<div class="field">
<label>{{svg "octicon-code"}} {{.i18n.Tr "packages.rubygems.install2"}}:</label>
<div class="markup"><pre class="code-block"><code>source "{{AppUrl}}api/packages/{{.PackageDescriptor.Owner.Name}}/rubygems" do
gem "{{.PackageDescriptor.Package.Name}}", "{{.PackageDescriptor.Version.Version}}"
end</code></pre></div>
</div>
<div class="field">
<label>{{.i18n.Tr "packages.rubygems.documentation" | Safe}}</label>
</div>
</div>
</div>
{{if .PackageDescriptor.Metadata.Description}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.about"}}</h4>
<div class="ui attached segment">{{.PackageDescriptor.Metadata.Description}}</div>
{{end}}
{{if or .PackageDescriptor.Metadata.RequiredRubyVersion .PackageDescriptor.Metadata.RequiredRubygemsVersion}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.requirements"}}</h4>
<div class="ui attached segment">
{{if .PackageDescriptor.Metadata.RequiredRubyVersion}}<p>{{.i18n.Tr "packages.rubygems.required.ruby"}}: {{range $i, $v := .PackageDescriptor.Metadata.RequiredRubyVersion}}{{if gt $i 0}}, {{end}}{{$v.Restriction}}{{$v.Version}}{{end}}</p>{{end}}
{{if .PackageDescriptor.Metadata.RequiredRubygemsVersion}}<p>{{.i18n.Tr "packages.rubygems.required.rubygems"}}: {{range $i, $v := .PackageDescriptor.Metadata.RequiredRubygemsVersion}}{{if gt $i 0}}, {{end}}{{$v.Restriction}}{{$v.Version}}{{end}}</p>{{end}}
</div>
{{end}}
{{if or .PackageDescriptor.Metadata.RuntimeDependencies .PackageDescriptor.Metadata.DevelopmentDependencies}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.dependencies"}}</h4>
<div class="ui attached segment">
<div class="ui list">
{{template "package/content/rubygems_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.RuntimeDependencies "title" (.i18n.Tr "packages.rubygems.dependencies.runtime")}}
{{template "package/content/rubygems_dependencies" dict "root" $ "dependencies" .PackageDescriptor.Metadata.DevelopmentDependencies "title" (.i18n.Tr "packages.rubygems.dependencies.development")}}
</div>
</div>
{{end}}
{{end}}

View File

@@ -0,0 +1,19 @@
{{if .dependencies}}
<p><strong>{{.title}}</strong></p>
<table class="ui single line very basic table">
<thead>
<tr>
<th class="eleven wide">{{.root.i18n.Tr "packages.dependency.id"}}</th>
<th class="five wide">{{.root.i18n.Tr "packages.dependency.version"}}</th>
</tr>
</thead>
<tbody>
{{range .dependencies}}
<tr>
<td>{{.Name}}</td>
<td>{{range $i, $v := .Version}}{{if gt $i 0}}, {{end}}{{$v.Restriction}}{{$v.Version}}{{end}}</td>
</tr>
{{end}}
</tbody>
</table>
{{end}}

View File

@@ -0,0 +1,5 @@
{{if eq .PackageDescriptor.Package.Type "composer"}}
{{range .PackageDescriptor.Metadata.Authors}}<div class="item" title="{{$.i18n.Tr "packages.details.author"}}">{{svg "octicon-person" 16 "mr-3"}} {{.Name}}</div>{{end}}
{{if .PackageDescriptor.Metadata.Homepage}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.Homepage}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div>{{end}}
{{range .PackageDescriptor.Metadata.License}}<div class="item" title="{{$.i18n.Tr "packages.details.license"}}">{{svg "octicon-law" 16 "mr-3"}} {{.}}</div>{{end}}
{{end}}

View File

@@ -0,0 +1,6 @@
{{if eq .PackageDescriptor.Package.Type "conan"}}
{{if .PackageDescriptor.Metadata.Author}}<div class="item" title="{{.i18n.Tr "packages.details.author"}}">{{svg "octicon-person" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Author}}</div>{{end}}
{{if .PackageDescriptor.Metadata.ProjectURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.ProjectURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div>{{end}}
{{if .PackageDescriptor.Metadata.License}}<div class="item" title="{{.i18n.Tr "packages.details.license"}}">{{svg "octicon-law" 16 "mr-3"}} {{.PackageDescriptor.Metadata.License}}</div>{{end}}
{{if .PackageDescriptor.Metadata.RepositoryURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.RepositoryURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.conan.details.repository"}}</a></div>{{end}}
{{end}}

View File

@@ -0,0 +1,9 @@
{{if eq .PackageDescriptor.Package.Type "container"}}
<div class="item" title="{{.i18n.Tr "packages.container.details.type"}}">{{svg "octicon-package" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Type.Name}}</div>
{{if .PackageDescriptor.Metadata.Platform}}<div class="item" title="{{$.i18n.Tr "packages.container.details.platform"}}">{{svg "octicon-cpu" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Platform}}</div>{{end}}
{{range .PackageDescriptor.Metadata.Authors}}<div class="item" title="{{$.i18n.Tr "packages.details.author"}}">{{svg "octicon-person" 16 "mr-3"}} {{.}}</div>{{end}}
{{if .PackageDescriptor.Metadata.Licenses}}<div class="item">{{svg "octicon-law" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Licenses}}</div>{{end}}
{{if .PackageDescriptor.Metadata.ProjectURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.ProjectURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div>{{end}}
{{if .PackageDescriptor.Metadata.RepositoryURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.RepositoryURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.container.details.repository_site"}}</a></div>{{end}}
{{if .PackageDescriptor.Metadata.DocumentationURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.DocumentationURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.container.details.documentation_site"}}</a></div>{{end}}
{{end}}

View File

View File

@@ -0,0 +1,5 @@
{{if eq .PackageDescriptor.Package.Type "maven"}}
{{if .PackageDescriptor.Metadata.Name}}<div class="item">{{svg "octicon-note" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Name}}</div>{{end}}
{{if .PackageDescriptor.Metadata.ProjectURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.ProjectURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div>{{end}}
{{range .PackageDescriptor.Metadata.Licenses}}<div class="item" title="{{$.i18n.Tr "packages.details.license"}}">{{svg "octicon-law" 16 "mr-3"}} {{.}}</div>{{end}}
{{end}}

View File

@@ -0,0 +1,8 @@
{{if eq .PackageDescriptor.Package.Type "npm"}}
{{if .PackageDescriptor.Metadata.Author}}<div class="item" title="{{.i18n.Tr "packages.details.author"}}">{{svg "octicon-person" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Author}}</div>{{end}}
{{if .PackageDescriptor.Metadata.ProjectURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.ProjectURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div>{{end}}
{{if .PackageDescriptor.Metadata.License}}<div class="item" title="{{.i18n.Tr "packages.details.license"}}">{{svg "octicon-law" 16 "mr-3"}} {{.PackageDescriptor.Metadata.License}}</div>{{end}}
{{range .PackageDescriptor.Properties}}
{{if eq .Name "npm.tag"}}<div class="item" title="{{$.i18n.Tr "packages.npm.details.tag"}}">{{svg "octicon-versions" 16 "mr-3"}} {{.Value}}</div>{{end}}
{{end}}
{{end}}

View File

@@ -0,0 +1,4 @@
{{if eq .PackageDescriptor.Package.Type "nuget"}}
{{if .PackageDescriptor.Metadata.Authors}}<div class="item" title="{{.i18n.Tr "packages.details.author"}}">{{svg "octicon-person" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Authors}}</div>{{end}}
{{if .PackageDescriptor.Metadata.ProjectURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.ProjectURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div>{{end}}
{{end}}

View File

@@ -0,0 +1,5 @@
{{if eq .PackageDescriptor.Package.Type "pypi"}}
{{if .PackageDescriptor.Metadata.Author}}<div class="item" title="{{.i18n.Tr "packages.details.author"}}">{{svg "octicon-person" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Author}}</div>{{end}}
{{if .PackageDescriptor.Metadata.ProjectURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.ProjectURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div>{{end}}
{{if .PackageDescriptor.Metadata.License}}<div class="item" title="{{.i18n.Tr "packages.details.license"}}">{{svg "octicon-law" 16 "mr-3"}} {{.PackageDescriptor.Metadata.License}}</div>{{end}}
{{end}}

View File

@@ -0,0 +1,5 @@
{{if eq .PackageDescriptor.Package.Type "rubygems"}}
{{range .PackageDescriptor.Metadata.Authors}}<div class="item" title="{{$.i18n.Tr "packages.details.author"}}">{{svg "octicon-person" 16 "mr-3"}} {{.}}</div>{{end}}
{{if .PackageDescriptor.Metadata.ProjectURL}}<div class="item">{{svg "octicon-link-external" 16 "mr-3"}} <a href="{{.PackageDescriptor.Metadata.ProjectURL}}" target="_blank" rel="noopener noreferrer me">{{.i18n.Tr "packages.details.project_site"}}</a></div> {{end}}
{{range .PackageDescriptor.Metadata.Licenses}}<div class="item" title="{{$.i18n.Tr "packages.details.license"}}">{{svg "octicon-law" 16 "mr-3"}} {{.}}</div>{{end}}
{{end}}

View File

@@ -0,0 +1,71 @@
{{template "base/head" .}}
<div class="page-content repository settings options">
{{template "user/overview/header" .}}
<div class="ui container">
{{template "base/alert" .}}
<p><a href="{{.PackageDescriptor.FullWebLink}}">{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</a> / <strong>{{.i18n.Tr "repo.settings"}}</strong></p>
<h4 class="ui top attached header">
{{.i18n.Tr "packages.settings.link"}}
</h4>
<div class="ui attached segment">
<p>{{.i18n.Tr "packages.settings.link.description"}}</p>
<form class="ui form" action="{{.Link}}" method="post">
{{template "base/disable_form_autofill"}}
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="link">
<div class="field">
<div class="ui clearable selection dropdown">
{{$repoID := 0}}
{{if .PackageDescriptor.Repository}}
{{$repoID = .PackageDescriptor.Repository.ID}}
{{end}}
<input type="hidden" name="repo_id" value="{{$repoID}}">
<i class="dropdown icon"></i>
<div class="default text">{{.i18n.Tr "packages.settings.link.select"}}</div>
<div class="menu">
{{range .Repos}}
<div class="item" data-value="{{.ID}}">{{.Name}}</div>
{{end}}
</div>
</div>
</div>
<div class="field">
<button class="ui green button">{{.i18n.Tr "packages.settings.link.button"}}</button>
</div>
</form>
</div>
<h4 class="ui top attached error header">
{{.i18n.Tr "repo.settings.danger_zone"}}
</h4>
<div class="ui attached error table danger segment">
<div class="item">
<div class="ui right">
<button class="ui basic red show-modal button" data-modal="#delete-package-modal">{{.i18n.Tr "packages.settings.delete"}}</button>
</div>
<div>
<h5>{{.i18n.Tr "packages.settings.delete"}}</h5>
<p>{{.i18n.Tr "packages.settings.delete.description"}}</p>
</div>
<div class="ui tiny modal" id="delete-package-modal">
<div class="header">
{{.i18n.Tr "packages.settings.delete"}}
</div>
<div class="content">
<div class="ui warning message text left">
{{.i18n.Tr "packages.settings.delete.notice" .PackageDescriptor.Package.Name .PackageDescriptor.Version.Version}}
</div>
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="delete">
<div class="text right actions">
<div class="ui cancel button">{{.i18n.Tr "cancel"}}</div>
<button class="ui red button">{{.i18n.Tr "ok"}}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{{template "base/footer" .}}

View File

@@ -0,0 +1,53 @@
<div class="ui container">
{{template "base/alert" .}}
<form class="ui form ignore-dirty">
<div class="ui fluid action input">
<input name="q" value="{{.Query}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<select class="ui dropdown" name="type">
<option value="">{{.i18n.Tr "packages.filter.type"}}</option>
<option value="all">{{.i18n.Tr "packages.filter.type.all"}}</option>
<option value="composer" {{if eq .PackageType "composer"}}selected="selected"{{end}}>Composer</option>
<option value="conan" {{if eq .PackageType "conan"}}selected="selected"{{end}}>Conan</option>
<option value="container" {{if eq .PackageType "container"}}selected="selected"{{end}}>Container</option>
<option value="generic" {{if eq .PackageType "generic"}}selected="selected"{{end}}>Generic</option>
<option value="maven" {{if eq .PackageType "maven"}}selected="selected"{{end}}>Maven</option>
<option value="npm" {{if eq .PackageType "npm"}}selected="selected"{{end}}>npm</option>
<option value="nuget" {{if eq .PackageType "nuget"}}selected="selected"{{end}}>NuGet</option>
<option value="pypi" {{if eq .PackageType "pypi"}}selected="selected"{{end}}>PyPi</option>
<option value="rubygems" {{if eq .PackageType "rubygems"}}selected="selected"{{end}}>RubyGems</option>
</select>
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
</div>
</form>
<div class="ui {{if .PackageDescriptors}}issue list{{end}}">
{{range .PackageDescriptors}}
<li class="item df py-3">
<div class="issue-item-main f1 fc df">
<div class="issue-item-top-row">
<a class="title" href="{{.FullWebLink}}">{{.Package.Name}}</a>
<span class="ui label">{{svg .Package.Type.SVGName 16}} {{.Package.Type.Name}}</span>
</div>
<div class="desc issue-item-bottom-row df ac fw my-1">
{{$timeStr := TimeSinceUnix .Version.CreatedUnix $.i18n.Lang}}
{{if .Repository}}
{{$.i18n.Tr "packages.published_by_in" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) .Repository.HTMLURL (.Repository.FullName | Escape) | Safe}}
{{else}}
{{$.i18n.Tr "packages.published_by" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}}
{{end}}
</div>
</div>
</li>
{{else}}
{{if not .HasPackages}}
<div class="empty center">
{{svg "octicon-package" 32}}
<h2>{{.i18n.Tr "packages.empty"}}</h2>
<p>{{.i18n.Tr "packages.empty.documentation" | Safe}}</p>
</div>
{{else}}
<p>{{.i18n.Tr "packages.filter.no_result"}}</p>
{{end}}
{{end}}
{{template "base/paginate" .}}
</div>
</div>

View File

@@ -0,0 +1,33 @@
<div class="ui container">
<p><a href="{{.PackageDescriptor.PackageWebLink}}">{{.PackageDescriptor.Package.Name}}</a> / <strong>{{.i18n.Tr "packages.versions"}}</strong></p>
<form class="ui form ignore-dirty">
<div class="ui fluid action input">
<input name="q" value="{{.Query}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
{{if eq .PackageDescriptor.Package.Type "container"}}
<select class="ui dropdown" name="tagged">
{{$isTagged := or (eq .Tagged "") (eq .Tagged "tagged")}}
<option value="tagged" {{if $isTagged}}selected="selected"{{end}}>{{.i18n.Tr "packages.filter.container.tagged"}}</option>
<option value="untagged" {{if not $isTagged}}selected="selected"{{end}}>{{.i18n.Tr "packages.filter.container.untagged"}}</option>
</select>
{{end}}
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
</div>
</form>
<div class="ui {{if .PackageDescriptors}}issue list{{end}}">
{{range .PackageDescriptors}}
<li class="item df py-3">
<div class="issue-item-main f1 fc df">
<div class="issue-item-top-row">
<a class="title" href="{{.FullWebLink}}">{{.Version.LowerVersion}}</a>
</div>
<div class="desc issue-item-bottom-row df ac fw my-1">
{{$.i18n.Tr "packages.published_by" (TimeSinceUnix .Version.CreatedUnix $.i18n.Lang) .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}}
</div>
</div>
</li>
{{else}}
<p>{{.i18n.Tr "packages.filter.no_result"}}</p>
{{end}}
{{template "base/paginate" .}}
</div>
</div>

View File

@@ -0,0 +1,94 @@
{{template "base/head" .}}
<div class="page-content repository view issue packages">
{{template "user/overview/header" .}}
<div class="ui container">
<div>
<div class="ui stackable grid">
<div class="sixteen wide column title">
<div class="issue-title">
<h1>{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</h1>
</div>
<div>
{{$timeStr := TimeSinceUnix .PackageDescriptor.Version.CreatedUnix $.i18n.Lang}}
{{if .PackageDescriptor.Repository}}
{{.i18n.Tr "packages.published_by_in" $timeStr .PackageDescriptor.Creator.HomeLink (.PackageDescriptor.Creator.GetDisplayName | Escape) .PackageDescriptor.Repository.HTMLURL (.PackageDescriptor.Repository.FullName | Escape) | Safe}}
{{else}}
{{.i18n.Tr "packages.published_by" $timeStr .PackageDescriptor.Creator.HomeLink (.PackageDescriptor.Creator.GetDisplayName | Escape) | Safe}}
{{end}}
</div>
<div class="ui divider"></div>
</div>
<div class="twelve wide column">
{{template "package/content/composer" .}}
{{template "package/content/conan" .}}
{{template "package/content/container" .}}
{{template "package/content/generic" .}}
{{template "package/content/nuget" .}}
{{template "package/content/npm" .}}
{{template "package/content/maven" .}}
{{template "package/content/pypi" .}}
{{template "package/content/rubygems" .}}
</div>
<div class="four wide column">
<div class="ui segment metas">
<strong>{{.i18n.Tr "packages.details"}}</strong>
<div class="ui relaxed list">
<div class="item">{{svg .PackageDescriptor.Package.Type.SVGName 16 "mr-3"}} {{.PackageDescriptor.Package.Type.Name}}</div>
{{if .PackageDescriptor.Repository}}
<div class="item">{{svg "octicon-repo" 16 "mr-3"}} <a href="{{.PackageDescriptor.Repository.HTMLURL}}">{{.PackageDescriptor.Repository.FullName}}</a></div>
{{end}}
<div class="item">{{svg "octicon-calendar" 16 "mr-3"}} {{.PackageDescriptor.Version.CreatedUnix.FormatDate}}</div>
<div class="item">{{svg "octicon-download" 16 "mr-3"}} {{.PackageDescriptor.Version.DownloadCount}}</div>
{{template "package/metadata/composer" .}}
{{template "package/metadata/conan" .}}
{{template "package/metadata/container" .}}
{{template "package/metadata/generic" .}}
{{template "package/metadata/nuget" .}}
{{template "package/metadata/npm" .}}
{{template "package/metadata/maven" .}}
{{template "package/metadata/pypi" .}}
{{template "package/metadata/rubygems" .}}
</div>
{{if not (eq .PackageDescriptor.Package.Type "container")}}
<div class="ui divider"></div>
<strong>{{.i18n.Tr "packages.assets"}} ({{len .PackageDescriptor.Files}})</strong>
<div class="ui relaxed list">
{{range .PackageDescriptor.Files}}
<div class="item">
<a href="{{$.Link}}/files/{{.File.ID}}">{{.File.Name}}</a>
<span class="text small file-size">{{FileSize .Blob.Size}}</span>
</div>
{{end}}
</div>
{{end}}
{{if .LatestVersions}}
<div class="ui divider"></div>
<strong>{{.i18n.Tr "packages.versions"}} ({{.TotalVersionCount}})</strong>
<a class="ui right" href="{{$.PackageDescriptor.PackageWebLink}}/versions">{{.i18n.Tr "packages.versions.view_all"}}</a>
<div class="ui relaxed list">
{{range .LatestVersions}}
<div class="item">
<a href="{{$.PackageDescriptor.PackageWebLink}}/{{PathEscape .LowerVersion}}">{{.Version}}</a>
<span class="text small">{{$.i18n.Tr "packages.versions.on"}} {{.CreatedUnix.FormatDate}}</span>
</div>
{{end}}
</div>
{{end}}
{{if or .CanWritePackages .PackageDescriptor.Repository}}
<div class="ui divider"></div>
<div class="ui relaxed list">
{{if .PackageDescriptor.Repository}}
<div class="item">{{svg "octicon-issue-opened" 16 "mr-3"}} <a href="{{.PackageDescriptor.Repository.HTMLURL}}/issues">{{.i18n.Tr "repo.issues"}}</a></div>
{{end}}
{{if .CanWritePackages}}
<div class="item">{{svg "octicon-tools" 16 "mr-3"}} <a href="{{.Link}}/settings">{{.i18n.Tr "repo.settings"}}</a></div>
{{end}}
</div>
{{end}}
</div>
</div>
</div>
</div>
</div>
</div>
{{template "base/footer" .}}

View File

@@ -177,6 +177,10 @@
</a>
{{end}}
<a href="{{.RepoLink}}/packages" class="{{ if .IsPackagesPage }}active{{end}} item">
{{svg "octicon-package"}} {{.i18n.Tr "packages.title"}}
</a>
{{ if and (not .UnitProjectsGlobalDisabled) (.Permission.CanRead $.UnitTypeProjects)}}
<a href="{{.RepoLink}}/projects" class="{{ if .IsProjectsPage }}active{{end}} item">
{{svg "octicon-project"}} {{.i18n.Tr "repo.project_board"}}

View File

@@ -0,0 +1,6 @@
{{template "base/head" .}}
<div class="page-content repository packages">
{{template "repo/header" .}}
{{template "package/shared/list" .}}
</div>
{{template "base/footer" .}}

View File

@@ -87,6 +87,16 @@
</div>
</div>
</div>
<!-- Package -->
<div class="seven wide column">
<div class="field">
<div class="ui checkbox">
<input class="hidden" name="package" type="checkbox" tabindex="0" {{if .Webhook.Package}}checked{{end}}>
<label>{{.i18n.Tr "repo.settings.event_package"}}</label>
<span class="help">{{.i18n.Tr "repo.settings.event_package_desc"}}</span>
</div>
</div>
</div>
<!-- Issue Events -->
<div class="fourteen wide column">

View File

@@ -1870,6 +1870,211 @@
}
}
},
"/packages/{owner}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"package"
],
"summary": "Gets all packages of an owner",
"operationId": "listPackages",
"parameters": [
{
"type": "string",
"description": "owner of the packages",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "page number of results to return (1-based)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "page size of results",
"name": "limit",
"in": "query"
},
{
"enum": [
"composer",
"conan",
"generic",
"maven",
"npm",
"nuget",
"pypi",
"rubygems"
],
"type": "string",
"description": "package type filter",
"name": "type",
"in": "query"
},
{
"type": "string",
"description": "name filter",
"name": "q",
"in": "query"
}
],
"responses": {
"200": {
"$ref": "#/responses/PackageList"
}
}
}
},
"/packages/{owner}/{type}/{name}/{version}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"package"
],
"summary": "Gets a package",
"operationId": "getPackage",
"parameters": [
{
"type": "string",
"description": "owner of the package",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "type of the package",
"name": "type",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the package",
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "version of the package",
"name": "version",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/Package"
},
"404": {
"$ref": "#/responses/notFound"
}
}
},
"delete": {
"tags": [
"package"
],
"summary": "Delete a package",
"operationId": "deletePackage",
"parameters": [
{
"type": "string",
"description": "owner of the package",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "type of the package",
"name": "type",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the package",
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "version of the package",
"name": "version",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"$ref": "#/responses/empty"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/packages/{owner}/{type}/{name}/{version}/files": {
"get": {
"produces": [
"application/json"
],
"tags": [
"package"
],
"summary": "Gets all files of a package",
"operationId": "listPackageFiles",
"parameters": [
{
"type": "string",
"description": "owner of the package",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "type of the package",
"name": "type",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the package",
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "version of the package",
"name": "version",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/PackageFileList"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/repos/issues/search": {
"get": {
"produces": [
@@ -16575,6 +16780,80 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"Package": {
"description": "Package represents a package",
"type": "object",
"properties": {
"created_at": {
"type": "string",
"format": "date-time",
"x-go-name": "CreatedAt"
},
"creator": {
"$ref": "#/definitions/User"
},
"id": {
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"name": {
"type": "string",
"x-go-name": "Name"
},
"owner": {
"$ref": "#/definitions/User"
},
"repository": {
"$ref": "#/definitions/Repository"
},
"type": {
"type": "string",
"x-go-name": "Type"
},
"version": {
"type": "string",
"x-go-name": "Version"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"PackageFile": {
"description": "PackageFile represents a package file",
"type": "object",
"properties": {
"Size": {
"type": "integer",
"format": "int64"
},
"id": {
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"md5": {
"type": "string",
"x-go-name": "HashMD5"
},
"name": {
"type": "string",
"x-go-name": "Name"
},
"sha1": {
"type": "string",
"x-go-name": "HashSHA1"
},
"sha256": {
"type": "string",
"x-go-name": "HashSHA256"
},
"sha512": {
"type": "string",
"x-go-name": "HashSHA512"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"PayloadCommit": {
"description": "PayloadCommit represents a commit",
"type": "object",
@@ -18688,6 +18967,30 @@
"$ref": "#/definitions/OrganizationPermissions"
}
},
"Package": {
"description": "Package",
"schema": {
"$ref": "#/definitions/Package"
}
},
"PackageFileList": {
"description": "PackageFileList",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/PackageFile"
}
}
},
"PackageList": {
"description": "PackageList",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Package"
}
}
},
"PublicKey": {
"description": "PublicKey",
"schema": {

View File

@@ -0,0 +1,25 @@
<div class="header-wrapper">
<div class="ui container">
<div class="repo-header">
<div class="repo-title-wrap df fc">
<div class="repo-title">
{{avatar .ContextUser 32}}
<a href="{{.ContextUser.HTMLURL}}">{{.ContextUser.Name}}</a>
</div>
</div>
</div>
</div>
<div class="ui tabs container">
<div class="ui tabular stackable menu navbar">
<a class="item" href="{{.ContextUser.HomeLink}}">
{{svg "octicon-repo"}} {{.i18n.Tr "user.repositories"}}
</a>
{{if (not .UnitPackagesGlobalDisabled)}}
<a href="{{.ContextUser.HTMLURL}}/-/packages" class="{{if .IsPackagesPage}}active{{end}} item">
{{svg "octicon-package"}} {{.i18n.Tr "packages.title"}}
</a>
{{end}}
</div>
</div>
<div class="ui tabs divider"></div>
</div>

View File

@@ -0,0 +1,6 @@
{{template "base/head" .}}
<div class="page-content repository packages">
{{template "user/overview/header" .}}
{{template "package/shared/versionlist" .}}
</div>
{{template "base/footer" .}}

View File

@@ -0,0 +1,6 @@
{{template "base/head" .}}
<div class="page-content repository packages">
{{template "user/overview/header" .}}
{{template "package/shared/list" .}}
</div>
{{template "base/footer" .}}

View File

@@ -87,6 +87,9 @@
<a class='{{if and (ne .TabName "activity") (ne .TabName "following") (ne .TabName "followers") (ne .TabName "stars") (ne .TabName "watching") (ne .TabName "projects")}}active{{end}} item' href="{{.Owner.HomeLink}}">
{{svg "octicon-repo"}} {{.i18n.Tr "user.repositories"}}
</a>
<a class='{{if eq .TabName "packages"}}active{{end}} item' href="{{.Owner.HomeLink}}/-/packages">
{{svg "octicon-package"}} {{.i18n.Tr "packages.title"}}
</a>
<a class='{{if eq .TabName "activity"}}active{{end}} item' href="{{.Owner.HomeLink}}?tab=activity">
{{svg "octicon-rss"}} {{.i18n.Tr "user.activity"}}
</a>