Compare commits
71 Commits
Author | SHA1 | Date |
---|---|---|
tastytea | f57f3b578d | |
tastytea | f5dc5e2359 | |
tastytea | e1c20bd1bd | |
tastytea | 9caeab9b91 | |
tastytea | aabd458e62 | |
tastytea | a1850db226 | |
tastytea | 7438f878c2 | |
tastytea | 6a4e15df81 | |
tastytea | 82261aadfb | |
tastytea | 23031b0dc9 | |
tastytea | f869ed9df2 | |
tastytea | 1e52e8edac | |
tastytea | 5cbbca2111 | |
tastytea | 6b08adce38 | |
tastytea | 98b6572b14 | |
tastytea | f3b97151f1 | |
tastytea | a83a11d8e2 | |
tastytea | c3fb4850ae | |
tastytea | 6dc9c1a740 | |
tastytea | 9c99aafe87 | |
tastytea | 089534e07d | |
tastytea | 0bcad56590 | |
tastytea | c0eb7494e1 | |
tastytea | fa225ff8e7 | |
tastytea | 82bbd03a2c | |
tastytea | 4a40cac16b | |
tastytea | 257d6ff09b | |
tastytea | 15ee493084 | |
tastytea | 8574da33a7 | |
tastytea | 7839cd3658 | |
tastytea | 0a1b9cfcaf | |
tastytea | d9d029b952 | |
tastytea | 51f3c0b4df | |
tastytea | aec946c50f | |
tastytea | 6ef00b689a | |
tastytea | 953c1cf3e7 | |
tastytea | 18a0edb30a | |
tastytea | d25fbccc9f | |
tastytea | 25cce227c1 | |
tastytea | 8cee77f743 | |
tastytea | c67875b75c | |
tastytea | 5906db11da | |
tastytea | 095645ba6e | |
tastytea | d9d28dd707 | |
tastytea | c19f5681a2 | |
tastytea | c7e36a7297 | |
tastytea | 31013f5192 | |
tastytea | babd67a750 | |
tastytea | 9e8504a0f5 | |
tastytea | e78d9cb346 | |
tastytea | 76ab574e09 | |
tastytea | 7b0920ee95 | |
tastytea | eee64c1f2d | |
tastytea | 74b8e58bf6 | |
tastytea | 6fb470effa | |
tastytea | a3ce76cbc1 | |
tastytea | fb7c3beca8 | |
tastytea | 84f290cf8e | |
tastytea | 820d1b8e17 | |
tastytea | 0e24f0433c | |
tastytea | 4e62eb1fcc | |
tastytea | 067fba7447 | |
tastytea | 6ff05f11ff | |
tastytea | 13709efbba | |
tastytea | d41b18183e | |
tastytea | 8c21e93791 | |
tastytea | 79dab8bd17 | |
tastytea | 08690e30fa | |
tastytea | 97c7e20da7 | |
tastytea | 6030c41243 | |
tastytea | 29d8ee8e61 |
|
@ -0,0 +1,131 @@
|
||||||
|
# -*- mode: yaml -*-
|
||||||
|
# Written for clang-format 10.
|
||||||
|
# https://releases.llvm.org/10.0.0/tools/clang/docs/ClangFormatStyleOptions.html
|
||||||
|
---
|
||||||
|
DisableFormat: false
|
||||||
|
Language: Cpp
|
||||||
|
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
# AlignConsecutiveBitFields: false # clang-format 11
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignConsecutiveMacros: false
|
||||||
|
AlignEscapedNewlines: DontAlign
|
||||||
|
AlignOperands: true # clang-format 11: Align
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
# AllowShortEnumsOnASingleLine: false # clang-format 11
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: Inline
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping: # If BreakBeforeBraces is set to Custom.
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: Always
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
# BeforeLambdaBody: true # clang-format 11
|
||||||
|
# BeforeWhile: true # clang-format 11
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
# CommentPragmas: 'regex'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- FOREACH
|
||||||
|
- RANGES_FOR
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories: # stdlib headers into own group.
|
||||||
|
- Regex: '^[^\.]+$'
|
||||||
|
Priority: 4
|
||||||
|
# IndentCaseBlocks: false # clang-format 11
|
||||||
|
IndentCaseLabels: false
|
||||||
|
# IndentExternBlock: NoIndent # clang-format 11
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
# MacroBlockBegin: 'string'
|
||||||
|
# MacroBlockEnd: 'string'
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
# NamespaceMacros: 'string'
|
||||||
|
PenaltyBreakAssignment: 250
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 300
|
||||||
|
# PenaltyBreakComment: 300
|
||||||
|
# PenaltyBreakFirstLessLess: 120
|
||||||
|
# PenaltyBreakString: 1000
|
||||||
|
# PenaltyBreakTemplateDeclaration: 10
|
||||||
|
# PenaltyExcessCharacter: 1000000
|
||||||
|
# PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
# RawStringFormats: # <YAML>
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
# StatementMacros:
|
||||||
|
# - Q_UNUSED
|
||||||
|
# - QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 4
|
||||||
|
# TypenameMacros:
|
||||||
|
# - STACK_OF
|
||||||
|
# - LIST
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
# WhitespaceSensitiveMacros: ['string', 'string'] # clang-format 11
|
||||||
|
...
|
236
.drone.yml
236
.drone.yml
|
@ -1,192 +1,54 @@
|
||||||
pipeline:
|
# -*- fill-column: 1000 -*-
|
||||||
gcc5:
|
kind: pipeline
|
||||||
image: debian:stretch-slim
|
name: on_push
|
||||||
pull: true
|
|
||||||
when:
|
|
||||||
event: [push, pull_request]
|
|
||||||
environment:
|
|
||||||
- LANG=C.utf8
|
|
||||||
- CXX=g++-5
|
|
||||||
- CXXFLAGS=-pipe -O2
|
|
||||||
commands:
|
|
||||||
- rm /etc/apt/apt.conf.d/docker-clean
|
|
||||||
- apt-get update -q
|
|
||||||
- echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
|
||||||
- echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
|
||||||
- echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" >> /etc/apt/sources.list.d/ubuntu-toolchain-r.list
|
|
||||||
- apt-get install -qy gnupg
|
|
||||||
- gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 0x60c317803a41ba51845e371a1e9377a2ba9ef27f
|
|
||||||
- gpg --armor --export 0x60c317803a41ba51845e371a1e9377a2ba9ef27f | apt-key add -
|
|
||||||
- apt-get update -q
|
|
||||||
- apt-get install -qy -t xenial g++-5
|
|
||||||
- apt-get install -qy cmake pkg-config
|
|
||||||
- apt-get install -qy libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
|
||||||
- apt-get install -qy -t sid libcurlpp-dev
|
|
||||||
- rm -rf build && mkdir -p build && cd build
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
|
||||||
- make VERBOSE=1
|
|
||||||
volumes:
|
|
||||||
- /var/cache/debian-package-cache:/var/cache/apt/archives
|
|
||||||
|
|
||||||
gcc6:
|
volumes:
|
||||||
image: debian:stretch-slim
|
- name: debian-package-cache
|
||||||
pull: true
|
host:
|
||||||
when:
|
path: /var/cache/debian-package-cache
|
||||||
event: [push, pull_request]
|
|
||||||
environment:
|
|
||||||
- LANG=C.utf8
|
|
||||||
- CXX=g++-6
|
|
||||||
- CXXFLAGS=-pipe -O2
|
|
||||||
commands:
|
|
||||||
- rm /etc/apt/apt.conf.d/docker-clean
|
|
||||||
- echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
|
||||||
- echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
|
||||||
- apt-get update -q
|
|
||||||
- apt-get install -qy g++-6 cmake pkg-config
|
|
||||||
- apt-get install -qy libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
|
||||||
- apt-get install -qy -t sid libcurlpp-dev
|
|
||||||
- rm -rf build && mkdir -p build && cd build
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
|
||||||
- make VERBOSE=1
|
|
||||||
volumes:
|
|
||||||
- /var/cache/debian-package-cache:/var/cache/apt/archives
|
|
||||||
|
|
||||||
gcc7:
|
trigger:
|
||||||
image: debian:stretch-slim
|
event:
|
||||||
pull: true
|
exclude:
|
||||||
when:
|
- tag
|
||||||
event: [push, pull_request]
|
|
||||||
environment:
|
|
||||||
- LANG=C.utf8
|
|
||||||
- CXX=g++-7
|
|
||||||
- CXXFLAGS=-pipe -O2
|
|
||||||
commands:
|
|
||||||
- rm /etc/apt/apt.conf.d/docker-clean
|
|
||||||
- apt-get update -q
|
|
||||||
- echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
|
||||||
- echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
|
||||||
- echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" >> /etc/apt/sources.list.d/ubuntu-toolchain-r.list
|
|
||||||
- apt-get install -qy gnupg
|
|
||||||
- gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 0x60c317803a41ba51845e371a1e9377a2ba9ef27f
|
|
||||||
- gpg --armor --export 0x60c317803a41ba51845e371a1e9377a2ba9ef27f | apt-key add -
|
|
||||||
- apt-get update -q
|
|
||||||
- apt-get install -qy -t xenial g++-7
|
|
||||||
- apt-get install -qy cmake pkg-config
|
|
||||||
- apt-get install -qy libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
|
||||||
- apt-get install -qy -t sid libcurlpp-dev
|
|
||||||
- rm -rf build && mkdir -p build && cd build
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
|
||||||
- make VERBOSE=1
|
|
||||||
volumes:
|
|
||||||
- /var/cache/debian-package-cache:/var/cache/apt/archives
|
|
||||||
|
|
||||||
gcc8:
|
steps:
|
||||||
image: debian:stretch-slim
|
- name: GCC 8 / clang 7
|
||||||
pull: true
|
image: debian:buster-slim
|
||||||
when:
|
pull: always
|
||||||
event: [push, pull_request]
|
environment:
|
||||||
environment:
|
CXX: g++-8
|
||||||
- LANG=C.utf8
|
CXXFLAGS: -pipe -O2
|
||||||
- CXX=g++-8
|
LANG: en_US.utf-8
|
||||||
- CXXFLAGS=-pipe -O2
|
DEBIAN_FRONTEND: noninteractive
|
||||||
commands:
|
commands:
|
||||||
- rm /etc/apt/apt.conf.d/docker-clean
|
- rm /etc/apt/apt.conf.d/docker-clean
|
||||||
- apt-get update -q
|
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
|
||||||
- echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
- apt-get update -q
|
||||||
- echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
- apt-get install -qq build-essential clang cmake pkg-config catch libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
||||||
- echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" >> /etc/apt/sources.list.d/ubuntu-toolchain-r.list
|
- rm -rf build && mkdir -p build && cd build
|
||||||
- apt-get install -qy gnupg
|
- cmake -DWITH_TESTS=yes ..
|
||||||
- gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 0x60c317803a41ba51845e371a1e9377a2ba9ef27f
|
- cmake --build .
|
||||||
- gpg --armor --export 0x60c317803a41ba51845e371a1e9377a2ba9ef27f | apt-key add -
|
- cd tests && ctest -V
|
||||||
- apt-get update -q
|
- cd ../../
|
||||||
- apt-get install -qy -t xenial g++-8
|
- rm -rf build && mkdir -p build && cd build
|
||||||
- apt-get install -qy cmake pkg-config
|
- CXX="clang++" cmake -DWITH_TESTS=yes ..
|
||||||
- apt-get install -qy libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
- cmake --build .
|
||||||
- apt-get install -qy -t sid libcurlpp-dev
|
- cd tests && ctest -V
|
||||||
- rm -rf build && mkdir -p build && cd build
|
- make install
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
volumes:
|
||||||
- make VERBOSE=1
|
- name: debian-package-cache
|
||||||
volumes:
|
path: /var/cache/apt/archives
|
||||||
- /var/cache/debian-package-cache:/var/cache/apt/archives
|
|
||||||
|
|
||||||
clang3:
|
- name: notify
|
||||||
image: debian:stretch-slim
|
image: drillster/drone-email
|
||||||
pull: true
|
pull: always
|
||||||
when:
|
settings:
|
||||||
event: [push, pull_request]
|
host: mail.tzend.de
|
||||||
environment:
|
|
||||||
- LANG=C.utf8
|
|
||||||
- CXX=clang++
|
|
||||||
- CXXFLAGS=-pipe -O2
|
|
||||||
commands:
|
|
||||||
- rm /etc/apt/apt.conf.d/docker-clean
|
|
||||||
- echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
|
||||||
- echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
|
||||||
- apt-get update -q
|
|
||||||
- apt-get install -qy clang cmake pkg-config
|
|
||||||
- apt-get install -qy libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
|
||||||
- apt-get install -qy -t sid libcurlpp-dev
|
|
||||||
- rm -rf build && mkdir -p build && cd build
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
|
||||||
- make VERBOSE=1
|
|
||||||
volumes:
|
|
||||||
- /var/cache/debian-package-cache:/var/cache/apt/archives
|
|
||||||
|
|
||||||
clang5:
|
|
||||||
image: debian:stretch-slim
|
|
||||||
pull: true
|
|
||||||
when:
|
|
||||||
event: [push, pull_request]
|
|
||||||
environment:
|
|
||||||
- LANG=C.utf8
|
|
||||||
- CXX=clang++-5.0
|
|
||||||
- CXXFLAGS=-pipe -O2
|
|
||||||
commands:
|
|
||||||
- rm /etc/apt/apt.conf.d/docker-clean
|
|
||||||
- echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
|
||||||
- echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
|
||||||
- echo "deb http://deb.debian.org/debian stretch-backports main" >> /etc/apt/sources.list.d/stretch.list
|
|
||||||
- apt-get update -q
|
|
||||||
- apt-get install -qy -t stretch-backports clang-5.0
|
|
||||||
- apt-get install -qy cmake pkg-config
|
|
||||||
- apt-get install -qy libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
|
||||||
- apt-get install -qy -t sid libcurlpp-dev
|
|
||||||
- rm -rf build && mkdir -p build && cd build
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
|
||||||
- make VERBOSE=1
|
|
||||||
volumes:
|
|
||||||
- /var/cache/debian-package-cache:/var/cache/apt/archives
|
|
||||||
|
|
||||||
clang6:
|
|
||||||
image: debian:stretch-slim
|
|
||||||
pull: true
|
|
||||||
when:
|
|
||||||
event: [push, pull_request]
|
|
||||||
environment:
|
|
||||||
- LANG=C.utf8
|
|
||||||
- CXX=clang++-6.0
|
|
||||||
- CXXFLAGS=-pipe -O2
|
|
||||||
commands:
|
|
||||||
- rm /etc/apt/apt.conf.d/docker-clean
|
|
||||||
- echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
|
||||||
- echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
|
||||||
- echo "deb http://deb.debian.org/debian stretch-backports main" >> /etc/apt/sources.list.d/stretch.list
|
|
||||||
- apt-get update -q
|
|
||||||
- apt-get install -qy -t stretch-backports clang-6.0
|
|
||||||
- apt-get install -qy cmake pkg-config
|
|
||||||
- apt-get install -qy libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
|
||||||
- apt-get install -qy -t sid libcurlpp-dev
|
|
||||||
- rm -rf build && mkdir -p build && cd build
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
|
||||||
- make VERBOSE=1
|
|
||||||
volumes:
|
|
||||||
- /var/cache/debian-package-cache:/var/cache/apt/archives
|
|
||||||
|
|
||||||
notify:
|
|
||||||
image: drillster/drone-email
|
|
||||||
pull: true
|
|
||||||
host: cryptoparty-celle.de
|
|
||||||
secrets: [ email_username, email_password ]
|
|
||||||
from: drone@tzend.de
|
from: drone@tzend.de
|
||||||
when:
|
username:
|
||||||
status: [ changed, failure ]
|
from_secret: email_username
|
||||||
|
password:
|
||||||
|
from_secret: email_password
|
||||||
|
when:
|
||||||
|
status: [ changed, failure ]
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Configuration file for EditorConfig.
|
||||||
|
# More information is available under <https://editorconfig.org/>.
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
max_line_length = 80
|
||||||
|
|
||||||
|
[*.?pp]
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 4
|
||||||
|
|
||||||
|
[{CMakeLists.txt,*.cmake}]
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
|
@ -1,51 +1,30 @@
|
||||||
cmake_minimum_required (VERSION 3.2)
|
# IMPORTED target CURL::libcurl needs 3.12.
|
||||||
project(gitea2rss
|
cmake_minimum_required(VERSION 3.12...3.18)
|
||||||
VERSION 0.4.0
|
|
||||||
LANGUAGES CXX
|
|
||||||
)
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
project(gitea2rss
|
||||||
find_package(PkgConfig REQUIRED)
|
VERSION 0.7.0
|
||||||
pkg_check_modules(CURLPP REQUIRED curlpp)
|
DESCRIPTION "Generates RSS feeds from Gitea releases or tags."
|
||||||
pkg_check_modules(JSONCPP REQUIRED jsoncpp)
|
LANGUAGES CXX)
|
||||||
|
|
||||||
|
option(WITH_MAN "Compile and install manpage." YES)
|
||||||
|
option(WITH_TESTS "Compile tests." NO)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG
|
include(cmake/debug_flags.cmake)
|
||||||
"${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Wpedantic -ftrapv \
|
|
||||||
-fsanitize=undefined -g -Og -fno-omit-frame-pointer")
|
|
||||||
|
|
||||||
include_directories(${PROJECT_BINARY_DIR})
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(jsoncpp REQUIRED IMPORTED_TARGET jsoncpp)
|
||||||
|
find_package(CURL 7.56 REQUIRED)
|
||||||
|
|
||||||
include_directories(${CURLPP_INCLUDE_DIRS})
|
add_subdirectory(src)
|
||||||
include_directories(${JSONCPP_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
link_directories(${CURLPP_LIBRARY_DIRS})
|
|
||||||
link_directories(${JSONCPP_LIBRARY_DIRS})
|
|
||||||
|
|
||||||
# Write version in header
|
|
||||||
configure_file(
|
|
||||||
"${PROJECT_SOURCE_DIR}/src/version.hpp.in"
|
|
||||||
"${PROJECT_BINARY_DIR}/version.hpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB sources src/*.cpp)
|
|
||||||
add_executable(${PROJECT_NAME} "${sources}")
|
|
||||||
target_link_libraries(${PROJECT_NAME} ${CURLPP_LIBRARIES} ${JSONCPP_LIBRARIES})
|
|
||||||
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
|
|
||||||
set(WITH_MAN "YES" CACHE STRING "WITH_MAN defaults to \"YES\"")
|
|
||||||
if (WITH_MAN)
|
if (WITH_MAN)
|
||||||
add_custom_command(
|
add_subdirectory(man)
|
||||||
OUTPUT "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.1"
|
endif()
|
||||||
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
|
|
||||||
DEPENDS "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.1.adoc"
|
if(WITH_TESTS)
|
||||||
COMMAND ${CMAKE_SOURCE_DIR}/build_manpage.sh
|
add_subdirectory(tests)
|
||||||
ARGS ${PROJECT_VERSION})
|
|
||||||
add_custom_target(run ALL DEPENDS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.1")
|
|
||||||
install(
|
|
||||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.1
|
|
||||||
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
60
README.adoc
60
README.adoc
|
@ -1,26 +1,28 @@
|
||||||
= gitea2rss
|
= gitea2rss
|
||||||
|
|
||||||
*gitea2rss* Generates RSS feeds from https://gitea.io[Gitea] releases or tags.
|
*gitea2rss* Generates RSS feeds from https://gitea.io[Gitea] releases, tags and
|
||||||
|
commits.
|
||||||
|
|
||||||
https://rss.schlomp.space/?repo=tastytea/gitea2rss[Subscribe to gitea2rss releases].
|
https://rss.schlomp.space/?repo=tastytea/gitea2rss[Subscribe to gitea2rss releases].
|
||||||
|
|
||||||
== Usage
|
== Usage
|
||||||
|
|
||||||
See https://schlomp.space/tastytea/gitea2rss/src/branch/master/gitea2rss.1.adoc[manpage].
|
See https://schlomp.space/tastytea/gitea2rss/src/branch/master/man/gitea2rss.1.adoc[manpage].
|
||||||
|
For an example nginx configuration file, see https://schlomp.space/tastytea/gitea2rss/src/branch/master/doc/nginx-example.conf[nginx-example.conf].
|
||||||
|
|
||||||
== Install
|
== Install
|
||||||
|
|
||||||
|
[alt="Packaging status" link=https://repology.org/project/gitea2rss/versions]
|
||||||
|
image::https://repology.org/badge/vertical-allrepos/gitea2rss.svg[]
|
||||||
|
|
||||||
=== Gentoo
|
=== Gentoo
|
||||||
|
|
||||||
Add my https://schlomp.space/tastytea/overlay[repository] and install it from
|
[source,shell]
|
||||||
there.
|
|
||||||
|
|
||||||
[source,shellsession]
|
|
||||||
----
|
----
|
||||||
eselect repository enable tastytea
|
eselect repository enable guru
|
||||||
echo "dev-util/gitea2rss ~amd64" >> /etc/portage/package.accept_keywords/gitea2rss
|
echo 'www-misc/gitea2rss' >> /etc/portage/package.accept_keywords/gitea2rss
|
||||||
emaint sync -r tastytea
|
emaint sync -r guru
|
||||||
emerge -a dev-util/gitea2rss
|
emerge -a www-misc/gitea2rss
|
||||||
----
|
----
|
||||||
|
|
||||||
=== From source
|
=== From source
|
||||||
|
@ -28,25 +30,19 @@ emerge -a dev-util/gitea2rss
|
||||||
==== Dependencies
|
==== Dependencies
|
||||||
|
|
||||||
* Tested OS: Linux
|
* Tested OS: Linux
|
||||||
* C++ compiler (tested: https://gcc.gnu.org/[gcc] 5/6/7/8,
|
* C++ compiler (tested: https://gcc.gnu.org/[gcc] 8/9/10,
|
||||||
https://llvm.org/[clang] 3/5/6)
|
https://llvm.org/[clang] 7)
|
||||||
* https://cmake.org/[cmake] (at least: 3.6)
|
* https://cmake.org/[cmake] (at least: 3.12)
|
||||||
* https://pkgconfig.freedesktop.org/wiki/[pkgconfig] (tested: 0.29)
|
* https://curl.haxx.se/libcurl/[libcurl] (at least: 7.56)
|
||||||
* http://www.curlpp.org/[curlpp] (tested: 0.8)
|
|
||||||
* https://github.com/open-source-parsers/jsoncpp[jsoncpp] (tested: 1.8)
|
* https://github.com/open-source-parsers/jsoncpp[jsoncpp] (tested: 1.8)
|
||||||
* Optional:
|
* Optional:
|
||||||
** Manpage: http://asciidoc.org/[asciidoc] (tested: 8.6)
|
** Manpage: http://asciidoc.org/[asciidoc] (tested: 8.6)
|
||||||
|
|
||||||
===== Debian stretch
|
===== Debian stretch
|
||||||
|
|
||||||
[source,shellsession]
|
[source,shell]
|
||||||
----
|
----
|
||||||
echo "APT::Default-Release \"stretch\";" >> /etc/apt/apt.conf.d/00default_release
|
apt install build-essential cmake libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
||||||
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
|
|
||||||
apt-get update
|
|
||||||
apt-get install g++-6 cmake pkg-config libcurl4-openssl-dev libjsoncpp-dev asciidoc
|
|
||||||
apt-get install -t sid libcurlpp-dev
|
|
||||||
export CXX="g++-6"
|
|
||||||
----
|
----
|
||||||
|
|
||||||
==== Get sourcecode
|
==== Get sourcecode
|
||||||
|
@ -58,17 +54,16 @@ https://schlomp.space/tastytea/gitea2rss/releases[schlomp.space].
|
||||||
|
|
||||||
===== Development version
|
===== Development version
|
||||||
|
|
||||||
[source,shellsession]
|
[source,shell]
|
||||||
----
|
----
|
||||||
git clone https://schlomp.space/tastytea/gitea2rss.git
|
git clone https://schlomp.space/tastytea/gitea2rss.git
|
||||||
----
|
----
|
||||||
|
|
||||||
==== Compile
|
==== Compile
|
||||||
|
|
||||||
[source,shellsession]
|
[source,shell]
|
||||||
----
|
----
|
||||||
mkdir build
|
mkdir build && cd build
|
||||||
cd build/
|
|
||||||
cmake ..
|
cmake ..
|
||||||
cmake --build .
|
cmake --build .
|
||||||
----
|
----
|
||||||
|
@ -76,14 +71,7 @@ cmake --build .
|
||||||
.cmake options:
|
.cmake options:
|
||||||
* `-DCMAKE_BUILD_TYPE=Debug` for a debug build.
|
* `-DCMAKE_BUILD_TYPE=Debug` for a debug build.
|
||||||
* `-DWITH_MAN=NO` to not compile the manpage.
|
* `-DWITH_MAN=NO` to not compile the manpage.
|
||||||
|
* `-DWITH_TESTS=YES` to compile the tests.
|
||||||
|
|
||||||
Install with `make install`.
|
You can run the tests with `ctest` inside `build/tests`. Install with `make
|
||||||
|
install`.
|
||||||
== Copyright
|
|
||||||
|
|
||||||
----
|
|
||||||
Copyright © 2019 tastytea <tastytea@tastytea.de>.
|
|
||||||
License GPLv3: GNU GPL version 3 <https://www.gnu.org/licenses/gpl-3.0.html>.
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY. This is free software,
|
|
||||||
and you are welcome to redistribute it under certain conditions.
|
|
||||||
----
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Set compiler flags for Debug builds.
|
||||||
|
# Only has an effect on GCC/Clang >= 5.0.
|
||||||
|
|
||||||
|
set(tmp_CXXFLAGS "")
|
||||||
|
set(tmp_LDFLAGS "")
|
||||||
|
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"
|
||||||
|
AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5")
|
||||||
|
list(APPEND tmp_CXXFLAGS
|
||||||
|
"-Wall"
|
||||||
|
"-Wextra"
|
||||||
|
"-Wpedantic"
|
||||||
|
"-Wuninitialized"
|
||||||
|
"-Wshadow"
|
||||||
|
"-Wnon-virtual-dtor"
|
||||||
|
"-Wconversion"
|
||||||
|
"-Wsign-conversion"
|
||||||
|
"-Wold-style-cast"
|
||||||
|
"-Wzero-as-null-pointer-constant"
|
||||||
|
"-Wmissing-declarations"
|
||||||
|
"-Wcast-align"
|
||||||
|
"-Wunused"
|
||||||
|
"-Woverloaded-virtual"
|
||||||
|
"-Wdouble-promotion"
|
||||||
|
"-Wformat=2"
|
||||||
|
"-ftrapv"
|
||||||
|
"-fsanitize=undefined"
|
||||||
|
"-Og"
|
||||||
|
"-fno-omit-frame-pointer")
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
|
list(APPEND tmp_CXXFLAGS
|
||||||
|
"-Wlogical-op"
|
||||||
|
"-Wuseless-cast")
|
||||||
|
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6")
|
||||||
|
list(APPEND tmp_CXXFLAGS
|
||||||
|
"-Wmisleading-indentation"
|
||||||
|
"-Wduplicated-cond"
|
||||||
|
"-Wnull-dereference")
|
||||||
|
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "7")
|
||||||
|
list(APPEND tmp_CXXFLAGS
|
||||||
|
"-Wduplicated-branches")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
add_compile_options("$<$<CONFIG:Debug>:${tmp_CXXFLAGS}>")
|
||||||
|
|
||||||
|
list(APPEND tmp_LDFLAGS
|
||||||
|
"-fsanitize=undefined")
|
||||||
|
# add_link_options was introduced in version 3.13.
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS 3.13)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${tmp_LDFLAGS}")
|
||||||
|
else()
|
||||||
|
add_link_options("$<$<CONFIG:Debug>:${tmp_LDFLAGS}>")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS
|
||||||
|
"No additional compiler flags were set, "
|
||||||
|
"because your compiler was not anticipated.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
unset(tmp_CXXFLAGS)
|
||||||
|
unset(tmp_LDFLAGS)
|
|
@ -1,24 +0,0 @@
|
||||||
# RSS feeds will be available at <https://rss.example.com/?repo=user/project>.
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
listen [::]:443 ssl;
|
|
||||||
server_name rss.example.com;
|
|
||||||
|
|
||||||
#access_log /var/log/nginx/rss.access_log main;
|
|
||||||
error_log /var/log/nginx/rss.error_log warn;
|
|
||||||
|
|
||||||
ssl_certificate /var/lib/dehydrated/certs/rss.example.com/fullchain.pem;
|
|
||||||
ssl_certificate_key /var/lib/dehydrated/certs/rss.example.com/privkey.pem;
|
|
||||||
|
|
||||||
expires 1h;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
include /etc/nginx/fastcgi_params;
|
|
||||||
# You may need to change fastcgi_pass.
|
|
||||||
fastcgi_pass unix:/var/run/cgi-fcgiwrap.socket-1;
|
|
||||||
fastcgi_param SCRIPT_FILENAME /usr/bin/gitea2rss;
|
|
||||||
# Base URL of your Gitea instance.
|
|
||||||
fastcgi_param GITEA2RSS_BASEURL "https://git.example.com";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Use 100 MiB cache with a 1 MiB memory zone (enough for ~8,000 keys).
|
||||||
|
# Delete data that has not been accessed for 10 minutes.
|
||||||
|
fastcgi_cache_path /var/cache/nginx/gitea2rss levels=1:2 keys_zone=gitea2rss:1m
|
||||||
|
max_size=100m inactive=10m use_temp_path=off;
|
||||||
|
fastcgi_cache_key "$scheme$request_method$host$request_uri";
|
||||||
|
add_header X-Cache $upstream_cache_status;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
server_name rss.example.com;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/rss.example.com_log warn;
|
||||||
|
|
||||||
|
ssl_certificate /var/lib/dehydrated/certs/rss.example.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /var/lib/dehydrated/certs/rss.example.com/privkey.pem;
|
||||||
|
|
||||||
|
# Tell clients to cache for 30 minutes.
|
||||||
|
expires 30m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
include /etc/nginx/fastcgi_params;
|
||||||
|
# You may need to change fastcgi_pass.
|
||||||
|
fastcgi_pass unix:/var/run/cgi-fcgiwrap.socket-1;
|
||||||
|
fastcgi_param SCRIPT_FILENAME /usr/bin/gitea2rss;
|
||||||
|
|
||||||
|
# Base URL of your Gitea instance.
|
||||||
|
fastcgi_param GITEA2RSS_BASEURL "https://git.example.com";
|
||||||
|
|
||||||
|
fastcgi_cache gitea2rss;
|
||||||
|
fastcgi_cache_valid 200 10m; # Cache answers for up to 10 minutes.
|
||||||
|
fastcgi_cache_lock on; # Relay only one identical request at a time.
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.1"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
DEPENDS "${PROJECT_NAME}.1.adoc"
|
||||||
|
COMMAND "${PROJECT_SOURCE_DIR}/man/build_manpage.sh"
|
||||||
|
ARGS "${PROJECT_VERSION}")
|
||||||
|
|
||||||
|
add_custom_target(man ALL
|
||||||
|
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.1")
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.1
|
||||||
|
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
|
@ -3,7 +3,7 @@
|
||||||
name="gitea2rss"
|
name="gitea2rss"
|
||||||
|
|
||||||
if [ -n "${1}" ]; then
|
if [ -n "${1}" ]; then
|
||||||
dir="$(dirname ${0})"
|
dir=$(dirname "${0}")
|
||||||
version=${1}
|
version=${1}
|
||||||
cp -vf "${dir}/${name}.1.adoc" .
|
cp -vf "${dir}/${name}.1.adoc" .
|
||||||
sed -Ei "s/(Revision: +)[0-9]+\.[0-9]\.[0-9]/\1${version}/" "${name}.1.adoc"
|
sed -Ei "s/(Revision: +)[0-9]+\.[0-9]\.[0-9]/\1${version}/" "${name}.1.adoc"
|
|
@ -2,7 +2,7 @@
|
||||||
:doctype: manpage
|
:doctype: manpage
|
||||||
:Author: tastytea
|
:Author: tastytea
|
||||||
:Email: tastytea@tastytea.de
|
:Email: tastytea@tastytea.de
|
||||||
:Date: 2019-04-20
|
:Date: 2021-04-25
|
||||||
:Revision: 0.0.0
|
:Revision: 0.0.0
|
||||||
:man source: gitea2rss
|
:man source: gitea2rss
|
||||||
:man version: {revision}
|
:man version: {revision}
|
||||||
|
@ -10,11 +10,11 @@
|
||||||
|
|
||||||
== NAME
|
== NAME
|
||||||
|
|
||||||
gitea2rss - Generates RSS feeds from Gitea releases.
|
gitea2rss - Generates RSS feeds from Gitea releases or tags.
|
||||||
|
|
||||||
== SYNOPSIS
|
== SYNOPSIS
|
||||||
|
|
||||||
*gitea2rss* _URL of Gitea project_ [_releases_|_tags_]
|
*gitea2rss* _URL of Gitea project_ [_releases_|_tags_|_commits_]
|
||||||
|
|
||||||
== DESCRIPTION
|
== DESCRIPTION
|
||||||
|
|
||||||
|
@ -27,15 +27,13 @@ If you want to use gitea2rss as a CGI script, you have to set
|
||||||
*GITEA2RSS_BASEURL* to the basis URL of your instance, without the trailing
|
*GITEA2RSS_BASEURL* to the basis URL of your instance, without the trailing
|
||||||
slash. For example: _https://git.example.com_. The *QUERY_STRING* must contain
|
slash. For example: _https://git.example.com_. The *QUERY_STRING* must contain
|
||||||
_repo=user/project_. The feed-URL for alice's project, cooltool, would be:
|
_repo=user/project_. The feed-URL for alice's project, cooltool, would be:
|
||||||
`https://rss.example.com/?repo=alice/cooltool`. You can select the type of the
|
_https://rss.example.com/?repo=alice/cooltool_. You can select the type of the
|
||||||
feed by appending `&type=` at the end of the URL. For example:
|
feed by appending `&type=` at the end of the URL. For example:
|
||||||
`https://rss.example.com/?repo=alice/cooltool&type=tags`.
|
_https://rss.example.com/?repo=alice/cooltool&type=tags_.
|
||||||
|
|
||||||
The generated RSS feed contains the *channel* elements _title_, _link_,
|
The generated RSS feed contains the *channel* elements _title_, _link_,
|
||||||
_description_, _generator_ and _lastBuildDate_ and the *item* elements _title_,
|
_description_, _generator_ and _lastBuildDate_ and the *item* elements _title_,
|
||||||
_link_, _guid_, _pubDate_ and _description_. Since Gitea has no individual pages
|
_link_, _guid_, _pubDate_ and _description_.
|
||||||
for each release, _link_ elements in *item* are set to the overview page for
|
|
||||||
releases.
|
|
||||||
|
|
||||||
== GITEA INTEGRATION
|
== GITEA INTEGRATION
|
||||||
|
|
||||||
|
@ -51,38 +49,41 @@ this in it:
|
||||||
href="https://rss.example.com/?repo={{.Repository.Owner.Name}}/{{.Repository.Name}}"/>
|
href="https://rss.example.com/?repo={{.Repository.Owner.Name}}/{{.Repository.Name}}"/>
|
||||||
<link rel="alternate" type="application/rss+xml"
|
<link rel="alternate" type="application/rss+xml"
|
||||||
title="Tags of {{.Repository.Name}}"
|
title="Tags of {{.Repository.Name}}"
|
||||||
href="https://rss.example.com/?repo={{.Repository.Owner.Name}}/{{.Repository.Name}}&type=tags"/>
|
href="https://rss.example.com/?repo={{.Repository.Owner.Name}}/{{.Repository.Name}}&type=tags"/>
|
||||||
|
<link rel="alternate" type="application/rss+xml"
|
||||||
|
title="Commits of {{.Repository.Name}}"
|
||||||
|
href="https://rss.example.com/?repo={{.Repository.Owner.Name}}/{{.Repository.Name}}&type=commits"/>
|
||||||
{{end}}
|
{{end}}
|
||||||
----
|
----
|
||||||
|
|
||||||
== PROXY SERVERS
|
== PROXY SERVERS
|
||||||
|
|
||||||
Since gitea2rss is built on libcurl, it respects the same proxy environment
|
Since *gitea2rss* is built on libcurl, it respects the same proxy environment
|
||||||
variables. See *curl*(1), section _ENVIRONMENT_.
|
variables. See *curl*(1), section _ENVIRONMENT_.
|
||||||
|
|
||||||
== EXAMPLES
|
== EXAMPLES
|
||||||
|
|
||||||
`gitea2rss https://git.example.com/user/project tags > repo.rss`
|
`gitea2rss https://git.example.com/user/project tags > repo.rss`
|
||||||
|
|
||||||
`https_proxy="socks4a://user:pass@localhost:9050/" gitea2rss
|
`ALL_PROXY="socks4a://[::1]:9050" gitea2rss https://git.example.com/user/project`
|
||||||
https://git.example.com/user/project`
|
|
||||||
|
|
||||||
=== Example RSS feed
|
=== Example RSS feed
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
<rss version="2.0">
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
<channel>
|
<channel>
|
||||||
|
<atom:link href="https://rss.schlomp.space/?repo=tastytea/gitea2rss" rel="self" type="application/rss+xml"/>
|
||||||
<title>gitea2rss releases</title>
|
<title>gitea2rss releases</title>
|
||||||
<link>https://schlomp.space/tastytea/gitea2rss</link>
|
<link>https://schlomp.space/tastytea/gitea2rss</link>
|
||||||
<description>Releases of tastytea/gitea2rss</description>
|
<description>List of releases of tastytea/gitea2rss</description>
|
||||||
<generator>gitea2rss 0.3.0</generator>
|
<generator>gitea2rss 0.4.4</generator>
|
||||||
<lastBuildDate>Wed, 17 Apr 2019 20:31:15 +0200</lastBuildDate>
|
<lastBuildDate>Mon, 22 Apr 2019 11:46:53 +0000</lastBuildDate>
|
||||||
<item>
|
<item>
|
||||||
<title>gitea2rss: 0.1.0</title>
|
<title>gitea2rss: 0.1.0</title>
|
||||||
<link>https://schlomp.space/tastytea/gitea2rss/releases</link>
|
<link>https://schlomp.space/tastytea/gitea2rss/releases</link>
|
||||||
<guid isPermaLink="false">schlomp.space release 169</guid>
|
<guid isPermaLink="false">schlomp.space release 169</guid>
|
||||||
<pubDate>Wed, 17 Apr 2019 05:37:10 +0200</pubDate>
|
<pubDate>Wed, 17 Apr 2019 04:37:10 +0000</pubDate>
|
||||||
<description>
|
<description>
|
||||||
<![CDATA[<p><strong>Stable</strong></p>
|
<![CDATA[<p><strong>Stable</strong></p>
|
||||||
<pre>First release. Everything works, as far as I can tell.</pre>
|
<pre>First release. Everything works, as far as I can tell.</pre>
|
|
@ -0,0 +1,16 @@
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
# Write version in header
|
||||||
|
configure_file("version.hpp.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/version.hpp")
|
||||||
|
|
||||||
|
file(GLOB sources *.cpp)
|
||||||
|
add_executable(${PROJECT_NAME} "${sources}" "gitea2rss.hpp")
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME}
|
||||||
|
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
PRIVATE PkgConfig::jsoncpp CURL::libcurl)
|
||||||
|
|
||||||
|
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2021 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
|
using std::cerr;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
using std::stringstream;
|
||||||
|
|
||||||
|
uint8_t write_commits(const string &url)
|
||||||
|
{
|
||||||
|
const string baseurl = get_baseurl(url);
|
||||||
|
const string repo = get_repo(url);
|
||||||
|
stringstream data(get_http(baseurl + "/api/v1/repos/" + repo + "/commits"));
|
||||||
|
|
||||||
|
if (cgi)
|
||||||
|
{
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.str().empty())
|
||||||
|
{
|
||||||
|
cerr << "Error: Could not download commits.\n";
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_preamble(url, "commits");
|
||||||
|
|
||||||
|
Json::Value json;
|
||||||
|
data >> json;
|
||||||
|
|
||||||
|
for (const Json::Value &commit : json)
|
||||||
|
{
|
||||||
|
const string sha = commit["sha"].asString();
|
||||||
|
string message = escape_some_html(
|
||||||
|
commit["commit"]["message"].asString());
|
||||||
|
const string title = message.substr(0, message.find('\n'));
|
||||||
|
{
|
||||||
|
size_t pos{};
|
||||||
|
while ((pos = message.find('\n')) != string::npos)
|
||||||
|
{
|
||||||
|
message.replace(pos, 1, "<br>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const string commit_url = commit["html_url"].asString();
|
||||||
|
const string author = commit["commit"]["author"]["email"].asString()
|
||||||
|
+ " ("
|
||||||
|
+ commit["commit"]["author"]["name"].asString()
|
||||||
|
+ ")";
|
||||||
|
const string date = strtime(
|
||||||
|
commit["commit"]["author"]["date"].asString());
|
||||||
|
|
||||||
|
cout << " <item>\n";
|
||||||
|
write_line(6, "title", get_project(url) + ": " + title);
|
||||||
|
write_line(6, "link", commit_url);
|
||||||
|
write_line(6, "guid isPermaLink=\"false\"",
|
||||||
|
get_domain(url) + " commit " + sha);
|
||||||
|
write_line(6, "author", author);
|
||||||
|
write_line(6, "pubDate", date);
|
||||||
|
write_line(6, "description",
|
||||||
|
"\n <![CDATA[<p>" + message + "</p>]]>\n ");
|
||||||
|
cout << " </item>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
|
bool cgi = false;
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019-2021 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,28 +17,37 @@
|
||||||
#ifndef GITEA2RSS_HPP
|
#ifndef GITEA2RSS_HPP
|
||||||
#define GITEA2RSS_HPP
|
#define GITEA2RSS_HPP
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ctime>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <ctime>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::chrono::system_clock;
|
|
||||||
using std::uint8_t;
|
using std::uint8_t;
|
||||||
|
using std::chrono::system_clock;
|
||||||
|
|
||||||
extern bool cgi;
|
extern bool cgi;
|
||||||
|
|
||||||
//! Fetch HTTP document.
|
//! Fetch HTTP document.
|
||||||
const string get_http(const string &url);
|
string get_http(const string &url);
|
||||||
|
|
||||||
|
// CURL receive function.
|
||||||
|
size_t writer_body(char *data, size_t size, size_t nmemb);
|
||||||
|
|
||||||
//! Convert time_point to RFC 822 compliant time string.
|
//! Convert time_point to RFC 822 compliant time string.
|
||||||
const string strtime(const system_clock::time_point &timepoint);
|
string strtime(const system_clock::time_point &timepoint);
|
||||||
|
|
||||||
//! Convert ISO 8601 time string to RFC 822 time string.
|
//! Convert ISO 8601 time string to RFC 822 time string.
|
||||||
const string strtime(const string &time);
|
string strtime(const string &time);
|
||||||
|
|
||||||
//! Write line of XML.
|
//! Write line of XML.
|
||||||
void write_line(const uint8_t spaces, const string &tag, const string &value);
|
void write_line(uint8_t spaces, const string &tag, const string &value);
|
||||||
|
|
||||||
|
//! Write the RSS preamble and channel data.
|
||||||
|
void write_preamble(const string &url, const string &type);
|
||||||
|
|
||||||
//! Write releases.
|
//! Write releases.
|
||||||
uint8_t write_releases(const string &url);
|
uint8_t write_releases(const string &url);
|
||||||
|
@ -46,16 +55,27 @@ uint8_t write_releases(const string &url);
|
||||||
//! Write tags.
|
//! Write tags.
|
||||||
uint8_t write_tags(const string &url);
|
uint8_t write_tags(const string &url);
|
||||||
|
|
||||||
|
//! Write commits.
|
||||||
|
uint8_t write_commits(const string &url);
|
||||||
|
|
||||||
//! @brief Get the base URL, without trailing slash.
|
//! @brief Get the base URL, without trailing slash.
|
||||||
const string get_baseurl(const string &url);
|
string get_baseurl(const string &url);
|
||||||
|
|
||||||
//! Get the domain name.
|
//! Get the domain name.
|
||||||
const string get_domain(const string &url);
|
string get_domain(const string &url);
|
||||||
|
|
||||||
//! Get the full name of the repo (user/project).
|
//! Get the full name of the repo (user/project).
|
||||||
const string get_repo(const string &url);
|
string get_repo(const string &url);
|
||||||
|
|
||||||
//! Get the project name.
|
//! Get the project name.
|
||||||
const string get_project(const string &url);
|
string get_project(const string &url);
|
||||||
|
|
||||||
#endif // GITEA2RSS_HPP
|
//! Escape some characters to named HTML entities.
|
||||||
|
string escape_some_html(string html);
|
||||||
|
|
||||||
|
//! Return environment variable or "" if it is not set.
|
||||||
|
string get_env_var(const string &variable);
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
||||||
|
#endif // GITEA2RSS_HPP
|
||||||
|
|
135
src/http.cpp
135
src/http.cpp
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -14,59 +14,112 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <exception>
|
|
||||||
#include <curlpp/cURLpp.hpp>
|
|
||||||
#include <curlpp/Easy.hpp>
|
|
||||||
#include <curlpp/Options.hpp>
|
|
||||||
#include <curlpp/Exception.hpp>
|
|
||||||
#include <curlpp/Infos.hpp>
|
|
||||||
#include "version.hpp"
|
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
#include "version.hpp"
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <exception>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace curlopts = curlpp::options;
|
namespace gitea2rss
|
||||||
|
|
||||||
using std::cout;
|
|
||||||
using std::cerr;
|
|
||||||
using std::endl;
|
|
||||||
using std::ostringstream;
|
|
||||||
using std::uint16_t;
|
|
||||||
|
|
||||||
const string get_http(const string &url)
|
|
||||||
{
|
{
|
||||||
string answer;
|
|
||||||
|
|
||||||
|
using std::cerr;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
using std::runtime_error;
|
||||||
|
using std::to_string;
|
||||||
|
|
||||||
|
string buffer_body;
|
||||||
|
|
||||||
|
string get_http(const string &url)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ostringstream oss;
|
curl_global_init(CURL_GLOBAL_ALL); // NOLINT(hicpp-signed-bitwise)
|
||||||
curlpp::Easy request;
|
CURL *connection{curl_easy_init()};
|
||||||
request.setOpt<curlopts::Url>(url);
|
if (connection == nullptr)
|
||||||
request.setOpt<curlopts::UserAgent>(string("gitea2rss/")
|
|
||||||
+ global::version);
|
|
||||||
request.setOpt<curlopts::HttpHeader>({ "Connection: close" });
|
|
||||||
request.setOpt<curlopts::FollowLocation>(true);
|
|
||||||
request.setOpt<curlopts::WriteStream>(&oss);
|
|
||||||
request.perform();
|
|
||||||
uint16_t ret = curlpp::infos::ResponseCode::get(request);
|
|
||||||
if (ret == 200 || ret == 302 || ret == 307
|
|
||||||
|| ret == 301 || ret == 308)
|
|
||||||
{
|
{
|
||||||
answer = oss.str();
|
throw runtime_error{"Failed to initialize curl."};
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
char buffer_error[256];
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
curl_easy_setopt(connection, CURLOPT_ERRORBUFFER, buffer_error);
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
curl_easy_setopt(connection, CURLOPT_WRITEFUNCTION, writer_body);
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
CURLcode code{curl_easy_setopt(connection, CURLOPT_FOLLOWLOCATION, 1L)};
|
||||||
|
if (code != CURLE_OK)
|
||||||
{
|
{
|
||||||
if (cgi)
|
throw runtime_error{"HTTP is not supported."};
|
||||||
{
|
|
||||||
cout << "Status: " << std::to_string(ret) << endl;
|
|
||||||
}
|
|
||||||
cerr << "HTTP Error: " << std::to_string(ret) << endl;
|
|
||||||
}
|
}
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
curl_easy_setopt(connection, CURLOPT_MAXREDIRS, 5L);
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
code = curl_easy_setopt(connection, CURLOPT_USERAGENT,
|
||||||
|
(string("gitea2rss/") += version).c_str());
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw runtime_error{"Failed to set User-Agent."};
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
curl_easy_setopt(connection, CURLOPT_HTTPGET, 1L);
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
code = curl_easy_setopt(connection, CURLOPT_URL, url.c_str());
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw runtime_error{"Couldn't set URL: " + to_string(code)};
|
||||||
|
}
|
||||||
|
|
||||||
|
code = curl_easy_perform(connection);
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw runtime_error{"libcurl error: " + to_string(code)};
|
||||||
|
}
|
||||||
|
|
||||||
|
long http_status{0}; // NOLINT(google-runtime-int)
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
curl_easy_getinfo(connection, CURLINFO_RESPONSE_CODE, &http_status);
|
||||||
|
|
||||||
|
curl_easy_cleanup(connection);
|
||||||
|
|
||||||
|
if (http_status == 200)
|
||||||
|
{
|
||||||
|
return buffer_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cgi)
|
||||||
|
{
|
||||||
|
cout << "Status: " << http_status << endl;
|
||||||
|
}
|
||||||
|
throw runtime_error{"HTTP error: " + to_string(http_status)};
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const runtime_error &e)
|
||||||
{
|
{
|
||||||
cerr << "Error: " << e.what() << endl;
|
cerr << "Error: " << e.what() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return answer;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t writer_body(char *data, size_t size, size_t nmemb)
|
||||||
|
{
|
||||||
|
if (data == nullptr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_body.append(data, size * nmemb);
|
||||||
|
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
58
src/main.cpp
58
src/main.cpp
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019-2021 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -14,34 +14,28 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
#include "version.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdlib>
|
|
||||||
#include <curlpp/cURLpp.hpp>
|
|
||||||
#include "version.hpp"
|
|
||||||
#include "gitea2rss.hpp"
|
|
||||||
|
|
||||||
using std::cout;
|
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::endl;
|
using std::cout;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::chrono::system_clock;
|
using namespace gitea2rss;
|
||||||
|
|
||||||
bool cgi = false;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const char *envquery = std::getenv("QUERY_STRING");
|
|
||||||
|
const string query{get_env_var("QUERY_STRING")};
|
||||||
string url;
|
string url;
|
||||||
string type = "releases";
|
string type = "releases";
|
||||||
|
|
||||||
curlpp::initialize();
|
if (!query.empty())
|
||||||
|
|
||||||
if (envquery != nullptr)
|
|
||||||
{
|
{
|
||||||
const string query = envquery;
|
const string baseurl{get_env_var("GITEA2RSS_BASEURL")};
|
||||||
const char *envbaseurl = std::getenv("GITEA2RSS_BASEURL");
|
if (baseurl.empty())
|
||||||
if (envbaseurl == nullptr)
|
|
||||||
{
|
{
|
||||||
cout << "Status: 500 Internal Server Error\n\n";
|
cout << "Status: 500 Internal Server Error\n\n";
|
||||||
cerr << "Error: GITEA2RSS_BASEURL not set\n";
|
cerr << "Error: GITEA2RSS_BASEURL not set\n";
|
||||||
|
@ -58,7 +52,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
const size_t pos_repo = pos_found + 5;
|
const size_t pos_repo = pos_found + 5;
|
||||||
const size_t pos_endrepo = query.find('&', pos_repo) - pos_repo;
|
const size_t pos_endrepo = query.find('&', pos_repo) - pos_repo;
|
||||||
url = string(envbaseurl) + "/" + query.substr(pos_repo, pos_endrepo);
|
url = string(baseurl) + "/" + query.substr(pos_repo, pos_endrepo);
|
||||||
|
|
||||||
// Look for type in QUERY_STRING.
|
// Look for type in QUERY_STRING.
|
||||||
pos_found = query.find("type=");
|
pos_found = query.find("type=");
|
||||||
|
@ -72,32 +66,22 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
else if (argc < 2)
|
else if (argc < 2)
|
||||||
{
|
{
|
||||||
cerr << "usage: " << argv[0] << " URL of Gitea project\n";
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||||
|
cerr << "usage: " << argv[0]
|
||||||
|
<< " URL of Gitea project [releases|tags|commits]\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||||
url = argv[1];
|
url = argv[1];
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
{
|
{
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||||
type = argv[2];
|
type = argv[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgi)
|
|
||||||
{
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "<rss version=\"2.0\">\n"
|
|
||||||
" <channel>\n";
|
|
||||||
|
|
||||||
write_line(4, "title", get_project(url) + " " + type);
|
|
||||||
write_line(4, "link", url);
|
|
||||||
write_line(4, "description", "List of " + type + " of " + get_repo(url));
|
|
||||||
write_line(4, "generator", string("gitea2rss ") + global::version);
|
|
||||||
write_line(4, "lastBuildDate", strtime(system_clock::now()));
|
|
||||||
|
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
if (type == "releases")
|
if (type == "releases")
|
||||||
{
|
{
|
||||||
|
@ -107,6 +91,10 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
ret = write_tags(url);
|
ret = write_tags(url);
|
||||||
}
|
}
|
||||||
|
else if (type == "commits")
|
||||||
|
{
|
||||||
|
ret = write_commits(url);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
|
@ -114,9 +102,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << " </channel>\n"
|
cout << " </channel>\n"
|
||||||
"</rss>\n";
|
"</rss>\n";
|
||||||
|
|
||||||
curlpp::terminate();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -14,28 +14,38 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <jsoncpp/json/json.h>
|
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using std::cout;
|
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
using std::stringstream;
|
using std::stringstream;
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
uint8_t write_releases(const string &url)
|
uint8_t write_releases(const string &url)
|
||||||
{
|
{
|
||||||
const string baseurl = get_baseurl(url);
|
const string baseurl = get_baseurl(url);
|
||||||
const string repo = get_repo(url);
|
const string repo = get_repo(url);
|
||||||
stringstream data(get_http(baseurl + "/api/v1/repos/"
|
stringstream data(
|
||||||
+ repo + "/releases"));
|
get_http(baseurl + "/api/v1/repos/" + repo + "/releases"));
|
||||||
|
|
||||||
|
if (cgi)
|
||||||
|
{
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
if (data.str().empty())
|
if (data.str().empty())
|
||||||
{
|
{
|
||||||
cerr << "Error: Could not download releases.\n";
|
cerr << "Error: Could not download releases.\n";
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_preamble(url, "releases");
|
||||||
|
|
||||||
Json::Value json;
|
Json::Value json;
|
||||||
data >> json;
|
data >> json;
|
||||||
|
|
||||||
|
@ -43,21 +53,30 @@ uint8_t write_releases(const string &url)
|
||||||
{
|
{
|
||||||
const bool prerelease = release["prerelease"].asBool();
|
const bool prerelease = release["prerelease"].asBool();
|
||||||
const string type = (prerelease ? "Pre-Release" : "Stable");
|
const string type = (prerelease ? "Pre-Release" : "Stable");
|
||||||
|
const string body = escape_some_html(release["body"].asString());
|
||||||
|
|
||||||
cout << " <item>\n";
|
cout << " <item>\n";
|
||||||
write_line(6, "title", get_project(url) + ": "
|
write_line(6, "title",
|
||||||
+ release["name"].asString());
|
get_project(url) + ": " + release["name"].asString());
|
||||||
write_line(6, "link", baseurl + "/" + repo + "/releases");
|
write_line(6, "link",
|
||||||
|
((baseurl + "/" += repo) += "/releases/tag/") +=
|
||||||
|
release["tag_name"].asString());
|
||||||
write_line(6, "guid isPermaLink=\"false\"",
|
write_line(6, "guid isPermaLink=\"false\"",
|
||||||
get_domain(url) + " release " + release["id"].asString());
|
get_domain(url) + " release " + release["id"].asString());
|
||||||
write_line(6, "pubDate", strtime(release["published_at"].asString()));
|
write_line(6, "pubDate", strtime(release["published_at"].asString()));
|
||||||
write_line(6, "description",
|
write_line(6, "description",
|
||||||
"\n <![CDATA[<p><strong>" + type + "</strong></p>\n"
|
"\n <![CDATA[<p><strong>" + type
|
||||||
"<pre>" + release["body"].asString() + "</pre>\n"
|
+ "</strong></p>\n"
|
||||||
" <p><a href=\"" + release["tarball_url"].asString()
|
"<pre>"
|
||||||
+ "\">Download tarball</a></p>]]>\n ");
|
+ body
|
||||||
|
+ "</pre>\n"
|
||||||
|
" <p><a href=\""
|
||||||
|
+ release["tarball_url"].asString()
|
||||||
|
+ "\">Download tarball</a></p>]]>\n ");
|
||||||
cout << " </item>\n";
|
cout << " </item>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019-2021 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,26 +16,61 @@
|
||||||
|
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
const string get_baseurl(const string &url)
|
#include <cstdlib>
|
||||||
|
#include <map>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
|
using std::getenv;
|
||||||
|
|
||||||
|
string get_baseurl(const string &url)
|
||||||
{
|
{
|
||||||
const size_t pos = url.find('/', 8);
|
const size_t pos = url.find('/', 8);
|
||||||
return url.substr(0, pos);
|
return url.substr(0, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string get_domain(const string &url)
|
string get_domain(const string &url)
|
||||||
{
|
{
|
||||||
const string baseurl = get_baseurl(url);
|
const string baseurl = get_baseurl(url);
|
||||||
return baseurl.substr(baseurl.rfind('/') + 1);
|
return baseurl.substr(baseurl.rfind('/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string get_repo(const string &url)
|
string get_repo(const string &url)
|
||||||
{
|
{
|
||||||
const size_t pos = url.find('/', 8) + 1;
|
const size_t pos = url.find('/', 8) + 1;
|
||||||
return url.substr(pos);
|
return url.substr(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string get_project(const string &url)
|
string get_project(const string &url)
|
||||||
{
|
{
|
||||||
const string repo = get_repo(url);
|
const string repo = get_repo(url);
|
||||||
return repo.substr(repo.find('/') + 1);
|
return repo.substr(repo.find('/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string escape_some_html(string html)
|
||||||
|
{
|
||||||
|
const std::map<const char, const string> names = {{'<', "<"},
|
||||||
|
{'>', ">"}};
|
||||||
|
|
||||||
|
for (const auto &pair : names)
|
||||||
|
{
|
||||||
|
const std::regex re(string(1, pair.first));
|
||||||
|
html = std::regex_replace(html, re, pair.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
string get_env_var(const string &variable)
|
||||||
|
{
|
||||||
|
const char *env{getenv(variable.c_str())};
|
||||||
|
if (env != nullptr)
|
||||||
|
{
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
42
src/tags.cpp
42
src/tags.cpp
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019-2021 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -14,21 +14,32 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <jsoncpp/json/json.h>
|
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
using std::cout;
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
using std::stringstream;
|
using std::stringstream;
|
||||||
|
|
||||||
uint8_t write_tags(const string &url)
|
uint8_t write_tags(const string &url)
|
||||||
{
|
{
|
||||||
const string baseurl = get_baseurl(url);
|
const string baseurl = get_baseurl(url);
|
||||||
const string repo = get_repo(url);
|
const string repo = get_repo(url);
|
||||||
stringstream data(get_http(baseurl + "/api/v1/repos/"
|
stringstream data(
|
||||||
+ repo + "/git/refs"));
|
get_http(baseurl + "/api/v1/repos/" + repo + "/git/refs"));
|
||||||
|
|
||||||
|
if (cgi)
|
||||||
|
{
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (data.str().empty())
|
if (data.str().empty())
|
||||||
{
|
{
|
||||||
|
@ -36,6 +47,8 @@ uint8_t write_tags(const string &url)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_preamble(url, "tags");
|
||||||
|
|
||||||
Json::Value json;
|
Json::Value json;
|
||||||
data >> json;
|
data >> json;
|
||||||
|
|
||||||
|
@ -51,14 +64,23 @@ uint8_t write_tags(const string &url)
|
||||||
|
|
||||||
cout << " <item>\n";
|
cout << " <item>\n";
|
||||||
write_line(6, "title", get_project(url) + ": " + name);
|
write_line(6, "title", get_project(url) + ": " + name);
|
||||||
write_line(6, "link", baseurl + "/" + repo + "/src/tag/" + name);
|
write_line(6, "link", baseurl + "/" += repo + "/src/tag/" += name);
|
||||||
write_line(6, "guid isPermaLink=\"false\"",
|
write_line(6, "guid isPermaLink=\"false\"",
|
||||||
get_domain(url) + " tag " + sha);
|
get_domain(url) + " tag " + sha);
|
||||||
write_line(6, "description",
|
write_line(6, "description",
|
||||||
"\n <![CDATA[<p><strong>" + name + "</strong> "
|
"\n <![CDATA[<p><strong>" + name
|
||||||
"with checksum " + sha + "</p>]]>\n ");
|
+ "</strong> "
|
||||||
|
"on commit "
|
||||||
|
+ sha
|
||||||
|
+ "</p>\n"
|
||||||
|
" <p><a href=\""
|
||||||
|
+ baseurl + "/" + repo + "/archive/" + name + ".tar.gz"
|
||||||
|
+ "\">Download tarball</a></p>]]>\n ");
|
||||||
|
|
||||||
cout << " </item>\n";
|
cout << " </item>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
42
src/time.cpp
42
src/time.cpp
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -14,25 +14,49 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
const string strtime(const system_clock::time_point &timepoint)
|
#include <ctime>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
|
string strtime(const system_clock::time_point &timepoint)
|
||||||
{
|
{
|
||||||
constexpr uint16_t bufsize = 1024;
|
constexpr uint16_t bufsize = 1024;
|
||||||
std::time_t time = system_clock::to_time_t(timepoint);
|
std::time_t time = system_clock::to_time_t(timepoint);
|
||||||
std::tm *tm;
|
std::tm *tm{std::gmtime(&time)};
|
||||||
tm = std::gmtime(&time);
|
|
||||||
char buffer[bufsize];
|
char buffer[bufsize];
|
||||||
std::strftime(buffer, bufsize, "%a, %d %b %Y %T %z", tm);
|
std::strftime(buffer, bufsize, "%a, %d %b %Y %T %z", tm);
|
||||||
return static_cast<const string>(buffer);
|
return static_cast<const string>(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string strtime(const string &time)
|
string strtime(const string &time)
|
||||||
{
|
{
|
||||||
|
// FIXME: Do this more elegantly.
|
||||||
std::tm tm = {};
|
std::tm tm = {};
|
||||||
tm.tm_isdst = -1; // Detect daylight saving time.
|
tm.tm_isdst = -1; // Detect daylight saving time.
|
||||||
std::stringstream ss(time);
|
std::stringstream ss(time);
|
||||||
ss >> std::get_time(&tm, "%Y-%m-%dT%T"); // Assume time is UTC.
|
ss >> std::get_time(&tm, "%Y-%m-%dT%T");
|
||||||
return strtime(system_clock::from_time_t(timegm(&tm)));
|
std::time_t time_tmp = timegm(&tm);
|
||||||
|
|
||||||
|
constexpr size_t zone_start = 19;
|
||||||
|
if (time[zone_start] == '+')
|
||||||
|
{
|
||||||
|
string zone = time.substr(zone_start + 1);
|
||||||
|
time_tmp -= std::stol(zone.substr(0, 2)) * 60 * 60;
|
||||||
|
time_tmp -= std::stol(zone.substr(3)) * 60;
|
||||||
|
}
|
||||||
|
else if (time[zone_start] == '+')
|
||||||
|
{
|
||||||
|
string zone = time.substr(zone_start + 1);
|
||||||
|
time_tmp += std::stol(zone.substr(0, 2)) * 60 * 60;
|
||||||
|
time_tmp += std::stol(zone.substr(3)) * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strtime(system_clock::from_time_t(time_tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#ifndef VERSION_HPP
|
#ifndef VERSION_HPP
|
||||||
#define VERSION_HPP
|
#define VERSION_HPP
|
||||||
|
|
||||||
namespace global
|
namespace gitea2rss
|
||||||
{
|
{
|
||||||
static constexpr char version[] = "@PROJECT_VERSION@";
|
|
||||||
}
|
static constexpr char version[] = "@PROJECT_VERSION@";
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
||||||
#endif // VERSION_HPP
|
#endif // VERSION_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* This file is part of gitea2rss.
|
/* This file is part of gitea2rss.
|
||||||
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -14,9 +14,14 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "version.hpp"
|
|
||||||
#include "gitea2rss.hpp"
|
#include "gitea2rss.hpp"
|
||||||
|
#include "version.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
namespace gitea2rss
|
||||||
|
{
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
|
||||||
|
@ -39,3 +44,40 @@ void write_line(const uint8_t spaces, const string &tag, const string &value)
|
||||||
cout << '<' << tag << '>' << value << "</" << endtag << ">\n";
|
cout << '<' << tag << '>' << value << "</" << endtag << ">\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write_preamble(const string &url, const string &type)
|
||||||
|
{
|
||||||
|
const string request_uri{get_env_var("REQUEST_URI")};
|
||||||
|
const string server_name{get_env_var("SERVER_NAME")};
|
||||||
|
const string https{get_env_var("HTTPS")};
|
||||||
|
string selfurl;
|
||||||
|
|
||||||
|
if (!request_uri.empty() && !server_name.empty())
|
||||||
|
{
|
||||||
|
if (https == "on")
|
||||||
|
{
|
||||||
|
selfurl = "https://";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selfurl = "http://";
|
||||||
|
}
|
||||||
|
selfurl += string(server_name) + request_uri;
|
||||||
|
selfurl = std::regex_replace(selfurl, std::regex("&"), "&");
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n"
|
||||||
|
" <channel>\n";
|
||||||
|
if (cgi)
|
||||||
|
{
|
||||||
|
cout << " <atom:link href=\"" + selfurl
|
||||||
|
+ "\" rel=\"self\" type=\"application/rss+xml\"/>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
write_line(4, "title", get_project(url) + " " + type);
|
||||||
|
write_line(4, "link", url);
|
||||||
|
write_line(4, "description", "List of " + type + " of " + get_repo(url));
|
||||||
|
write_line(4, "generator", string("gitea2rss ") + version);
|
||||||
|
write_line(4, "lastBuildDate", strtime(system_clock::now()));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gitea2rss
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
|
file(GLOB sources_testlib ../src/*.cpp)
|
||||||
|
add_library(${PROJECT_NAME}_testlib SHARED ${sources_testlib})
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME}_testlib
|
||||||
|
PUBLIC
|
||||||
|
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>"
|
||||||
|
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>")
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}_testlib
|
||||||
|
PRIVATE CURL::libcurl PkgConfig::jsoncpp)
|
||||||
|
|
||||||
|
file(GLOB sources_tests test_*.cpp)
|
||||||
|
|
||||||
|
find_package(Catch2 CONFIG)
|
||||||
|
if(Catch2_FOUND) # Catch 2.x
|
||||||
|
include(Catch)
|
||||||
|
add_executable(all_tests main.cpp ${sources_tests})
|
||||||
|
target_link_libraries(all_tests
|
||||||
|
PRIVATE Catch2::Catch2 ${PROJECT_NAME}_testlib)
|
||||||
|
target_include_directories(all_tests PRIVATE "/usr/include/catch2")
|
||||||
|
catch_discover_tests(all_tests EXTRA_ARGS "${EXTRA_TEST_ARGS}")
|
||||||
|
else() # Catch 1.x
|
||||||
|
if(EXISTS "/usr/include/catch.hpp")
|
||||||
|
message(STATUS "Catch 1.x found.")
|
||||||
|
foreach(src ${sources_tests})
|
||||||
|
get_filename_component(bin ${src} NAME_WE)
|
||||||
|
add_executable(${bin} main.cpp ${src})
|
||||||
|
target_link_libraries(${bin}
|
||||||
|
PRIVATE ${PROJECT_NAME}_testlib)
|
||||||
|
add_test(${bin} ${bin} "${EXTRA_TEST_ARGS}")
|
||||||
|
endforeach()
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Neither Catch 2.x nor Catch 1.x could be found.")
|
||||||
|
endif()
|
||||||
|
endif()
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
|
#include <catch.hpp>
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019-2021 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using namespace gitea2rss;
|
||||||
|
|
||||||
|
SCENARIO("escape_some_html() works as expected", "[strings]")
|
||||||
|
{
|
||||||
|
WHEN("String with escape-able characters")
|
||||||
|
{
|
||||||
|
const string escaped = escape_some_html("<p><small>.</small></p>");
|
||||||
|
|
||||||
|
THEN("The HTML is escaped")
|
||||||
|
{
|
||||||
|
REQUIRE(escaped
|
||||||
|
== "<p><small>.</"
|
||||||
|
"small></p>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using namespace gitea2rss;
|
||||||
|
|
||||||
|
SCENARIO("get_baseurl() works as expected", "[strings]")
|
||||||
|
{
|
||||||
|
WHEN("HTTPS URL")
|
||||||
|
{
|
||||||
|
const string baseurl =
|
||||||
|
get_baseurl("https://git.example.com/user/project");
|
||||||
|
|
||||||
|
THEN("The base URL is correctly returned")
|
||||||
|
{
|
||||||
|
REQUIRE(baseurl == "https://git.example.com");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WHEN("HTTP URL")
|
||||||
|
{
|
||||||
|
const string baseurl =
|
||||||
|
get_baseurl("http://git.example.com/user/project");
|
||||||
|
|
||||||
|
THEN("The base URL is correctly returned")
|
||||||
|
{
|
||||||
|
REQUIRE(baseurl == "http://git.example.com");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using namespace gitea2rss;
|
||||||
|
|
||||||
|
SCENARIO("get_domain() works as expected", "[strings]")
|
||||||
|
{
|
||||||
|
WHEN("HTTPS URL is valid")
|
||||||
|
{
|
||||||
|
const string domain =
|
||||||
|
get_domain("https://git.example.com/user/project");
|
||||||
|
|
||||||
|
THEN("The domain is correctly returned")
|
||||||
|
{
|
||||||
|
REQUIRE(domain == "git.example.com");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using namespace gitea2rss;
|
||||||
|
|
||||||
|
SCENARIO("get_http() works as expected", "[http]")
|
||||||
|
{
|
||||||
|
WHEN("URL is valid")
|
||||||
|
{
|
||||||
|
const string answer = get_http("https://ip.tastytea.de/");
|
||||||
|
|
||||||
|
THEN("Answer is not empty")
|
||||||
|
{
|
||||||
|
REQUIRE(!answer.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WHEN("URL is invalid")
|
||||||
|
{
|
||||||
|
const string answer = get_http("https://url.invalid/");
|
||||||
|
|
||||||
|
THEN("Answer is empty")
|
||||||
|
{
|
||||||
|
REQUIRE(answer.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using namespace gitea2rss;
|
||||||
|
|
||||||
|
SCENARIO("get_project() works as expected", "[strings]")
|
||||||
|
{
|
||||||
|
WHEN("HTTPS URL is valid")
|
||||||
|
{
|
||||||
|
const string project =
|
||||||
|
get_project("https://git.example.com/user/project");
|
||||||
|
|
||||||
|
THEN("The project is correctly returned")
|
||||||
|
{
|
||||||
|
REQUIRE(project == "project");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using namespace gitea2rss;
|
||||||
|
|
||||||
|
SCENARIO("get_repo() works as expected", "[strings]")
|
||||||
|
{
|
||||||
|
WHEN("HTTPS URL is valid")
|
||||||
|
{
|
||||||
|
const string repo = get_repo("https://git.example.com/user/project");
|
||||||
|
|
||||||
|
THEN("The repo is correctly returned")
|
||||||
|
{
|
||||||
|
REQUIRE(repo == "user/project");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* This file is part of gitea2rss.
|
||||||
|
* Copyright © 2019, 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gitea2rss.hpp"
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using namespace gitea2rss;
|
||||||
|
|
||||||
|
SCENARIO("strtime() works as expected", "[time]")
|
||||||
|
{
|
||||||
|
GIVEN("Time as time_point")
|
||||||
|
{
|
||||||
|
std::chrono::system_clock::time_point tp;
|
||||||
|
const string time = strtime(tp);
|
||||||
|
|
||||||
|
THEN("The time is returned in the correct format")
|
||||||
|
{
|
||||||
|
REQUIRE(time == "Thu, 01 Jan 1970 00:00:00 +0000");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GIVEN("Time as ISO 8601 string")
|
||||||
|
{
|
||||||
|
const string time = strtime("1970-01-01T00:00:00+0000");
|
||||||
|
|
||||||
|
THEN("The time is returned in the correct format")
|
||||||
|
{
|
||||||
|
REQUIRE(time == "Thu, 01 Jan 1970 00:00:00 +0000");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue