Skip to content

Commit

Permalink
Add Conda package registry (#22262)
Browse files Browse the repository at this point in the history
This PR adds a [Conda](https://conda.io/) package registry.
  • Loading branch information
KN4CK3R committed Feb 1, 2023
1 parent 5882e17 commit 6ba9ff7
Show file tree
Hide file tree
Showing 24 changed files with 1,244 additions and 3 deletions.
2 changes: 2 additions & 0 deletions custom/conf/app.example.ini
Expand Up @@ -2458,6 +2458,8 @@ ROUTER = console
;LIMIT_SIZE_COMPOSER = -1
;; Maximum size of a Conan upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
;LIMIT_SIZE_CONAN = -1
;; Maximum size of a Conda upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
;LIMIT_SIZE_CONDA = -1
;; Maximum size of a Container upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
;LIMIT_SIZE_CONTAINER = -1
;; Maximum size of a Generic upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
Expand Down
1 change: 1 addition & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Expand Up @@ -1214,6 +1214,7 @@ Task queue configuration has been moved to `queue.task`. However, the below conf
- `LIMIT_TOTAL_OWNER_SIZE`: **-1**: Maximum size of packages a single owner can use (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_COMPOSER`: **-1**: Maximum size of a Composer upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_CONAN`: **-1**: Maximum size of a Conan upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_CONDA`: **-1**: Maximum size of a Conda upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_CONTAINER`: **-1**: Maximum size of a Container upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_GENERIC`: **-1**: Maximum size of a Generic upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_HELM`: **-1**: Maximum size of a Helm upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
Expand Down
85 changes: 85 additions & 0 deletions docs/content/doc/packages/conda.en-us.md
@@ -0,0 +1,85 @@
---
date: "2022-12-28T00:00:00+00:00"
title: "Conda Packages Repository"
slug: "packages/conda"
draft: false
toc: false
menu:
sidebar:
parent: "packages"
name: "Conda"
weight: 25
identifier: "conda"
---

# Conda Packages Repository

Publish [Conda](https://docs.conda.io/en/latest/) packages for your user or organization.

**Table of Contents**

{{< toc >}}

## Requirements

To work with the Conda package registry, you need to use [conda](https://docs.conda.io/projects/conda/en/stable/user-guide/install/index.html).

## Configuring the package registry

To register the package registry and provide credentials, edit your `.condarc` file:

```yaml
channel_alias: https://gitea.example.com/api/packages/{owner}/conda
channels:
- https://gitea.example.com/api/packages/{owner}/conda
default_channels:
- https://gitea.example.com/api/packages/{owner}/conda
```

| Placeholder | Description |
| ------------ | ----------- |
| `owner` | The owner of the package. |

See the [official documentation](https://conda.io/projects/conda/en/latest/user-guide/configuration/use-condarc.html) for explanations of the individual settings.

If you need to provide credentials, you may embed them as part of the channel url (`https://user:password@gitea.example.com/...`).

## Publish a package

To publish a package, perform a HTTP PUT operation with the package content in the request body.

```
PUT https://gitea.example.com/api/packages/{owner}/conda/{channel}/{filename}
```

| Placeholder | Description |
| ------------ | ----------- |
| `owner` | The owner of the package. |
| `channel` | The [channel](https://conda.io/projects/conda/en/latest/user-guide/concepts/channels.html) of the package. (optional) |
| `filename` | The name of the file. |

Example request using HTTP Basic authentication:

```shell
curl --user your_username:your_password_or_token \
--upload-file path/to/package-1.0.conda \
https://gitea.example.com/api/packages/testuser/conda/package-1.0.conda
```

You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first.

## Install a package

To install a package from the package registry, execute one of the following commands:

```shell
conda install {package_name}
conda install {package_name}={package_version}
conda install -c {channel} {package_name}
```

| Parameter | Description |
| ----------------- | ----------- |
| `package_name` | The package name. |
| `package_version` | The package version. |
| `channel` | The channel of the package. (optional) |
1 change: 1 addition & 0 deletions docs/content/doc/packages/overview.en-us.md
Expand Up @@ -28,6 +28,7 @@ The following package managers are currently supported:
| ---- | -------- | -------------- |
| [Composer]({{< relref "doc/packages/composer.en-us.md" >}}) | PHP | `composer` |
| [Conan]({{< relref "doc/packages/conan.en-us.md" >}}) | C++ | `conan` |
| [Conda]({{< relref "doc/packages/conda.en-us.md" >}}) | - | `conda` |
| [Container]({{< relref "doc/packages/container.en-us.md" >}}) | - | any OCI compliant client |
| [Generic]({{< relref "doc/packages/generic.en-us.md" >}}) | - | any HTTP client |
| [Helm]({{< relref "doc/packages/helm.en-us.md" >}}) | - | any HTTP client, `cm-push` |
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -26,6 +26,7 @@ require (
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
github.com/djherbis/buffer v1.2.0
github.com/djherbis/nio/v3 v3.0.1
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5
github.com/dustin/go-humanize v1.0.0
github.com/editorconfig/editorconfig-core-go/v2 v2.5.1
github.com/emersion/go-imap v1.2.1
Expand Down Expand Up @@ -161,7 +162,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
Expand Down
63 changes: 63 additions & 0 deletions models/packages/conda/search.go
@@ -0,0 +1,63 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package conda

import (
"context"
"strings"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/packages"
conda_module "code.gitea.io/gitea/modules/packages/conda"

"xorm.io/builder"
)

type FileSearchOptions struct {
OwnerID int64
Channel string
Subdir string
Filename string
}

// SearchFiles gets all files matching the search options
func SearchFiles(ctx context.Context, opts *FileSearchOptions) ([]*packages.PackageFile, error) {
var cond builder.Cond = builder.Eq{
"package.type": packages.TypeConda,
"package.owner_id": opts.OwnerID,
"package_version.is_internal": false,
}

if opts.Filename != "" {
cond = cond.And(builder.Eq{
"package_file.lower_name": strings.ToLower(opts.Filename),
})
}

var versionPropsCond builder.Cond = builder.Eq{
"package_property.ref_type": packages.PropertyTypePackage,
"package_property.name": conda_module.PropertyChannel,
"package_property.value": opts.Channel,
}

cond = cond.And(builder.In("package.id", builder.Select("package_property.ref_id").Where(versionPropsCond).From("package_property")))

var filePropsCond builder.Cond = builder.Eq{
"package_property.ref_type": packages.PropertyTypeFile,
"package_property.name": conda_module.PropertySubdir,
"package_property.value": opts.Subdir,
}

cond = cond.And(builder.In("package_file.id", builder.Select("package_property.ref_id").Where(filePropsCond).From("package_property")))

sess := db.GetEngine(ctx).
Select("package_file.*").
Table("package_file").
Join("INNER", "package_version", "package_version.id = package_file.version_id").
Join("INNER", "package", "package.id = package_version.package_id").
Where(cond)

pfs := make([]*packages.PackageFile, 0, 10)
return pfs, sess.Find(&pfs)
}
3 changes: 3 additions & 0 deletions models/packages/descriptor.go
Expand Up @@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/packages/composer"
"code.gitea.io/gitea/modules/packages/conan"
"code.gitea.io/gitea/modules/packages/conda"
"code.gitea.io/gitea/modules/packages/container"
"code.gitea.io/gitea/modules/packages/helm"
"code.gitea.io/gitea/modules/packages/maven"
Expand Down Expand Up @@ -132,6 +133,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
metadata = &composer.Metadata{}
case TypeConan:
metadata = &conan.Metadata{}
case TypeConda:
metadata = &conda.VersionMetadata{}
case TypeContainer:
metadata = &container.Metadata{}
case TypeGeneric:
Expand Down
6 changes: 6 additions & 0 deletions models/packages/package.go
Expand Up @@ -32,6 +32,7 @@ type Type string
const (
TypeComposer Type = "composer"
TypeConan Type = "conan"
TypeConda Type = "conda"
TypeContainer Type = "container"
TypeGeneric Type = "generic"
TypeHelm Type = "helm"
Expand All @@ -47,6 +48,7 @@ const (
var TypeList = []Type{
TypeComposer,
TypeConan,
TypeConda,
TypeContainer,
TypeGeneric,
TypeHelm,
Expand All @@ -66,6 +68,8 @@ func (pt Type) Name() string {
return "Composer"
case TypeConan:
return "Conan"
case TypeConda:
return "Conda"
case TypeContainer:
return "Container"
case TypeGeneric:
Expand Down Expand Up @@ -97,6 +101,8 @@ func (pt Type) SVGName() string {
return "gitea-composer"
case TypeConan:
return "gitea-conan"
case TypeConda:
return "gitea-conda"
case TypeContainer:
return "octicon-container"
case TypeGeneric:
Expand Down

0 comments on commit 6ba9ff7

Please sign in to comment.