42 Commits
1.1.0 ... main

Author SHA1 Message Date
cbe5614794 fixes the push 2025-07-14 17:12:15 +01:00
f03c56fead Merge branch 'main' of gitea.pschneider.fr:paul/isn 2025-07-08 17:47:24 +01:00
26e253a3ab get prereleases from restoration by default
Fixes the .nupkgs pushes
2025-07-08 17:46:11 +01:00
6d0ec6d8a8 get prerelease from restoration by default 2025-07-07 15:52:03 +01:00
b97f3d3575 Bump to net9.0 2025-07-07 15:26:19 +01:00
9f357b4b0e logging 2025-07-07 13:07:02 +01:00
dc54df19a6 re testing 2025-07-07 11:51:02 +01:00
1224d27caa test upgrade 2025-07-07 09:36:41 +01:00
f91557ba05 WIP 2025-07-07 09:32:35 +01:00
a483804ac2 init a debian package 2025-06-08 01:33:29 +01:00
ee5a3cd775 get the package ignoring character case 2025-03-04 15:50:44 +00:00
5f7a346d8a implements the Web API deletion 2025-03-04 15:50:07 +00:00
94c850c293 Typo 2025-03-04 14:41:17 +00:00
301a276a7b Find package versions ignoring character case 2025-03-04 14:28:29 +00:00
bc1464db7f Web search result fixed 2025-02-01 19:44:31 +00:00
913f2ae5dd Layout 2024-11-03 16:20:43 +00:00
27ad3841a0 Fixes he layout 2024-11-03 16:10:03 +00:00
a6f9d974d3 Licence 2024-11-03 13:30:21 +00:00
a3d3e51259 uodated : usefull 2024-11-03 11:12:48 +00:00
753f54dad0 Home index 2024-11-02 15:49:26 +00:00
72ecf30458 repo cleanup 2024-10-20 19:54:36 +01:00
5f1dca3d61 dotnet package resolution 2024-10-20 19:47:49 +01:00
c615886a4c unit testing 2024-10-19 13:25:58 +01:00
2b45e421dd GetMetaData OK 2024-10-09 23:19:38 +01:00
7ca465d4a9 JQuery version bump 2024-07-28 14:07:06 +01:00
8532b81638 WIP package resolution 2024-07-19 10:21:25 +02:00
01405abdf2 Package deletion and types 2024-04-28 15:44:12 +01:00
62a8bf27cb Error Page 2024-04-28 15:43:10 +01:00
9c9ee6cc4c trying with isn.abst 2024-04-22 21:51:06 +01:00
3af05fc034 dependencies 2024-04-16 22:30:39 +01:00
04a467dd83 registration and detail url's 2024-03-31 15:59:43 +01:00
96f91c3ba0 net-8, localization, privacy, and js ref's 2024-03-30 09:45:17 +00:00
aeecc524a4 WIP /search 2024-03-24 16:53:12 +00:00
e229439174 Fixes the registration page index 2024-03-16 14:33:10 +00:00
c6c52a48c4 some details 2024-03-11 20:55:52 +00:00
8656bce151 fixes the catalog page 2024-03-11 01:02:11 +00:00
d6180aa154 REORG 2024-03-10 20:10:05 +00:00
89e1b5a235 Testing the push method (TODO coherence between return code a physical result) 2024-03-09 21:43:56 +00:00
e69462999e Cx strings contains user secrets ... 2024-03-09 16:13:30 +00:00
e1a012e15b orthograph 2024-02-12 02:45:47 +00:00
16258d1c33 version bumps 2024-02-12 02:22:10 +00:00
019d858ac2 fixes the chown 2024-02-12 02:21:50 +00:00
1691 changed files with 237279 additions and 3484 deletions

7
.gitignore vendored
View File

@ -6,14 +6,8 @@
/src/isn/.vscode/
/test/isnd.tests/obj/
/test/isnd.tests/bin/
/packages/
bower_components/
/test/isn.tests/bin
/test/isn.tests/obj/
appsettings.Testing.json
appsettings.Development.json
/wwwroot/.sass-cache/
/src/isnd/wwwroot/.sass-cache/
/src/isn.abst/bin
/src/isn.abst/obj
/src/isnd/packages/
@ -23,4 +17,5 @@ appsettings.Development.json
/artifacts/
/.vs/
/.vscode/
appsettings.Development.json

52
.vscode/tasks.json vendored
View File

@ -1,19 +1,6 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "restore",
"command": "dotnet",
"type": "process",
"args": [
"restore",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"--ignore-failed-sources"
],
"problemMatcher": "$msCompile",
"group": "build"
},
{
"label": "build",
"command": "dotnet",
@ -46,21 +33,6 @@
"dependsOn":["build"],
"group": "test"
},
{
"label": "buildcli",
"command": "msbuild",
"type": "process",
"args": [
"src/isn",
"/p:Configuration=Debug",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"/restore"
],
"problemMatcher": "$msCompile",
"group": "build"
},
{
"label": "publish",
"command": "dotnet",
@ -79,31 +51,13 @@
},
"group": "none"
},
{
"label": "monopublish",
"command": "msbuild",
"type": "process",
"args": [
"/t:publish",
"/p:TargetFramework=netcoreapp2.1;PublishDir=${workspaceFolder}/artiffacts;RuntimeIdentifier=linux-x64",
],
"problemMatcher": "$msCompile"
},
{
"label": "copyTestConfig",
"command": "dotnet",
"type": "process",
"args": [ "build", "/t:CopyTestConfig" ],
"group": "test"
},
{
"label": "test",
"command": "dotnet",
"type": "process",
"options": {
"env": {
"ASPNETCORE_ENVIRONMENT": "Testing"
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"args": [
@ -112,7 +66,7 @@
"--logger:xunit"
],
"problemMatcher": "$msCompile",
"dependsOn": [ "build", "copyTestConfig"],
"dependsOn": [ "build"],
"group": "test"
},
{
@ -130,7 +84,7 @@
}
},
"problemMatcher": "$msCompile",
"group": "test"
"group": "none"
}
]
}

10
Directory.Build.props Normal file
View File

@ -0,0 +1,10 @@
<Project>
<PropertyGroup>
<Version>1.0.8</Version>
<Authors>paul</Authors>
<Copyright>WFPL</Copyright>
<ProjectUrl></ProjectUrl>
<RepositoryUrl></RepositoryUrl>
<RepositoryType>git</RepositoryType>
</PropertyGroup>
</Project>

View File

@ -1,5 +0,0 @@
mode: Mainline
branches: {}
ignore:
sha: []
merge-message-formats: {}

View File

@ -1,6 +1,6 @@
CONFIGURATION=Debug
TARGETFV=net7.0
TARGETFV=net8.0
all: build-isn build-isnd
@ -16,17 +16,34 @@ watch:
test-push:
isn push src/isn/bin/Debug/isn.*.nupkg
clean-%: src/%
clean-src-%: src/%
rm -rf $^/bin $^/obj
clean-test-%: test/%
rm -rf $^/bin $^/obj
packs: pack-isn pack-isnd pack-isn.abst
clean: clean-isnd clean-isn clean-isn.abst
clean: clean-src-isnd clean-src-isn clean-src-isn.abst clean-test-isnd.tests clean-test-isn.tests
TARGETFRAMEWORK=net9.0
server-update:
dotnet build -c Release
dotnet publish -c Release -f net7.0 src/isnd
dotnet build -c Release src/isnd
dotnet publish -c Release -f $(TARGETFRAMEWORK) src/isnd
sudo systemctl stop isnd
sudo cp -a src/isnd/bin/Release/net7.0/publish/* /srv/www/isnd
sudo cp -a src/isnd/bin/Release/$(TARGETFRAMEWORK)/publish/* /srv/www/isnd
sudo systemctl start isnd
client-update:
dotnet build -c Release src/isn
# MAJ du client
sudo cp -a src/isn/bin/Release/$(TARGETFRAMEWORK)/* /usr/local/lib/isn
sudo chown -R root:root /usr/local/lib/isn
src/isn.abst/bin/Release/isn.abst.1.0.24.nupkg:
dotnet pack src/isn.abst -c Release
push-test: src/isn.abst/bin/Release/isn.abst.1.0.24.nupkg
isn push -s "http://localhost:3002/v3/index.json" src/isn.abst/bin/Release/isn.abst.1.0.24.nupkg

View File

@ -1,6 +1,6 @@
# ISN
En cours de developement, le détail du paquet n'est toujours pas fourni en API.
Hébergement de paquets logiciels Nuget, fournissant une implémentation minimale de l'API Nuget V3
## Usage
@ -20,21 +20,22 @@ wget http://localhost:5000/package/index.json?q=your&prerelease=true&semVerLevel
### Compilation
Depuis le dossier de la solution, compiler la solution :
Dans le dossier de la solution, compiler la solution :
````bash
dotnet build /restore -c Release
dotnet publish -c Release
dotnet publish -c Release src/isnd
````
### Déploiement du serveur
Commençont par la livraison initiale, aujourd'hui :
La livraison initiale, aujourd'hui :
````bash
sudo mkdir -p /srv/www/isnd
sudo cp -a src/isnd/bin/Release/net7.0/publish/* /srv/www/isnd
sudo cp -a src/isnd/bin/Release/net9.0/publish/* /srv/www/isnd
sudo cp contrib/isnd.service /etc/systemd/system
chown -R isn:isn /srv/www/isnd/
sudo systemctl daemon-reload
````
@ -43,13 +44,13 @@ son utilisateur, et le droit de créer des tables (ce dernier droit pourrait exp
Il faudra éditer la configuration pour indiquer :
* la connextion à une base de donnée Postresgql, sous la forme :
* dans /etc/systemd/system/isnd.service , la connextion à une base de donnée Postresgql, sous la forme :
`"Server=<pgserver>;Port=<pgport>;Database=<dbname>;Username=<dbusername>;Password=<dbpass>;"`
* la connection au serveur de messagerie,
* l'URL du ou des sites à propulser,
* Les autres détails.
* dans /srv/www/isnd/appsettings.Production.json, la connection au serveur de messagerie,
* l'URL externe du ou des sites à propulser, et à utiliser dans la description de service,
* et les autres détails.
Pour faire ceci, vous pourrez éditer une copie du fichier `appsettings.json` vers `appsettings.Production.json`,
Pour faire ceci, vous pourrez éditer une copie du fichier `appsettings.json` vers `appsettings.Production.json`,
pour renseigner toutes les valeurs spécifiées.
* Démarrer le serveur :
@ -75,15 +76,25 @@ sudo ln -s /usr/local/lib/isn/isn /usr/local/bin/isn
### Mises à jour
Dans le détail, la séquence serait du style :
````bash
# compiler tout
dotnet build -c Release
dotnet publish -c Release -f net7.0 src/isnd
dotnet publish -c Release -f net9.0 src/isnd
# MAJ du serveur
sudo systemctl stop isnd
sudo cp -a src/isnd/bin/Release/net7.0/publish/* /srv/www/isnd
sudo cp -a src/isnd/bin/Release/net9.0/publish/* /srv/www/isnd
sudo systemctl start isnd
# MAJ du client
sudo cp -a src/isn/bin/Release/net7.0/* /usr/local/lib/isn
sudo chown -R root.root /usr/local/lib/isn
sudo cp -a src/isn/bin/Release/net9.0/* /usr/local/lib/isn
sudo chown -R root:root /usr/local/lib/isn
````
On pourra cibler "client-update" ou "server-update", à la construction :
````bash
make server-update
make client-update
````

View File

@ -1,28 +0,0 @@
[Unit]
Description=isnd - a Nuget package repository daemon
After=syslog.target
After=network.target
Wants=postgresql.service
After=postgresql.service
[Service]
RestartSec=5s
Type=simple
User=isn
Group=isn
WorkingDirectory=/srv/www/isnd/
# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file
# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
#RuntimeDirectory=gitea
ExecStart=/srv/www/isnd/isnd
Restart=always
Environment=HOME=/srv/www/isnd
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<apikeys>
</apikeys>
<packageSources>
<add key="myIsnDev" value="http://localhost:5000/index.json" protocolVersion="3" />
</packageSources>
</configuration>

View File

@ -1,2 +0,0 @@
nuget install -Verbosity detailed -Source http://localhost:5000/index.json -Prerelease Yavsc.Abstract
nuget locals all -clear

View File

@ -1,4 +0,0 @@
= URL's
<http://localhost:5000/v3.4.0/registration/yavsc.abstract/index.json>

8
debian/README.Debian vendored Normal file
View File

@ -0,0 +1,8 @@
yavsc for Debian
Please edit this to provide information specific to
this yavsc Debian package.
(Automatically generated by debmake Version 4.5.1)
-- Paul Schneider <paul@localhost> Sun, 08 Jun 2025 01:41:54 +0100

14
debian/README.source vendored Normal file
View File

@ -0,0 +1,14 @@
yavsc for Debian
See Debian policy manual section 4.14.
https://www.debian.org/doc/debian-policy/ch-source.html#source-package-handling-debian-readme-source
If running dpkg-source -x on a source package doesnt produce the source of the
package, ready for editing, and allow one to make changes and run
dpkg-buildpackage to produce a modified package without taking any additional
steps, creating this file explain how to do all of these is recommended.
Otherwise, remove this file.
(Automatically generated by debmake Version 4.5.1)
-- Paul Schneider <paul@localhost> Sun, 08 Jun 2025 01:41:54 +0100

6
debian/changelog vendored Normal file
View File

@ -0,0 +1,6 @@
yavsc (1.1.0-1) UNRELEASED; urgency=low
* Initial release. Closes: #nnnn
<nnnn is the bug number of your ITP>
-- Paul Schneider <paul@localhost> Sun, 08 Jun 2025 01:41:54 +0100

1
debian/clean vendored Normal file
View File

@ -0,0 +1 @@
# You must remove unused comment lines for the released package.

21
debian/control vendored Normal file
View File

@ -0,0 +1,21 @@
Source: yavsc
Section: unknown
Priority: optional
Maintainer: Paul Schneider <paul@localhost>
Build-Depends:
debhelper-compat (= 13),
Standards-Version: 4.7.0
Homepage: <insert the upstream URL, if relevant>
Rules-Requires-Root: no
#Vcs-Git: https://salsa.debian.org/debian/yavsc.git
#Vcs-Browser: https://salsa.debian.org/debian/yavsc
Package: yavsc
Architecture: any
Multi-Arch: foreign
Depends:
${misc:Depends},
${shlibs:Depends},
Description: auto-generated package by debmake
This Debian binary package was auto-generated by the
debmake(1) command provided by the debmake package.

2092
debian/copyright vendored Normal file

File diff suppressed because it is too large Load Diff

2
debian/dirs vendored Normal file
View File

@ -0,0 +1,2 @@
# You must remove unused comment lines for the released package.

2
debian/gbp.conf vendored Normal file
View File

@ -0,0 +1,2 @@
[DEFAULT]
upstream-tag=v%(version)s

2
debian/install vendored Normal file
View File

@ -0,0 +1,2 @@
# You must remove unused comment lines for the released package.

2
debian/links vendored Normal file
View File

@ -0,0 +1,2 @@
# You must remove unused comment lines for the released package.

7
debian/maintscript.ex vendored Normal file
View File

@ -0,0 +1,7 @@
# see: dh_installdeb(1), dpkg-maintscript-helper(1)
# For renaming a conffile, you are advised to uncomment and edit the following
#dpkg-maintscript-helper mv_conffile old-conffile new-conffile prior-version package
# For switching a symlink to directory, you are advised to uncomment and edit the following
#dpkg-maintscript-helper symlink_to_dir pathname old-target prior-version package
# For switching a directory to symlink, you are advised to uncomment and edit the following
#dpkg-maintscript-helper dir_to_symlink pathname new-target prior-version package

73
debian/manpage.1.ex vendored Normal file
View File

@ -0,0 +1,73 @@
.\" Hey, EMACS: -*- nroff -*-
.\" (C) Copyright 2025 Paul Schneider <paul@localhost>,
.\"
.\" See man(1), man(7) and man-pages(7), https://www.tldp.org/HOWTO/Man-Page/
.\" for the documentation about man-pages and man-page-formatting:
.\"
.\" 1. Use this as the template for the manpage for <commandname> after
.\" renaming this file to <commandname>.1 (if it is for section 1).
.\"
.\" 2. List the path to this file in debian/<packagename>.manpages to
.\" install this manpage to the target binary package.
.\"
.\" First parameter, YAVSC, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.\"
.\" Easier way to make an initial manpage for commands is the use of help2man
.\" command provided by help2man package while using this file as an tutorial
.\" to understand what was created or to make touch-up edits.
.\"
.\" Other template files (manpage.*) created by debmake command are secondary
.\" helper files to create an initial manpage.
.\"
.TH YAVSC SECTION "08 Jun 2025"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
yavsc \- program to do something
.SH SYNOPSIS
.B yavsc
.RI [ options ] " files" ...
.br
.B bar
.RI [ options ] " files" ...
.SH DESCRIPTION
This manual page documents briefly the
.B yavsc
and
.B bar
commands.
.PP
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
.\" respectively.
\fByavsc\fP is a program that...
.SH OPTIONS
These programs follow the usual GNU command line syntax, with long
options starting with two dashes (`-').
A summary of options is included below.
For a complete description, see the Info files.
.TP
.B \-h, \-\-help
Show summary of options.
.TP
.B \-v, \-\-version
Show version of program.
.SH SEE ALSO
.BR bar (1),
.BR baz (1).
.br
The programs are documented fully by
.IR "The Rise and Fall of a Fooish Bar" ,
available via the Info system.

44
debian/manpage.asciidoc.ex vendored Normal file
View File

@ -0,0 +1,44 @@
= @UPACKAGE@(1)
:man source: YAVSC
:man version: 1.1.0-1
:man manual: YAVSC Manual
// Secondary template file to make manpage.1
//
// See "AsciiDoc Syntax Quick Reference"
// https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/
// https://docs.asciidoctor.org/asciidoctor/latest/manpage-backend/
// convert by:
// $ asciidoctor --doctype manpage -b manpage -a 'newline=\n' yavsc.asciidoc
== NAME
yavsc - program to do something
== SYNOPSIS
*yavsc* [*-h*] ...
== DESCRIPTION
*yavsc* do something.
=== optional arguments:
*-h*, *--help*::
show this help message and exit.
== AUTHOR
Copyright © 2025 Paul Schneider <paul@localhost>
== LICENSE
MIT License
== SEE ALSO
See also ...

129
debian/manpage.md.ex vendored Normal file
View File

@ -0,0 +1,129 @@
% YAVSC(SECTION) | User Commands
%
% "08 Jun 2025"
[comment]: # Secondary template file to make manpage.1
[comment]: #
[comment]: # The lines above form a Pandoc metadata block. They must be
[comment]: # the first ones in the file.
[comment]: # See https://pandoc.org/MANUAL.html#metadata-blocks for details.
[comment]: # pandoc -s -f markdown -t man package.md -o package.1
[comment]: #
[comment]: # A manual page package.1 will be generated. You may view the
[comment]: # manual page with: nroff -man package.1 | less. A typical entry
[comment]: # in a Makefile or Makefile.am is:
[comment]: #
[comment]: # package.1: package.md
[comment]: # pandoc --standalone --from=markdown --to=man $< --output=$@
[comment]: #
[comment]: # The pandoc binary is found in the pandoc package. Please remember
[comment]: # that if you create the nroff version in one of the debian/rules
[comment]: # file targets, such as build, you will need to include pandoc in
[comment]: # your Build-Depends control field.
[comment]: # lowdown is a low dependency, lightweight alternative to
[comment]: # pandoc as a markdown to manpage translator. Use with:
[comment]: #
[comment]: # package.1: package.md
[comment]: # lowdown -s -Tman -o $@ $<
[comment]: #
[comment]: # And add lowdown to the Build-Depends control field.
[comment]: # Remove the lines starting with '[comment]:' in this file in order
[comment]: # to avoid warning messages.
# NAME
yavsc - short summary
# SYNOPSIS
**yavsc** **-e** _this_ [**\-\-example=that**] [{**-e** | **\-\-example**} _this_]
[{**-e** | **\-\-example**} {_this_ | _that_}]
**yavsc** [{**-h** | *\-\-help**} | {**-v** | **\-\-version**}]
# DESCRIPTION
**yavsc** is a program that...
# OPTIONS
The program follows the usual GNU command line syntax, with long options
starting with two dashes ('-'). A summary of options is included below.
**-e** _this_, **\-\-example=**_that_
: Does this and that.
**-h**, **\-\-help**
: Show summary of options.
**-v**, **\-\-version**
: Show version of program.
# FILES
/etc/foo.conf
: The system-wide configuration file to control the behaviour of
yavsc. See **foo.conf**(5) for further details.
${HOME}/.foo.conf
: The per-user configuration file to control the behaviour of
yavsc. See **foo.conf**(5) for further details.
# ENVIRONMENT
**FOO_CONF**
: If used, the defined file is used as configuration file (see also
the section called FILES).
# DIAGNOSTICS
The following diagnostics may be issued on stderr:
Bad configuration file. Exiting.
: The configuration file seems to contain a broken configuration
line. Use the **\-\-verbose** option, to get more info.
**yavsc** provides some return codes, that can be used in scripts:
Code Diagnostic
0 Program exited successfully.
1 The configuration file seems to be broken.
# BUGS
The program is currently limited to only work with the foobar library.
The upstream BTS can be found at https://bugzilla.foo.tld.
# SEE ALSO
**bar**(1), **baz**(1), **foo.conf**(5)
The programs are documented fully by The Rise and Fall of a Fooish Bar
available via the **info**(1) system.
# AUTHOR
Paul Schneider <paul@localhost>
: Wrote this manpage for the Debian system.
# COPYRIGHT
Copyright © 2025 Paul Schneider
This manual page was written for the Debian system (and may be used by
others).
Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU General Public License, Version 2 or (at your option)
any later version published by the Free Software Foundation.
On Debian systems, the complete text of the GNU General Public License
can be found in /usr/share/common-licenses/GPL.
[comment]: # Local Variables:
[comment]: # mode: markdown
[comment]: # End:

144
debian/manpage.sgml.ex vendored Normal file
View File

@ -0,0 +1,144 @@
<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!--
Install docbook-to-man package and see docbook-to-man(1)
Secondary template file to make manpage.1
-->
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
<!ENTITY dhsurname "<surname>SURNAME</surname>">
<!-- Please adjust the date whenever revising the manpage. -->
<!ENTITY dhdate "<date>08 Jun 2025</date>">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1). -->
<!ENTITY dhsection "<manvolnum>SECTION</manvolnum>">
<!ENTITY dhemail "<email>paul@localhost</email>">
<!ENTITY dhusername "Paul Schneider">
<!ENTITY dhucpackage "<refentrytitle>YAVSC</refentrytitle>">
<!ENTITY dhpackage "yavsc">
<!ENTITY debian "<productname>Debian</productname>">
<!ENTITY gnu "<acronym>GNU</acronym>">
<!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
]>
<refentry>
<refentryinfo>
<address>
&dhemail;
</address>
<author>
&dhfirstname;
&dhsurname;
</author>
<copyright>
<year>2003</year>
<holder>&dhusername;</holder>
</copyright>
&dhdate;
</refentryinfo>
<refmeta>
&dhucpackage;
&dhsection;
</refmeta>
<refnamediv>
<refname>&dhpackage;</refname>
<refpurpose>program to do something</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&dhpackage;</command>
<arg><option>-e <replaceable>this</replaceable></option></arg>
<arg><option>--example <replaceable>that</replaceable></option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>This manual page documents briefly the
<command>&dhpackage;</command> and <command>bar</command>
commands.</para>
<para>This manual page was written for the &debian; distribution
because the original program does not have a manual page.
Instead, it has documentation in the &gnu;
<application>Info</application> format; see below.</para>
<para><command>&dhpackage;</command> is a program that...</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<para>These programs follow the usual &gnu; command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below. For a complete description, see the
<application>Info</application> files.</para>
<variablelist>
<varlistentry>
<term><option>-h</option>
<option>--help</option>
</term>
<listitem>
<para>Show summary of options.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option>
<option>--version</option>
</term>
<listitem>
<para>Show version of program.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>bar (1), baz (1).</para>
<para>The programs are documented fully by <citetitle>The Rise and
Fall of a Fooish Bar</citetitle> available via the
<application>Info</application> system.</para>
</refsect1>
<refsect1>
<title>AUTHOR</title>
<para>This manual page was written by &dhusername; &dhemail; for
the &debian; system (and may be used by others). Permission is
granted to copy, distribute and/or modify this document under
the terms of the &gnu; General Public License, Version 2 any
later version published by the Free Software Foundation.
</para>
<para>
On Debian systems, the complete text of the GNU General Public
License can be found in /usr/share/common-licenses/GPL.
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

267
debian/manpage.xml.ex vendored Normal file
View File

@ -0,0 +1,267 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!--
Secondary template file to make manpage.1
Install docbook-xsl and docbook-xsl-doc-html and see
/usr/share/doc/docbook-xsl/examples/foo.1.example_manpage.xml
/usr/share/doc/docbook-xsl-doc-html/doc/manpages/index.html
The xsltproc binary is found in the xsltproc package. The XSL files are in
docbook-xsl. A description of the parameters you can use can be found in the
docbook-xsl-doc-* packages.
Validation can be done using: `xmllint -''-noout -''-valid manpage.xml`
General documentation about man-pages and man-page-formatting:
man(1), man(7), man-pages(7), https://www.tldp.org/HOWTO/Man-Page/
-->
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!ENTITY dhfirstname "FIRSTNAME">
<!ENTITY dhsurname "SURNAME">
<!-- dhusername could also be set to "&dhfirstname; &dhsurname;". -->
<!ENTITY dhusername "Paul Schneider">
<!ENTITY dhemail "paul@localhost">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1) and
https://www.tldp.org/HOWTO/Man-Page/q2.html. -->
<!ENTITY dhsection "SECTION">
<!-- TITLE should be something like "User commands" or similar (see
https://www.tldp.org/HOWTO/Man-Page/q2.html). -->
<!ENTITY dhtitle "yavsc User Manual">
<!ENTITY dhucpackage "YAVSC">
<!ENTITY dhpackage "yavsc">
]>
<refentry>
<refentryinfo>
<title>&dhtitle;</title>
<productname>&dhpackage;</productname>
<authorgroup>
<author>
<firstname>&dhfirstname;</firstname>
<surname>&dhsurname;</surname>
<contrib>Wrote this manpage for the Debian system.</contrib>
<address>
<email>&dhemail;</email>
</address>
</author>
</authorgroup>
<copyright>
<year>2007</year>
<holder>&dhusername;</holder>
</copyright>
<legalnotice>
<para>This manual page was written for the Debian system
(and may be used by others).</para>
<para>Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License,
Version 2 or (at your option) any later version published by
the Free Software Foundation.</para>
<para>On Debian systems, the complete text of the GNU General Public
License can be found in
<filename>/usr/share/common-licenses/GPL</filename>.</para>
</legalnotice>
</refentryinfo>
<refmeta>
<refentrytitle>&dhucpackage;</refentrytitle>
<manvolnum>&dhsection;</manvolnum>
</refmeta>
<refnamediv>
<refname>&dhpackage;</refname>
<refpurpose>program to do something</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&dhpackage;</command>
<!-- These are several examples, how syntaxes could look -->
<arg choice="plain"><option>-e <replaceable>this</replaceable></option></arg>
<arg choice="opt"><option>--example=<parameter>that</parameter></option></arg>
<arg choice="opt">
<group choice="req">
<arg choice="plain"><option>-e</option></arg>
<arg choice="plain"><option>--example</option></arg>
</group>
<replaceable class="option">this</replaceable>
</arg>
<arg choice="opt">
<group choice="req">
<arg choice="plain"><option>-e</option></arg>
<arg choice="plain"><option>--example</option></arg>
</group>
<group choice="req">
<arg choice="plain"><replaceable>this</replaceable></arg>
<arg choice="plain"><replaceable>that</replaceable></arg>
</group>
</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>&dhpackage;</command>
<!-- Normally the help and version options make the programs stop
right after outputting the requested information. -->
<group choice="opt">
<arg choice="plain">
<group choice="req">
<arg choice="plain"><option>-h</option></arg>
<arg choice="plain"><option>--help</option></arg>
</group>
</arg>
<arg choice="plain">
<group choice="req">
<arg choice="plain"><option>-v</option></arg>
<arg choice="plain"><option>--version</option></arg>
</group>
</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="description">
<title>DESCRIPTION</title>
<para>This manual page documents briefly the
<command>&dhpackage;</command> and <command>bar</command>
commands.</para>
<para>This manual page was written for the Debian distribution
because the original program does not have a manual page.
Instead, it has documentation in the GNU <citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> format; see below.</para>
<para><command>&dhpackage;</command> is a program that...</para>
</refsect1>
<refsect1 id="options">
<title>OPTIONS</title>
<para>The program follows the usual GNU command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below. For a complete description, see the
<citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> files.</para>
<variablelist>
<!-- Use the variablelist.term.separator and the
variablelist.term.break.after parameters to
control the term elements. -->
<varlistentry>
<term><option>-e <replaceable>this</replaceable></option></term>
<term><option>--example=<replaceable>that</replaceable></option></term>
<listitem>
<para>Does this and that.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-h</option></term>
<term><option>--help</option></term>
<listitem>
<para>Show summary of options.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option></term>
<term><option>--version</option></term>
<listitem>
<para>Show version of program.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="files">
<title>FILES</title>
<variablelist>
<varlistentry>
<term><filename>/etc/foo.conf</filename></term>
<listitem>
<para>The system-wide configuration file to control the
behaviour of <application>&dhpackage;</application>. See
<citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for further details.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>${HOME}/.foo.conf</filename></term>
<listitem>
<para>The per-user configuration file to control the
behaviour of <application>&dhpackage;</application>. See
<citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for further details.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="environment">
<title>ENVIRONMENT</title>
<variablelist>
<varlistentry>
<term><envar>FOO_CONF</envar></term>
<listitem>
<para>If used, the defined file is used as configuration
file (see also <xref linkend="files"/>).</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="diagnostics">
<title>DIAGNOSTICS</title>
<para>The following diagnostics may be issued
on <filename class="devicefile">stderr</filename>:</para>
<variablelist>
<varlistentry>
<term><errortext>Bad configuration file. Exiting.</errortext></term>
<listitem>
<para>The configuration file seems to contain a broken configuration
line. Use the <option>--verbose</option> option, to get more info.
</para>
</listitem>
</varlistentry>
</variablelist>
<para><command>&dhpackage;</command> provides some return codes, that can
be used in scripts:</para>
<segmentedlist>
<segtitle>Code</segtitle>
<segtitle>Diagnostic</segtitle>
<seglistitem>
<seg><errorcode>0</errorcode></seg>
<seg>Program exited successfully.</seg>
</seglistitem>
<seglistitem>
<seg><errorcode>1</errorcode></seg>
<seg>The configuration file seems to be broken.</seg>
</seglistitem>
</segmentedlist>
</refsect1>
<refsect1 id="bugs">
<!-- Or use this section to tell about upstream BTS. -->
<title>BUGS</title>
<para>The program is currently limited to only work
with the <package>foobar</package> library.</para>
<para>The upstreams <acronym>BTS</acronym> can be found
at <ulink url="https://bugzilla.foo.tld"/>.</para>
</refsect1>
<refsect1 id="see_also">
<title>SEE ALSO</title>
<!-- In alphabetical order. -->
<para><citerefentry>
<refentrytitle>bar</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>, <citerefentry>
<refentrytitle>baz</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>, <citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry></para>
<para>The programs are documented fully by <citetitle>The Rise and
Fall of a Fooish Bar</citetitle> available via the <citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> system.</para>
</refsect1>
</refentry>

1
debian/patches/series vendored Normal file
View File

@ -0,0 +1 @@
# You must remove unused comment lines for the released package.

7
debian/postinst.ex vendored Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh
# If no user provided script is activated in this file, you should remove this file.
set -e
#DEBHELPER#
exit 0

7
debian/postrm.ex vendored Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh
# If no user provided script is activated in this file, you should remove this file.
set -e
#DEBHELPER#
exit 0

7
debian/preinst.ex vendored Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh
# If no user provided script is activated in this file, you should remove this file.
set -e
#DEBHELPER#
exit 0

7
debian/prerm.ex vendored Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh
# If no user provided script is activated in this file, you should remove this file.
set -e
#DEBHELPER#
exit 0

15
debian/rules vendored Executable file
View File

@ -0,0 +1,15 @@
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1
%:
dh $@
#override_dh_auto_install:
# dh_auto_install -- prefix=/usr
#override_dh_install:
# dh_install --list-missing -X.pyc -X.pyo

25
debian/salsa-ci.yml vendored Normal file
View File

@ -0,0 +1,25 @@
# For more information on what jobs are run see:
# https://salsa.debian.org/salsa-ci-team/pipeline
#
# To enable the jobs, go to your repository (at salsa.debian.org)
# and click over Settings > CI/CD > Expand (in General pipelines).
# In "CI/CD configuration file" write debian/salsa-ci.yml and click
# in "Save Changes". The CI tests will run after the next commit.
---
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
# # This commented-out sample disables all default tests, only disable those
# # CI tests that is required to get the CI process to succeed.
#
# variables:
# SALSA_CI_DISABLE_APTLY: 1
# SALSA_CI_DISABLE_AUTOPKGTEST: 1
# SALSA_CI_DISABLE_BLHC: 1
# SALSA_CI_DISABLE_LINTIAN: 1
# SALSA_CI_DISABLE_PIUPARTS: 1
# SALSA_CI_DISABLE_REPROTEST: 1
# SALSA_CI_DISABLE_BUILD_PACKAGE_ALL: 1
# SALSA_CI_DISABLE_BUILD_PACKAGE_ANY: 1
# SALSA_CI_DISABLE_BUILD_PACKAGE_I386: 1
# SALSA_CI_DISABLE_CROSSBUILD_ARM64: 1

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (quilt)

2
debian/source/lintian-overrides.ex vendored Normal file
View File

@ -0,0 +1,2 @@
# See dh_lintian(1)
# cut and paste the lintian(1) outputs without leading "E: ", "W: ", ...

47
debian/source/local-options.ex vendored Normal file
View File

@ -0,0 +1,47 @@
# Uncomment to active options. See dpkg-source(1)
#
# This file contains a list of long options that should be automatically
# prepended to the set of command line options of a dpkg-source --build call.
# This is normally for the non-native Debian packaging.
# Whenever possible, use this instead of debian/local-options to make
# dpkg-source long options applied for the team builds based on the VCS
# repository while NMU builds based on the Debian source package are not
# affected.
# == Patch unapplied strategy (dquilt, gbp, ...) ==
#
# The source outside of debian/ directory is unmodified from the upstream one:
# * Workflow using diff -u
# https://www.debian.org/doc/manuals/debmake-doc/ch04.en.html#diff-u
# * Workflow using dquilt
# https://www.debian.org/doc/manuals/debmake-doc/ch04.en.html#dquilt
# * Workflow using dpkg-source commit (commit only patch to VCS after dpkg-source commit)
# https://www.debian.org/doc/manuals/debmake-doc/ch04.en.html#dpkg-source-commit
# * Workflow to use gbp-buildpackage(1) with pristine-tar
# * Workflow described in dgit-maint-gbp(7)
#
# Uncomment following if you use this strategy
#abort-on-upstream-changes
#unapply-patches
# == Patch applied strategy (merge) ==
#
# The source outside of debian/ directory is modified by maintainer and
# different from the upstream one:
# * Workflow using dpkg-source commit (commit all to VCS after dpkg-source commit)
# https://www.debian.org/doc/manuals/debmake-doc/ch04.en.html#dpkg-source-commit
# * Workflow described in dgit-maint-merge(7)
#
# uncomment following if you use this strategy
#single-debian-patch
#auto-commit
# == Patch applied strategy (debrebase) ==
#
# The source outside of debian/ directory is modified by maintainer and
# different from the upstream one:
# * Workflow described in dgit-maint-debrebase(7)
#
# Remove this file if you use this strategy

26
debian/source/local-patch-header.ex vendored Normal file
View File

@ -0,0 +1,26 @@
The automatically generated patch by dpkg-source(1) puts this free form text on
top of it.
This is normally for the non-native Debian packaging.
Whenever possible, use this instead of debian/patch-header to make dpkg-source
long options applied for the team builds based on the VCS repository while NMU
builds based on the Debian source package are not affected.
== Patch applied strategy (merge) ==
The source outside of debian/ directory is modified by maintainer and
different from the upstream one:
* Workflow using dpkg-source commit (commit all to VCS after dpkg-source commit)
https://www.debian.org/doc/manuals/debmake-doc/ch04.en.html#dpkg-source-commit
* Workflow described in dgit-maint-merge(7)
Keep this file after updating its content if you use this strategy
== Other strategies ==
Remove this file if you use this strategy
===
A single combined diff, containing all the changes, follows.

10
debian/source/options.ex vendored Normal file
View File

@ -0,0 +1,10 @@
# Uncomment to active options. See dpkg-source(1)
#
# This file contains a list of long options that should be automatically
# prepended to the set of command line options of a dpkg-source --build call.
# This is normally for the non-native Debian packaging.
# Whenever possible, use debian/local-options instead to make dpkg-source long
# options applied for the team builds based on the VCS repository while NMU
# builds based on the Debian source package are not affected.

12
debian/source/patch-header.ex vendored Normal file
View File

@ -0,0 +1,12 @@
The automatically generated patch by dpkg-source(1) puts this free form text on
top of it.
This is normally for the non-native Debian packaging.
Whenever possible, use debian/local-patch-header instead to make dpkg-source long
options applied for the team builds based on the VCS repository while NMU
builds based on the Debian source package are not affected.
A single combined diff, containing all the changes, follows.
===

9
debian/tests/control vendored Normal file
View File

@ -0,0 +1,9 @@
#
# DEP-8: autopkgtest - automatic as-installed package testing
# Please check * https://dep-team.pages.debian.net/deps/dep8/
# * /usr/share/doc/autopkgtest
#
# !!! Please make sure to edit this to a valid test, otherwise build will fails
#
#Tests: testcode.sh
#Restrictions: allow-stderr, breaks-testbed, needs-internet, needs-root

16
debian/upstream/metadata vendored Normal file
View File

@ -0,0 +1,16 @@
#
# DEP-12: Per-package machine-readable metadata about Upstream
# Please check * https://dep-team.pages.debian.net/deps/dep12/
# * https://wiki.debian.org/UpstreamMetadata
Reference:
Author: <please use full names and separate multiple author by the keyword "and">
Title:
Journal:
Year:
Volume:
Number:
Pages:
DOI:
PMID:
URL:
eprint:

3
debian/watch vendored Normal file
View File

@ -0,0 +1,3 @@
# You must remove unused comment lines for the released package.
# Compulsory line, this is a version 4 file
version=4

3
debian/yavsc.bug-control.ex vendored Normal file
View File

@ -0,0 +1,3 @@
# Installed as usr/share/bug/yavsc/control in yavsc
# See dh_bugfiles(1) and /usr/share/doc/reportbug/README.developers.gz
# It is the bug control file containing some directions for the bug reporting tool.

3
debian/yavsc.bug-presubj.ex vendored Normal file
View File

@ -0,0 +1,3 @@
# Installed as usr/share/bug/yavsc/presubj in yavsc
# See dh_bugfiles(1) and /usr/share/doc/reportbug/README.developers.gz
# The contents of this file are displayed to the user by the bug reporting tool.

3
debian/yavsc.bug-script.ex vendored Normal file
View File

@ -0,0 +1,3 @@
# Installed as usr/share/bug/yavsc or usr/share/bug/yavsc/script in yavsc
# See dh_bugfiles(1) and /usr/share/doc/reportbug/README.developers.gz
# This is the script to be run by the bug reporting program for generating a bug report template.

10
debian/yavsc.conffiles.ex vendored Normal file
View File

@ -0,0 +1,10 @@
# See dh_installdeb(1).
# This file will be installed into the DEBIAN directory. The provided file will
# be enriched by debhelper to include all the conffiles auto-detected by
# debhelper (the maintainer should not list there as debhelper assumes it
# should handle that part).
#
# This file is primarily useful for using "special" entries such as the
# remove-on-upgrade feature from dpkg.
#
# For most packages, this file doesnt need to exist.

5
debian/yavsc.cron.d.ex vendored Normal file
View File

@ -0,0 +1,5 @@
#
# Regular cron jobs for the yavsc package
# See dh_installcron(1) and crontab(5).
#
#0 4 * * * root [ -x /usr/bin/yavsc_maintenance ] && /usr/bin/yavsc_maintenance

3
debian/yavsc.cron.daily.ex vendored Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
# Daily cron jobs shell script for the yavsc package
#true

3
debian/yavsc.cron.hourly.ex vendored Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
# Hourly cron jobs shell script for the yavsc package
#true

3
debian/yavsc.cron.monthly.ex vendored Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
# Monthly cron jobs shell script for the yavsc package
#true

3
debian/yavsc.cron.weekly.ex vendored Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
# Weekly cron jobs shell script for the yavsc package
#true

7
debian/yavsc.default.ex vendored Normal file
View File

@ -0,0 +1,7 @@
# Defaults for yavsc initscript
#
# This is a POSIX shell fragment
#
#DAEMON_OPTS=""

47
debian/yavsc.emacsen-install.ex vendored Normal file
View File

@ -0,0 +1,47 @@
#! /bin/sh -e
# /usr/lib/emacsen-common/packages/install/yavsc
# Written by Jim Van Zandt <jrv@debian.org>, borrowing heavily
# from the install scripts for gettext by Santiago Vila
# <sanvila@ctv.es> and octave by Dirk Eddelbuettel <edd@debian.org>.
FLAVOR=$1
PACKAGE=yavsc
if [ ${FLAVOR} = emacs ]; then exit 0; fi
echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR}
#FLAVORTEST=`echo $FLAVOR | cut -c-6`
#if [ ${FLAVORTEST} = xemacs ] ; then
# SITEFLAG="-no-site-file"
#else
# SITEFLAG="--no-site-file"
#fi
FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile"
ELDIR=/usr/share/emacs/site-lisp/${PACKAGE}
ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE}
ELRELDIR=../../../emacs/site-lisp/${PACKAGE}
# Install-info-altdir does not actually exist.
# Maybe somebody will write it.
if test -x /usr/sbin/install-info-altdir; then
echo install/${PACKAGE}: install Info links for ${FLAVOR}
install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/share/info/${PACKAGE}.info.gz
fi
install -m 755 -d ${ELCDIR}
cd ${ELDIR}
FILES=`echo *.el`
cd ${ELCDIR}
ln -sf ${ELRELDIR}/*.el .
cat << EOF > path.el
(debian-pkg-add-load-path-item ".")
(setq byte-compile-warnings nil)
EOF
${FLAVOR} ${FLAGS} ${FILES}
rm -f path.el
exit 0

15
debian/yavsc.emacsen-remove.ex vendored Normal file
View File

@ -0,0 +1,15 @@
#!/bin/sh -e
# /usr/lib/emacsen-common/packages/remove/yavsc
FLAVOR=$1
PACKAGE=yavsc
if [ ${FLAVOR} != emacs ]; then
if test -x /usr/sbin/install-info-altdir; then
echo remove/${PACKAGE}: removing Info links for ${FLAVOR}
install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/share/info/yavsc.info.gz
fi
echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR}
rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE}
fi

26
debian/yavsc.emacsen-startup.ex vendored Normal file
View File

@ -0,0 +1,26 @@
;; -*-emacs-lisp-*-
;;
;; Emacs startup file, e.g. /etc/emacs/site-start.d/50yavsc.el
;; for the Debian yavsc package
;;
;; Originally contributed by Nils Naumann <naumann@unileoben.ac.at>
;; Modified by Dirk Eddelbuettel <edd@debian.org>
;; Adapted for dh-make by Jim Van Zandt <jrv@debian.org>
;; The yavsc package follows the Debian/GNU Linux 'emacsen' policy and
;; byte-compiles its elisp files for each 'emacs flavor' (emacs19,
;; xemacs19, emacs20, xemacs20...). The compiled code is then
;; installed in a subdirectory of the respective site-lisp directory.
;; We have to add this to the load-path:
(let ((package-dir (concat "/usr/share/"
(symbol-name debian-emacs-flavor)
"/site-lisp/yavsc")))
;; If package-dir does not exist, the yavsc package must have
;; removed but not purged, and we should skip the setup.
(when (file-directory-p package-dir)
(if (fboundp 'debian-pkg-add-load-path-item)
(debian-pkg-add-load-path-item package-dir)
(setq load-path (cons package-dir load-path)))
(autoload 'yavsc-mode "yavsc-mode"
"Major mode for editing yavsc files." t)
(add-to-list 'auto-mode-alist '("\\.yavsc$" . yavsc-mode))))

2
debian/yavsc.lintian-overrides.ex vendored Normal file
View File

@ -0,0 +1,2 @@
# See dh_lintian(1) and Lintian User Manual (/usr/share/doc/lintian/lintian.html)
# cut and paste the lintian(1) outputs without leading "E: ", "W: ", ...

2
debian/yavsc.service.ex vendored Normal file
View File

@ -0,0 +1,2 @@
# If this exists, it is installed into lib/systemd/system/yavsc.service in yavsc
# See dh_systemd_enable(1).

2
debian/yavsc.tmpfile.ex vendored Normal file
View File

@ -0,0 +1,2 @@
# If this exists, it is installed into usr/lib/tmpfiles.d/yavsc.conf in yavsc
# See dh_installtmpfiles(1).

View File

@ -1,30 +1,27 @@
{
"version": 1,
"isRoot": true,
"tools": {
"codecov.tool": {
"version": "1.13.0",
"commands": [
"codecov"
]
},
"gitversion.tool": {
"version": "5.10.1",
"commands": [
"dotnet-gitversion"
]
},
"gitreleasemanager.tool": {
"version": "0.13.0",
"commands": [
"dotnet-gitreleasemanager"
]
},
"Wyam2.Tool": {
"version": "3.0.0-rc3",
"commands": [
"wyam2"
]
}
"version": 1,
"isRoot": true,
"tools": {
"codecov.tool": {
"version": "1.13.0",
"commands": [
"codecov"
],
"rollForward": false
},
"gitreleasemanager.tool": {
"version": "0.20.0",
"commands": [
"dotnet-gitreleasemanager"
],
"rollForward": false
},
"Wyam2.Tool": {
"version": "3.0.0-rc3",
"commands": [
"wyam2"
],
"rollForward": false
}
}
}
}

27
gitversion.json Normal file
View File

@ -0,0 +1,27 @@
{
"AssemblySemFileVer": "1.1.1.0",
"AssemblySemVer": "1.1.1.0",
"BranchName": "main",
"BuildMetaData": null,
"CommitDate": "2024-10-09",
"CommitsSinceVersionSource": 19,
"EscapedBranchName": "main",
"FullBuildMetaData": "Branch.main.Sha.2b45e421dda285b73bf7eb3387915030cd751b88",
"FullSemVer": "1.1.1-19",
"InformationalVersion": "1.1.1-19+Branch.main.Sha.2b45e421dda285b73bf7eb3387915030cd751b88",
"Major": 1,
"MajorMinorPatch": "1.1.1",
"Minor": 1,
"Patch": 1,
"PreReleaseLabel": "",
"PreReleaseLabelWithDash": "",
"PreReleaseNumber": 19,
"PreReleaseTag": "19",
"PreReleaseTagWithDash": "-19",
"SemVer": "1.1.1-19",
"Sha": "2b45e421dda285b73bf7eb3387915030cd751b88",
"ShortSha": "2b45e42",
"UncommittedChanges": 20,
"VersionSourceSha": "72839e8251297935a4ab138a99152733f07a23f2",
"WeightedPreReleaseNumber": 55019
}

View File

@ -1,12 +0,0 @@
drop table "AspNetRoleClaims" ;
drop table "AspNetUserRoles" ;
drop table "AspNetRoles" ;
drop table "AspNetUserClaims" ;
drop table "AspNetUserTokens" ;
drop table "PackageVersions" ;
drop table "Packages" ;
drop table "Commits" ;
drop table "ApiKeys" ;
drop table "AspNetUserLogins" ;
drop table "AspNetUsers" ;
drop table "__EFMigrationsHistory" ;

View File

@ -1,22 +0,0 @@
{
"dotnet": {
"enabled": false
},
"msbuild": {
"enabled": true
},
"Dnx": {
"enabled": false
},
"Script": {
"enabled": false
},
"fileOptions": {
"systemExcludeSearchPatterns": [
"**/bin/**/*",
"**/obj/**/*",
"**/node_modules/**/*"
],
"userExcludeSearchPatterns": []
}
}

35
src/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md.
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/isnd/bin/Debug/net9.0/isnd.dll",
"args": [],
"cwd": "${workspaceFolder}/isnd",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

41
src/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/isnd/isnd.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/isnd/isnd.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/isnd/isnd.csproj"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -1,3 +1,4 @@
using System;
using isn.abst;
namespace isnd.Entities
@ -11,10 +12,13 @@ namespace isnd.Entities
public const string AutoComplete = "/autocomplete";
public const string Registration = "/registration";
public const string Nuspec = "/nuspec";
public const string Content = "/content";
public const string ContentBase = "/content";
public const string Nuget = "/nuget";
public const string Find = "/index/FindPackagesById()"; // /FindPackagesById()?id='isn.abst'&semVerLevel=2.0.0
public const string PackageDetailUriTemplate = Package+"/{id}/{version}";
[Obsolete("use the V3 search")]
public const string V2Find = "/v2/FindPackagesById()"; // /FindPackagesById()??$filter=IsLatestVersion&$orderby=Version desc&$top=1&id='isn.abst'
}
}

View File

@ -2,8 +2,8 @@ namespace isn.abst
{
public static class Constants
{
public const string PaquetFileEstension = "nupkg";
public const string SpecFileEstension = "nuspec";
public const string PacketFileExtension = "nupkg";
public const string SpecFileExtension = "nuspec";
public const string ApiVersionPrefix = "/v3";
}
}

View File

@ -4,6 +4,11 @@ namespace isnd.Data.Catalog
{
public abstract class Permalink
{
public Permalink(string id)
{
Type = GetType().Name;
this.id = id;
}
public Permalink(string id, string type)
{
@ -11,19 +16,14 @@ namespace isnd.Data.Catalog
this.id = id;
}
public Permalink(string id)
{
Type = GetType().Name;
this.id = id;
}
[JsonProperty("@type")]
public virtual string Type { get; set; }
[JsonProperty("@id")]
public string Id { get => GetId(); }
private readonly string id;
public string Id { get => id; }
protected string id;
public string GetId() { return id; }

View File

@ -1,14 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageVersion>1.0.1</PackageVersion>
<Version>1.0.7</Version>
<TargetFrameworks>net7.0</TargetFrameworks>
<NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>1.0.7.0</AssemblyVersion>
<FileVersion>1.0.7.0</FileVersion>
<InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion>
</PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>

View File

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace isn
{
public interface IDataProtector
{
string Protect(string data);
string UnProtect(string data);
}
public class DefaultDataProtector : IDataProtector
{
private byte delta = 145;
public DefaultDataProtector()
{
}
public string Protect(string data)
{
List<Byte> protd = new List<byte>();
StringBuilder sb = new StringBuilder();
foreach (byte c in Encoding.UTF8.GetBytes(data))
{
protd.Add((byte) (c ^ delta));
}
return System.Convert.ToBase64String(protd.ToArray());
}
public string UnProtect(string data)
{
if (data==null) return null;
StringBuilder sb = new StringBuilder();
List<byte> unps = new List<byte>();
foreach (byte c in System.Convert.FromBase64CharArray(data.ToCharArray(),0,data.Length))
{
unps.Add((byte) (c ^ delta));
}
return Encoding.UTF8.GetString(unps.ToArray());
}
}
}

View File

@ -1,9 +0,0 @@
namespace isn
{
public class IsnSourceSettings
{
internal string Source { get; set; }
internal string[] Keys { get; set; }
}
}

View File

@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Mono.Options;
using Newtonsoft.Json;
@ -16,16 +18,17 @@ namespace isn
if (cfgSettingIf.Exists)
{
var json = File.ReadAllText(cfgSettingIf.FullName);
settings = JsonConvert.DeserializeObject<Settings>(json);
if (settings.DefaultSourceKey == null)
{
Settings.DefaultSourceKey = settings.Sources.Keys.FirstOrDefault();
}
CurrentSource = settings.DefaultSourceKey;
Settings = JsonConvert.DeserializeObject<Settings>(json);
CurrentSource = Settings.DefaultSourceKey;
}
if (Settings==null)
{
Settings= Settings.Create();
}
}
static readonly OptionSet storeoptions = new OptionSet {
{ "s|source=", "use source", val => CurrentSource ??= val },
{ "s|source=", "use source", val => Settings.CurrentSourceKey ??= val },
{ "h|help", "show this message and exit", h => shouldShowPushHelp = h != null },
};
@ -42,11 +45,9 @@ namespace isn
{ "v|version", "show soft version info and exit", h => shouldShowVersion = h != null }
};
static string apiKey;
static readonly OptionSet pushoptions = new OptionSet {
{ "k|api-key=", "use api key", val => apiKey = apiKey ?? val },
{ "s|source=", "use source", val => CurrentSource = CurrentSource ?? val },
{ "k|api-key=", "use api key", val => Settings.CurrentSource.SetApiKey(val)},
{ "s|source=", "use source", val => Settings.CurrentSourceKey = val },
{ "h|help", "show this message and exit", h => shouldShowPushHelp = h != null },
};
static readonly OptionSet sourceoptions = new OptionSet {
@ -62,30 +63,19 @@ namespace isn
private static bool shouldShowSourceHelp;
private static bool shouldShowPushHelp;
static Settings settings = null;
public static Settings Settings
{
get
{
if (settings == null)
LoadConfig();
if (settings == null)
{
settings = new Settings
{
DataProtectionTitle = "isn",
Sources = new Dictionary<string, SourceSettings>()
};
}
return settings;
}
get; set;
}
public static string CurrentSource { get => Settings.CurrentSourceKey; set => Settings.CurrentSourceKey = value; }
static int Main(string[] args)
{
LoadConfig();
var commandSet = new CommandSet("isn");
var srclst = new Command("list")
{
@ -217,7 +207,6 @@ namespace isn
Console.WriteLine("isn version " + GitVersionInformation.AssemblySemFileVer);
}
return commandSet.Run(args);
}
}
}

View File

@ -1,46 +1,57 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
namespace isn
{
public class SourceSettings
{
/// <summary>
/// Protected API Key
/// </summary>
/// <value></value>
public string ApiKey { get; set; }
public string ApiKey { get; set; }
/// <summary>
/// Key alias
/// </summary>
/// <value></value>
public string Alias { get; set; }
public string Url { get; set; }
public SourceSettings()
{
}
public string GetClearApiKey()
{
return Protector.UnProtect(ApiKey);
return ApiKey;
}
public void SetApiKey(string key)
{
ApiKey = Protector.Protect(key);
ApiKey = key;
}
public static IDataProtector Protector { get; set; } = new DefaultDataProtector();
}
public class Settings
{
public string DataProtectionTitle { get; set; }
public Dictionary<string, SourceSettings> Sources { get; set; }
private Settings()
{
public bool AutoUpdateApiKey { get; set; } = false;
}
public static Settings Create()
{
return new Settings {
Sources = new Dictionary<string, SourceSettings>()
};
}
public Dictionary<string, SourceSettings> Sources { get; set; }
private string defSourceKey;
@ -53,29 +64,26 @@ namespace isn
get => defSourceKey;
set
{
if (!Sources.ContainsKey(value))
{
Sources[value]=new SourceSettings
{
Alias = defSourceKey
};
}
defSourceKey = value;
}
}
string currentSourceKey;
[JsonIgnore, NotMapped]
public string CurrentSourceKey
public string CurrentSourceKey {get; set;}
[JsonIgnore, NotMapped]
public SourceSettings CurrentSource
{
get {
return currentSourceKey;
}
set{
if (!Sources.ContainsKey(value))
throw new InvalidOperationException($"source is invalid ({value})");
currentSourceKey = value;
get
{
if (CurrentSourceKey==null) return null;
if (!Sources.ContainsKey(CurrentSourceKey))
{
Sources.Add(CurrentSourceKey, new SourceSettings());
}
return Sources[CurrentSourceKey];
}
}
}

View File

@ -17,7 +17,7 @@ namespace isn
this.settings = settings;
}
public PushReport Run(string pkg, string source, string apikey)
public PushReport Run(string pkg, string source, string apiKey)
{
var resources = SourceHelpers.GetServerResources(source);
@ -33,25 +33,30 @@ namespace isn
var report = new PushReport
{
PkgName = fi.Name,
Message = "Le fichier n'existe pas : " + fi.FullName
Message = "The package does not exist : " + fi.FullName
};
return report;
}
using (var client = new HttpClient())
using (var client = new HttpClient(
new HttpClientHandler
{
AllowAutoRedirect = false
}
))
try
{
return client.UploadFilesToServer(new Uri(pubRes.Id), fi, settings.Sources[source].GetClearApiKey());
return client.UploadFilesToServer(new Uri(pubRes.Id), fi, settings.Sources[source].ApiKey);
}
catch (HttpRequestException hrex)
catch (HttpRequestException httpEx)
{
var report = new PushReport
{
PkgName = fi.Name,
Message = "HttpRequest: " + hrex.Message,
StackTrace = hrex.StackTrace,
StatusCode = hrex.HResult.ToString()
Message = "HttpRequest: " + httpEx.Message,
StackTrace = httpEx.StackTrace,
StatusCode = httpEx.HResult.ToString()
};
Console.Error.WriteLine(hrex.Message);
Console.Error.WriteLine(httpEx.Message);
return report;
}
catch (Exception ex)

View File

@ -14,11 +14,11 @@ namespace isn
List<PushReport> pushReports = new List<PushReport>();
var cmd = new PushCommand(Settings);
if (CurrentSource == null) throw new InvalidOperationException("source is null");
if (Settings.CurrentSource == null) throw new InvalidOperationException("source is null");
var source = Settings.CurrentSource;
foreach (string pkg in pkgs)
{
var report = cmd.Run(pkg, CurrentSource, apiKey);
var report = cmd.Run(pkg, source.Url, source.ApiKey);
pushReports.Add(report);
}
return pushReports;

View File

@ -16,7 +16,7 @@ namespace isn
{
SourceSettings setting = Settings.Sources[arg];
throw new InvalidOperationException
(setting.Alias);
(setting.Url);
}
throw new NotImplementedException();
}

View File

@ -11,7 +11,7 @@ namespace isn
SourceSettings settings =
Settings.Sources.ContainsKey(arg) ?
Settings.Sources[arg] :
Settings.Sources.Values.FirstOrDefault((s)=> s.Alias == arg) ;
Settings.Sources.Values.FirstOrDefault((s)=> s.Url == arg) ;
if (settings==null) throw new InvalidOperationException(arg);
Settings.DefaultSourceKey = arg;
SaveConfig();

View File

@ -14,7 +14,7 @@ namespace isn
var args = storeoptions.Parse(storeArgs);
if (args.Count != 1)
{
Console.Error.WriteLine("StoreApiKey command takse one and only one argument, the key.");
Console.Error.WriteLine("StoreApiKey command takes only one argument, the key.");
shouldShowPushHelp=true;
}
if (shouldShowPushHelp)
@ -25,7 +25,7 @@ namespace isn
}
else
{
Settings.Sources[Settings.CurrentSourceKey].SetApiKey(args[0]);
Settings.CurrentSource.SetApiKey(args[0]);
SaveConfig();
}
}

View File

@ -1,25 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net9.0</TargetFrameworks>
<RootNamespace>nuget_cli</RootNamespace>
<UserSecretsId>45b74c62-05bc-4603-95b4-3e80ae2fdf50</UserSecretsId>
<Version>1.0.7</Version>
<PackageVersion>1.0.1</PackageVersion>
<IsPackable>true</IsPackable>
<PackageLicenseExpression>WTFPL</PackageLicenseExpression>
<IsTool>true</IsTool>
<NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>1.0.7.0</AssemblyVersion>
<FileVersion>1.0.7.0</FileVersion>
<InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="7.0.1" />
<PackageReference Include="Mono.Options" Version="5.3.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="unleash.client" Version="1.6.1" />
<PackageReference Include="GitVersion.MsBuild" Version="5.6.10*" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.6" />
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="unleash.client" Version="5.2.1" />
<PackageReference Include="GitVersion.MsBuild" Version="6.3.0" />
<ProjectReference Include="../isn.abst/isn.abst.csproj" />
</ItemGroup>
</Project>

View File

@ -16,7 +16,6 @@ using System.Threading.Tasks;
namespace isnd.Controllers
{
[AllowAnonymous]
public class AccountController : Controller
{
private readonly IAuthenticationSchemeProvider _schemeProvider;
@ -40,7 +39,7 @@ namespace isnd.Controllers
/// <summary>
/// Entry point into the login workflow
/// </summary>
[HttpGet]
[HttpGet,AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl)
{
// build a model so we know what to show on the login page
@ -59,7 +58,7 @@ namespace isnd.Controllers
/// Handle postback from username/password login
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateAntiForgeryToken, AllowAnonymous]
public async Task<IActionResult> Login(LoginInputModel model, string button)
{
@ -167,7 +166,7 @@ namespace isnd.Controllers
return View("LoggedOut", vm);
}
[HttpGet]
[HttpGet,AllowAnonymous]
public IActionResult AccessDenied()
{
return new BadRequestObjectResult(403);

View File

@ -13,6 +13,7 @@ using Microsoft.Extensions.Options;
using isnd.Data;
using isnd.Entities;
using isnd.Data.ApiKeys;
using isnd.Interfaces;
namespace isnd.Controllers
@ -23,17 +24,20 @@ namespace isnd.Controllers
private readonly ApplicationDbContext dbContext;
private readonly IsndSettings isndSettings;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IApiKeyProvider apiKeyProvider;
private readonly IDataProtector protector;
public ApiKeysController(ApplicationDbContext dbContext,
IOptions<IsndSettings> isndSettingsOptions,
IDataProtectionProvider provider,
UserManager<ApplicationUser> userManager)
UserManager<ApplicationUser> userManager,
IApiKeyProvider apiKeyProvider
)
{
this.dbContext = dbContext;
this.isndSettings = isndSettingsOptions.Value;
protector = provider.CreateProtector(isndSettings.ProtectionTitle);
_userManager = userManager;
this.apiKeyProvider = apiKeyProvider;
}
[HttpGet]
@ -57,17 +61,17 @@ namespace isnd.Controllers
[HttpPost]
public async Task<ActionResult> Create(CreateModel model)
{
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
IQueryable<ApiKey> userKeys = GetUserKeys();
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
IQueryable<ApiKey> userKeys = apiKeyProvider.GetUserKeys(User.Identity.Name);
if (userKeys.Count() >= isndSettings.MaxUserKeyCount)
{
ModelState.AddModelError(null, "Maximum key count reached");
return View();
}
ApiKey newKey = new ApiKey { UserId = userid, Name = model.Name,
CreationDate = DateTimeOffset.Now.ToUniversalTime() };
_ = dbContext.ApiKeys.Add(newKey);
_ = await dbContext.SaveChangesAsync();
model.UserId = userId;
ApiKey newKey = await apiKeyProvider.CreateApiKeyAsync(model);
return View("Details", new DetailModel { Name = newKey.Name,
ProtectedValue = protector.Protect(newKey.Id),
ApiKey = newKey });
@ -77,22 +81,21 @@ namespace isnd.Controllers
public async Task<ActionResult> Delete(string id)
{
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
ApiKey key = await dbContext.ApiKey.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
return View(new DeleteModel { ApiKey = key });
}
[HttpPost]
public async Task<ActionResult> Delete(DeleteModel model)
{
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
ApiKey key = dbContext.ApiKeys.FirstOrDefault(k => k.Id == model.ApiKey.Id && k.UserId == userid);
ApiKey key = dbContext.ApiKey.FirstOrDefault(k => k.Id == model.ApiKey.Id && k.UserId == userid);
if (key == null)
{
ModelState.AddModelError(null, "Key not found");
return View();
}
_ = dbContext.ApiKeys.Remove(key);
_ = dbContext.ApiKey.Remove(key);
_ = await dbContext.SaveChangesAsync();
return View("Index", new IndexModel { ApiKey = GetUserKeys().ToList() } );
}
@ -100,10 +103,10 @@ namespace isnd.Controllers
public async Task<ActionResult> Details(string id)
{
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
ApiKey key = await dbContext.ApiKey.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
if (key == null)
{
ModelState.AddModelError(null, "Key not found");
ModelState.AddModelError("id", "Key not found");
return View();
}
return View("Details", new DetailModel { ApiKey = key, Name = key.Name, ProtectedValue = protector.Protect(key.Id)});
@ -130,7 +133,7 @@ namespace isnd.Controllers
{
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var apiKey = await dbContext.ApiKeys.SingleOrDefaultAsync(k => k.UserId == userId && k.Id == model.ApiKey.Id);
var apiKey = await dbContext.ApiKey.SingleOrDefaultAsync(k => k.UserId == userId && k.Id == model.ApiKey.Id);
apiKey.Name = model.ApiKey.Name;
apiKey.ValidityPeriodInDays = model.ApiKey.ValidityPeriodInDays;
await dbContext.SaveChangesAsync();
@ -139,7 +142,7 @@ namespace isnd.Controllers
public IQueryable<ApiKey> GetUserKeys()
{
return dbContext.ApiKeys.Include(k => k.User).Where(k => k.User.UserName == User.Identity.Name);
return dbContext.ApiKey.Include(k => k.User).Where(k => k.User.UserName == User.Identity.Name);
}
}
}

View File

@ -6,6 +6,10 @@ using System.Linq;
using isnd.ViewModels;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Build.Logging;
using Microsoft.Extensions.Options;
using isnd.Entities;
using isn.abst;
namespace isnd.Controllers
{
@ -15,22 +19,27 @@ namespace isnd.Controllers
public class HomeController : Controller
{
private readonly ApplicationDbContext _dbContext;
private readonly IsndSettings _isndSettings;
/// <summary>
/// Home controller ctor
/// </summary>
/// <param name="dbContext"></param>
/// <param name="isndSettings"></param>
public HomeController(
ApplicationDbContext dbContext)
ApplicationDbContext dbContext, IOptions<IsndSettings> isndSettings)
{
_dbContext = dbContext;
_isndSettings = isndSettings.Value;
}
public IActionResult Index()
{
return View(new HomeIndexViewModel{
PkgCount = _dbContext.Packages
PkgCount = _dbContext.Package
.Where(p => p.Versions.Count > 0)
.Count()});
.Count(),
APIUrl = _isndSettings.ExternalUrl + Constants.ApiVersionPrefix + ApiConfig.Index});
}
public IActionResult About()
@ -59,9 +68,9 @@ namespace isnd.Controllers
return View(ViewData);
}
public IActionResult Error()
public IActionResult Error(string id)
{
return View();
return View("Error", id);
}
}
}

View File

@ -27,7 +27,7 @@ namespace isnd
// GET: PackageVersion
public async Task<IActionResult> Index(PackageVersionIndexViewModel model)
{
var applicationDbContext = _context.PackageVersions.Include(p => p.Package)
var applicationDbContext = _context.PackageVersion.Include(p => p.Package)
.Include(p => p.Package.Owner)
.Include(p => p.Package.Versions)
.Where(
@ -41,7 +41,7 @@ namespace isnd
public async Task<IActionResult> Mines(PackageVersionIndexViewModel model)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var applicationDbContext = _context.PackageVersions
var applicationDbContext = _context.PackageVersion
.Include(p => p.Package).Where(
p => (string.IsNullOrEmpty(model.PackageId) || p.PackageId.StartsWith(model.PackageId))
&& p.Package.OwnerId == userId);

View File

@ -33,7 +33,7 @@ namespace isnd.Controllers
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Index)]
public IActionResult ApiIndex()
{
return Ok(new ApiIndexViewModel(packageManager.CatalogBaseUrl){ Version = PackageManager.BASE_API_LEVEL, Resources = resources });
return Ok(new ApiIndexViewModel(packageManager.CatalogBaseUrl + ApiConfig.Index){ Version = PackageManager.BASE_API_LEVEL, Resources = resources });
}
}

View File

@ -0,0 +1,18 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using isnd.Entities;
using isn.abst;
namespace isnd.Controllers
{
public partial class PackagesController
{
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.PackageDetailUriTemplate)]
public async Task<IActionResult> Details(string id, string version)
{
var result = await packageManager.GetPackageDetailsAsync(id, version);
if (result==null) return NotFound();
return Ok(result);
}
}
}

View File

@ -1,13 +1,6 @@
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
using isnd.Services;
using isnd.Entities;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using NuGet.Versioning;
using isnd.Data.Packages.Catalog;
using isnd.Data.Catalog;
using isn.abst;
namespace isnd.Controllers
@ -23,7 +16,9 @@ namespace isnd.Controllers
}
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Registration + "/{id}/{version}.json")]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Registration + "/{id}/{version}.json")]
public async Task<IActionResult> CatalogRegistration(string id, string version)
{
if ("index" == version)
@ -38,8 +33,8 @@ namespace isnd.Controllers
return Ok(index);
}
// return a Package
var leaf = await packageManager.GetCatalogEntryAsync(id, version, null);
// return Package details
var leaf = await packageManager.GetPackageDetailsAsync(id, version, null);
if (null == leaf) return NotFound(new { id, version });
return Ok(leaf);

View File

@ -4,54 +4,67 @@ using Microsoft.AspNetCore.Mvc;
using isnd.Attributes;
using isnd.Entities;
using isn.abst;
using System.Linq;
using Microsoft.Extensions.Logging;
namespace isnd.Controllers
{
public partial class PackagesController
{
// Web get the paquet
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Nuget + "/{id}/{lower}/{idf}-{lowerf}."
+ Constants.PaquetFileEstension)]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Content + "/{id}/{lower}/{idf}-{lowerf}."
+ Constants.PaquetFileEstension)]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.ContentBase + "/{id}/{version}/{idf}.{versionFromName}."
+ Constants.PacketFileExtension)]
public IActionResult GetPackage(
[FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower,
[FromRoute] string idf, [FromRoute] string lowerf)
[FromRoute][SafeName][Required] string version,
[FromRoute] string idf,
[FromRoute] string versionFromName)
{
var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}-{lower}." + Constants.PaquetFileEstension
);
DirectoryInfo pkgsDirInfo = new DirectoryInfo(isndSettings.PackagesRootDir);
FileInfo pkgfi = new FileInfo(pkgpath);
var pkgDirInfo = pkgsDirInfo.GetDirectories().FirstOrDefault(
s=>string.Compare(s.Name,id, System.StringComparison.InvariantCultureIgnoreCase)==0);
if (pkgDirInfo==null)
return BadRequest("Package does´nt exist in the file system.");
var pkgVersionDirInfo = pkgDirInfo.GetDirectories().FirstOrDefault(
s=>s.Name==version);
if (pkgVersionDirInfo==null)
return BadRequest("Package does´nt exist in the specified version.");
var pkgNameSpec=$"{id}-{version}.{Constants.PacketFileExtension}";
if (!pkgfi.Exists)
FileInfo pkgFileInfo = pkgVersionDirInfo.GetFiles()
.FirstOrDefault(p=>string.Compare(p.Name,pkgNameSpec,
System.StringComparison.InvariantCultureIgnoreCase)==0);
if (pkgFileInfo==null || !pkgFileInfo.Exists)
{
return BadRequest("!pkgfi.Exists");
logger.LogError($"Not found in {pkgVersionDirInfo.FullName} : {pkgNameSpec}");
return BadRequest("Package version does´nt exist in the file system.");
}
return File(pkgfi.OpenRead(), "application/zip; charset=binary");
return File(pkgFileInfo.OpenRead(), "application/zip; charset=binary");
}
// Web get spec
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Nuspec + "/{id}/{lower}/{idf}-{lowerf}."
+ Constants.SpecFileEstension)]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.ContentBase + "/{id}/{lower}/{idf}-{lowerFromName}."
+ Constants.SpecFileExtension)]
public IActionResult GetNuspec(
[FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower,
[FromRoute][SafeName][Required] string idf,
[FromRoute][SafeName][Required] string lowerf)
[FromRoute][SafeName][Required] string lowerFromName)
{
var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}." + Constants.SpecFileEstension);
var pkgPath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}." + Constants.SpecFileExtension);
FileInfo pkgfi = new FileInfo(pkgpath);
if (!pkgfi.Exists)
FileInfo pkgFileInfo = new FileInfo(pkgPath);
if (!pkgFileInfo.Exists)
{
return BadRequest("!pkgfi.Exists");
return BadRequest("Package info does´nt exist in the file system.");
}
return File(pkgfi.OpenRead(), "text/xml; charset=utf-8");
return File(pkgFileInfo.OpenRead(), "text/xml; charset=utf-8");
}
}
}

View File

@ -7,23 +7,31 @@ namespace isnd.Controllers
{
public partial class PackagesController
{
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Find)]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.ContentBase + "/{id}/{version}.json")]
public IActionResult GetVersions(
string id,
string lower,
bool prerelease = false,
string version,
bool prerelease = true,
string packageType = null,
int skip = 0,
int take = 25)
int take = 50)
{
NuGetVersion parsedVersion=null;
if (take > maxTake)
{
ModelState.AddModelError("take", "Maximum exceeded");
}
// NugetVersion
if (!NuGetVersion.TryParse(lower, out NuGetVersion parsedVersion))
if ("index"==version)
{
ModelState.AddModelError("lower", "invalid version string");
version=null;
}
if (version!=null)
{
if (!NuGetVersion.TryParse(version, out parsedVersion))
{
ModelState.AddModelError("version", "invalid version string");
}
}
if (!ModelState.IsValid)
{

View File

@ -1,25 +1,14 @@
using Microsoft.VisualBasic.CompilerServices;
using System.Linq.Expressions;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using NuGet.Packaging.Core;
using NuGet.Versioning;
using isnd.Data;
using isnd.Helpers;
using isnd.Entities;
using Microsoft.AspNetCore.Http;
using isn.abst;
using isnd.Data.Packages;
using Microsoft.EntityFrameworkCore;
using System.IO;
namespace isnd.Controllers
{
@ -38,184 +27,42 @@ namespace isnd.Controllers
var files = new List<string>();
ViewData["files"] = files;
var clearkey = protector.Unprotect(apiKey);
var apikey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearkey);
if (apikey == null)
var clearKey = protector.Unprotect(apiKey);
var dbApiKey = dbContext.ApiKey.SingleOrDefault(k => k.Id == clearKey);
if (dbApiKey == null)
{
logger.LogError("403 : no api-key");
return Unauthorized();
}
Commit commit = new Commit
{
Action = PackageAction.PublishPackage,
TimeStamp = DateTimeOffset.Now.ToUniversalTime()
};
bool foundPackage = false;
foreach (IFormFile file in Request.Form.Files)
{
string initpath = Path.Combine(Environment.GetEnvironmentVariable("TEMP") ??
Environment.GetEnvironmentVariable("TMP") ?? "/tmp",
$"isn-{Guid.NewGuid()}."+Constants.PaquetFileEstension);
using (FileStream fw = new FileStream(initpath, FileMode.Create))
FileInfo inputFileInfo = new FileInfo(file.FileName);
switch (inputFileInfo.Extension)
{
file.CopyTo(fw);
case ".nupkg":
case ".nupkgs":
var libVersion = await packageManager.PutPackageAsync(inputFileInfo.Extension, file.OpenReadStream(), dbApiKey.UserId);
logger.LogInformation($"new package : {libVersion.PackageId} {libVersion.NugetLink}");
foundPackage = true;
break;
default:
logger.LogInformation($"file extension is not supported : {inputFileInfo.Extension}");
break;
}
using (FileStream fw = new FileStream(initpath, FileMode.Open))
{
var archive = new ZipArchive(fw);
var spec = archive.Entries.FirstOrDefault(e => e.FullName.EndsWith("." + Constants.SpecFileEstension));
if (spec == null) return BadRequest(new { error = "no " + Constants.SpecFileEstension + " from archive" });
string pkgpath;
NuGetVersion version;
string pkgid;
string fullpath;
using (var specstr = spec.Open())
{
NuspecCoreReader reader = new NuspecCoreReader(specstr);
string pkgdesc = reader.GetDescription();
var types = reader.GetPackageTypes();
pkgid = reader.GetId();
version = reader.GetVersion();
string pkgidpath = Path.Combine(isndSettings.PackagesRootDir,
pkgid);
pkgpath = Path.Combine(pkgidpath, version.ToFullString());
string name = $"{pkgid}-{version}."+Constants.PaquetFileEstension;
fullpath = Path.Combine(pkgpath, name);
var destpkgiddir = new DirectoryInfo(pkgidpath);
Package pkg = dbContext.Packages.SingleOrDefault(p => p.Id == pkgid);
if (pkg != null)
{
if (pkg.OwnerId != apikey.UserId)
{
return new ForbidResult();
}
pkg.Description = pkgdesc;
}
else
{
pkg = new Package
{
Id = pkgid,
Description = pkgdesc,
OwnerId = apikey.UserId,
LatestCommit = commit
};
dbContext.Packages.Add(pkg);
}
if (!destpkgiddir.Exists) destpkgiddir.Create();
var source = new FileInfo(initpath);
var dest = new FileInfo(fullpath);
var destdir = new DirectoryInfo(dest.DirectoryName);
if (dest.Exists)
{
logger.LogWarning($"Existant package on disk : '{dest.FullName}'");
// La version existe sur le disque,
// mais si elle ne l'est pas en base de donnéés,
// on remplace la version sur disque.
string exFullString = version.ToFullString();
var pkgv = dbContext.PackageVersions.
Include(v=>v.LatestCommit)
.SingleOrDefault(
v => v.PackageId == pkg.Id && v.FullString == exFullString
);
if (pkgv!=null && ! pkgv.IsDeleted)
{
string msg = $"existant : {pkg.Id}-{exFullString}";
logger.LogWarning("400 : {msg}", msg);
ModelState.AddModelError("pkgversion", msg);
return BadRequest(this.CreateAPIKO("existant"));
} else dest.Delete();
}
{
if (!destdir.Exists) destdir.Create();
source.MoveTo(fullpath);
files.Add(name);
string fullstringversion = version.ToFullString();
var pkgvers = dbContext.PackageVersions.Where
(v => v.PackageId == pkg.Id && v.FullString == fullstringversion);
if (pkgvers.Count() > 0)
{
foreach (var v in pkgvers.ToArray())
dbContext.PackageVersions.Remove(v);
}
// FIXME default type or null
if (types==null || types.Count==0)
dbContext.PackageVersions.Add
(new PackageVersion{
Package = pkg,
Major = version.Major,
Minor = version.Minor,
Patch = version.Patch,
Revision = version.Revision,
IsPrerelease = version.IsPrerelease,
FullString = version.ToFullString(),
Type = null,
LatestCommit = commit
});
else
foreach (var type in types)
{
var pkgver = new PackageVersion
{
Package = pkg,
Major = version.Major,
Minor = version.Minor,
Patch = version.Patch,
IsPrerelease = version.IsPrerelease,
FullString = version.ToFullString(),
Type = type.Name,
LatestCommit = commit
};
dbContext.PackageVersions.Add(pkgver);
}
dbContext.Commits.Add(commit);
await dbContext.SaveChangesAsync();
await packageManager.ÛpdateCatalogForAsync(commit);
logger.LogInformation($"new paquet : {spec.Name}");
}
}
using (var shacrypto = System.Security.Cryptography.SHA512.Create())
{
using (var stream = System.IO.File.OpenRead(fullpath))
{
var hash = shacrypto.ComputeHash(stream);
var shafullname = fullpath + ".sha512";
var hashtext = Convert.ToBase64String(hash);
var hashtextbytes = Encoding.ASCII.GetBytes(hashtext);
using (var shafile = System.IO.File.OpenWrite(shafullname))
{
shafile.Write(hashtextbytes, 0, hashtextbytes.Length);
}
}
}
string nuspecfullpath = Path.Combine(pkgpath, pkgid + "." + Constants.SpecFileEstension);
FileInfo nfpi = new(nuspecfullpath);
if (nfpi.Exists)
nfpi.Delete();
spec.ExtractToFile(nuspecfullpath);
}
}
return Ok();
if (foundPackage)
return Ok();
return BadRequest("no package");
}
catch (Exception ex)
{
logger.LogError("PUT exception : " + ex.Message);
var message = $"PUT exception : {ex.Message} ({ex.GetType().Name})";
logger.LogError(message);
logger.LogError("Stack Trace : " + ex.StackTrace);
return new ObjectResult(new { ViewData, ex.Message })
return new ObjectResult(new { ViewData, message })
{ StatusCode = 500 };
}
}

View File

@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Mvc;
using isnd.Entities;
using isn.abst;
using System.Threading.Tasks;
using isnd.Data.Catalog;
namespace isnd.Controllers
{
// TODO /search GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE}
public partial class PackagesController
{
// Web get the paquet
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Search)]
[HttpHead("~" + Constants.ApiVersionPrefix + ApiConfig.Search)]
[HttpHead("~" + ApiConfig.V2Find)]
public async Task<IActionResult> Search(
string q=null,
int skip=0,
int take=25,
bool prerelease=true,
string semVerLevel = "2.0.0",
string packageType = "Dependency")
{
PackageRegistrationQuery query = new PackageRegistrationQuery
{
Prerelease= prerelease,
Query = q,
Skip = skip,
Take = take
};
var result = await packageManager.SearchPackageAsync(query);
return Ok(result);
}
}
}

View File

@ -1,12 +1,15 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using isn.abst;
using isnd.Data;
using isnd.Data.Catalog;
using isnd.Entities;
using isnd.Helpers;
using isnd.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
@ -19,11 +22,30 @@ namespace isnd.Controllers
public async Task<IActionResult> Index(PackageRegistrationQuery model)
{
var pkgs = await packageManager.SearchPackageAsync(model);
var result = new RegistrationPageIndexQueryAndResult
{
Source = packageManager.CatalogBaseUrl+ApiConfig.Index,
Query = model
};
List<Catalog> registrations = new List<Catalog>();
if (pkgs.data!=null)
if (pkgs.data.Length>0)
{
var grouped = pkgs.data.GroupBy(x => x.PackageId);
if (grouped!=null) if (grouped.Count()>0)
{
foreach (var pk in grouped.ToArray())
{
registrations.Add(new Catalog(apiBase, pk.Key, pkgs.GetResults().Single(p=>p.Id == pk.Key).Versions));
}
}
}
return View(new RegistrationPageIndexQueryAndResult
{
Source = packageManager.CatalogBaseUrl+ApiConfig.Index,
Query = model,
Result = pkgs.ToArray()
Result = registrations.ToArray()
});
}
@ -34,7 +56,7 @@ namespace isnd.Controllers
return NotFound();
}
var packageVersion = dbContext.PackageVersions
var packageVersion = dbContext.PackageVersion
.Include(p=>p.LatestCommit)
.Include(p => p.Package)
.Where(m => m.PackageId == model.pkgid)
@ -62,29 +84,29 @@ namespace isnd.Controllers
return NotFound();
}
var packageVersion = await dbContext.PackageVersions.Include(p => p.Package)
.FirstOrDefaultAsync(m => m.PackageId == pkgid
&& m.FullString == version && m.Type == pkgtype);
var packageVersion = await dbContext.PackageVersion.Include(p => p.Package)
.FirstOrDefaultAsync(m => m.PackageId == pkgid && m.FullString == version
&& (pkgtype!=null && m.Type == pkgtype || m.Type != "Delete" ));
if (packageVersion == null) return NotFound();
if (!User.IsOwner(packageVersion)) return Unauthorized();
var pkg = await packageManager.GetPackageAsync(pkgid, version, pkgtype);
if (!User.IsOwner(packageVersion)) return Challenge();
var pkg = await packageManager.GetPackageDetailsAsync(pkgid, version, pkgtype);
return View(pkg);
}
// POST: PackageVersion/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string PackageId, string FullString,
string Type)
[ValidateAntiForgeryToken][Authorize]
public async Task<IActionResult> DeleteConfirmed(string pkgid, string version,
string type)
{
PackageVersion packageVersion = await dbContext.PackageVersions
var packageVersion = await dbContext.PackageVersion
.Include(pv => pv.Package)
.FirstOrDefaultAsync(m => m.PackageId == PackageId
&& m.FullString == FullString && m.Type == Type);
if (packageVersion == null) return NotFound();
if (!User.IsOwner(packageVersion)) return Unauthorized();
await packageManager.DeletePackageAsync(PackageId, FullString, Type);
.Where(m => m.PackageId == pkgid
&& m.FullString == version && (type==null || m.Type == type))
.ToArrayAsync();
if (packageVersion.Length==0) return NotFound();
if (!User.IsOwner(packageVersion.First())) return Unauthorized();
await packageManager.DeletePackageAsync(pkgid, version, type);
return RedirectToAction(nameof(Index));
}
}

View File

@ -8,6 +8,7 @@ using isnd.Data;
using isnd.Entities;
using isnd.Interfaces;
using isn.Abstract;
using isn.abst;
namespace isnd.Controllers
{
@ -16,6 +17,7 @@ namespace isnd.Controllers
{
const int maxTake = 100;
private readonly Resource[] resources;
private readonly string apiBase;
private readonly ILogger<PackagesController> logger;
private readonly IDataProtector protector;
@ -36,6 +38,9 @@ namespace isnd.Controllers
this.dbContext = dbContext;
packageManager = pm;
resources = packageManager.GetResources().ToArray();
this.apiBase = isndSettings.ExternalUrl + Constants.ApiVersionPrefix;
}
}
}

View File

@ -9,6 +9,8 @@ namespace isnd.Data.ApiKeys
[Display(Name = "Key Name")]
public string Name { get; set; }
public string UserId { get; set; }
public int ValidityPeriodInDays { get; set; }
}
}

View File

@ -2,6 +2,8 @@
using Microsoft.EntityFrameworkCore;
using isnd.Data.ApiKeys;
using isnd.Data.Packages;
using Microsoft.VisualStudio.Web.CodeGenerators.Mvc.Templates.BlazorIdentity.Pages;
using Microsoft.DotNet.Scaffolding.Shared.ProjectModel;
namespace isnd.Data
{
@ -24,6 +26,10 @@ namespace isnd.Data
.HasKey( v => new { v.PackageId, v.FullString } );
_ = builder.Entity<PackageVersion>()
.HasOne(v => v.Package).WithMany(p => p.Versions).HasForeignKey(x => x.PackageId);
_ = builder.Entity<PackageDependencyGroup>().HasOne(g=>g.PackageVersion)
.WithMany(v => v.DependencyGroups).HasForeignKey(x => new { x.PackageId, x.PackageVersionFullString } );
}
@ -31,24 +37,27 @@ namespace isnd.Data
/// User API keys
/// </summary>
/// <value></value>
public DbSet<ApiKey> ApiKeys { get; set; }
public DbSet<ApiKey> ApiKey { get; set; }
/// <summary>
/// Packages
/// </summary>
/// <value></value>
public DbSet<Package> Packages { get; set; }
public DbSet<Package> Package { get; set; }
/// <summary>
/// Package Versions
/// </summary>
/// <value></value>
public DbSet<PackageVersion> PackageVersions { get; set; }
public DbSet<PackageVersion> PackageVersion { get; set; }
/// <summary>
/// Commits
/// </summary>
/// <value></value>
public DbSet<Commit> Commits { get; set; }
public DbSet<Dependency> Dependency { get; set; }
public DbSet<PackageDependencyGroup> PackageDependencyGroup { get; set; }
}
}

View File

@ -5,6 +5,8 @@ namespace isnd.Data
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
[PersonalData]
public string FullName { get; set; }
}
}

View File

@ -1,6 +0,0 @@
namespace isnd.Data.Catalog
{
public class DependencyGroup
{
}
}

View File

@ -12,33 +12,42 @@ using NuGet.Protocol;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using System.Threading.Tasks;
using isnd.Entities;
namespace isnd.Data.Catalog
{
public class PackageDetails : Permalink, IObject, IPackageSearchMetadata
public class PackageDetails : Permalink, IObject
{
/// <summary>
/// Creates a catalog entry
/// </summary>
/// <param name="pkg">package id</param>
/// <param name="apiBase">api Base</param>
/// <param name="uri">package permalink</param>
/// <returns></returns>
public PackageDetails(PackageVersion pkg, string apiBase, string uri): base(uri)
public PackageDetails(PackageVersion pkg, string apiBase): base( apiBase + ApiConfig.Package + "/" + pkg.PackageId + "/" + pkg.FullString)
{
PackageId = pkg.Package.Id;
Title = PackageId = pkg.Package.Id;
Version = pkg.FullString;
Authors = $"{pkg.Package.Owner.FullName} <${pkg.Package.Owner.Email}>";
Authors = $"{pkg.Package.Owner.FullName} <{pkg.Package.Owner.Email}>";
packageContent = apiBase + pkg.NugetLink;
CommitId = pkg.CommitId;
CommitTimeStamp = pkg.LatestCommit.CommitTimeStamp;
IsListed = !pkg.IsDeleted && pkg.Package.Public;
// TODO Licence Project Urls, Summary, Title, etc ...
Published = CommitTimeStamp = pkg.LatestCommit.CommitTimeStamp;
Listed = !pkg.IsDeleted && pkg.Package.Public;
if (pkg.DependencyGroups!=null)
{
DependencySets = pkg.DependencyGroups;
}
Description = pkg.Description;
Owners = pkg.Package.Owner.Email;
// TODO Licence Project Urls, Summary, Title, Owners, etc ...
}
[JsonProperty("@type")]
public string[] RefType { get; protected set; } = new string[] { "PackageDetails" };
[JsonProperty("commitId")]
public string CommitId { get; set; }
@ -52,12 +61,6 @@ namespace isnd.Data.Catalog
[JsonProperty("authors")]
public string Authors { get; set; }
/// <summary>
/// The dependencies of the package, grouped by target framework
/// </summary>
/// <value>array of objects</value>
public DependencyGroup[] dependencyGroups { get; set; } = Array.Empty<DependencyGroup>();
/// <summary>
/// The deprecation associated with the package
/// </summary>
@ -127,28 +130,23 @@ namespace isnd.Data.Catalog
[JsonProperty("id")]
public string PackageId { get; set; }
public IEnumerable<PackageDependencyGroup> DependencySets { get; set; }
= Array.Empty<PackageDependencyGroup>();
public long? DownloadCount { get; set; }
public PackageIdentity Identity{ get; set; }
public Uri ReadmeUrl { get; set; }
public Uri ReportAbuseUrl { get; set; }
public Uri PackageDetailsUrl { get; set; }
public string Owners { get; set; }
[JsonProperty("isListed")]
public bool IsListed { get; set; }
public bool PrefixReserved { get; set; }
public bool Listed { get; set; }
public LicenseMetadata LicenseMetadata { get; set; }
[JsonProperty("dependencyGroups")]
public IEnumerable<PackageDependencyGroup> DependencySets {get; set;}
public Task<PackageDeprecationMetadata> GetDeprecationMetadataAsync()
{
throw new NotImplementedException();
@ -159,4 +157,5 @@ namespace isnd.Data.Catalog
throw new NotImplementedException();
}
}
}

View File

@ -1,4 +1,5 @@
using isnd.Data.Packages;
using isnd.Entities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -6,19 +7,19 @@ using System.Linq;
namespace isnd.Data.Catalog
{
public class PackageRegistration : Permalink
public class Catalog : Permalink
{
public PackageRegistration(string url) : base(url)
public Catalog(string url) : base(url)
{
Items = new List<CatalogPage>();
Items = new List<RegistrationPage>();
}
public PackageRegistration(string bid, string apiBase, Packages.Package pkg) : base(bid + $"/{pkg.Id}/index.json")
public Catalog(string apiBase, string pkgId, IEnumerable<PackageVersion> versions) : base($"{apiBase}{ApiConfig.Registration}/{pkgId}/index.json")
{
Items = new List<CatalogPage>
Items = new List<RegistrationPage>
{
new CatalogPage(bid, pkg.Id, apiBase, pkg.Versions)
new RegistrationPage(pkgId, apiBase, versions)
};
}
@ -26,7 +27,7 @@ namespace isnd.Data.Catalog
public int Count { get => Items.Count; }
[JsonProperty("items")]
public List<CatalogPage> Items { get; set; }
public List<RegistrationPage> Items { get; set; }
}
}

View File

@ -21,5 +21,10 @@ namespace isnd.Data.Catalog
[JsonProperty("take")]
public int Take { get; set; } = 25;
override public string ToString()
{
return $"[PackageRegistrationQuery Query:{Query} Prerelease:{Prerelease} Skip:{Skip} Take:{Take}]";
}
}
}

View File

@ -9,15 +9,15 @@ namespace isnd.Data.Catalog
/// Hosts a catalog entry,
/// the atomic content reference
/// </summary>
public class Package
public class RegistrationLeaf
{
public Package(string apiBase, string pkgId, string fullVersionString, PackageDetails entry)
public RegistrationLeaf(string apiBase, string pkgId, string fullVersionString, PackageDetails entry)
{
this.registration = apiBase + ApiConfig.Registration + "/" + pkgId + "/" + fullVersionString + ".json";
Id = registration;
this.PackageContent = apiBase + ApiConfig.Nuget + "/" + pkgId + "/" + fullVersionString
+ "/" + pkgId + "-" + fullVersionString + "." + Constants.PaquetFileEstension;
this.PackageContent = apiBase + ApiConfig.ContentBase + "/" + pkgId + "/" + fullVersionString
+ "/" + pkgId + "-" + fullVersionString + "." + Constants.PacketFileExtension;
Entry = entry;
}

View File

@ -7,23 +7,23 @@ using NuGet.Versioning;
namespace isnd.Data.Catalog
{
public class CatalogPage : Permalink
public class RegistrationPage : Permalink
{
private readonly string pkgid;
private readonly List<Package> items;
private readonly List<RegistrationLeaf> items;
private readonly string apiBase;
public CatalogPage (string pkgid, string apiBase) : base(apiBase + $"/registration/{pkgid}/index.json")
public RegistrationPage (string pkgid, string apiBase) : base(apiBase + $"/registration/{pkgid}/index.json")
{
Parent = apiBase + $"/registration/{pkgid}/index.json";
this.items = new List<Package>();
this.items = new List<RegistrationLeaf>();
this.pkgid = pkgid;
this.apiBase = apiBase;
}
public CatalogPage(string bid, string pkgid, string apiBase, List<PackageVersion> versions) : this(pkgid, apiBase)
public RegistrationPage(string pkgid, string apiBase, IEnumerable<PackageVersion> versions) : this(pkgid, apiBase)
{
AddVersionRange(versions);
}
@ -39,7 +39,7 @@ namespace isnd.Data.Catalog
/// <value></value>
[JsonProperty("items")]
public Package[] Items { get => items.ToArray(); }
public RegistrationLeaf[] Items { get => items.ToArray(); }
public void AddVersionRange(IEnumerable<PackageVersion> vitems)
{
@ -54,6 +54,7 @@ namespace isnd.Data.Catalog
long commitMax = 0;
foreach (var p in vitems)
{
if (p.LatestCommit==null) continue;
var pkg = p.ToPackage(apiBase);
if (items.Contains(pkg)) continue;
@ -69,8 +70,8 @@ namespace isnd.Data.Catalog
}
items.Add(pkg);
}
Upper = upper.ToFullString();
Lower = lower.ToFullString();
Upper = upper?.ToFullString() ?? lower?.ToFullString();
Lower = lower?.ToFullString() ?? upper?.ToFullString();
}
/// <summary>

Some files were not shown because too many files have changed in this diff Show More