import jabref

This commit is contained in:
Artem Semenovykh 2024-11-16 11:43:42 +01:00
parent e84d1ad460
commit 415abbc47b
3388 changed files with 385988 additions and 95 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
.DS_Store
.DS_Store
/classes

4
.idea/sq_2024.iml generated
View File

@ -2,7 +2,9 @@
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/classes" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>

View File

@ -1,93 +0,0 @@
# Software Quality
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.uni-marburg.de/tadjikys/software-quality.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.uni-marburg.de/tadjikys/software-quality/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

View File

@ -0,0 +1,39 @@
{
"name": "Java",
"image": "mcr.microsoft.com/devcontainers/base:debian",
"customizations": {
"vscode": {
"extensions": [
"vscjava.vscode-java-pack",
"vscjava.vscode-gradle",
"shengchen.vscode-checkstyle",
"DavidAnson.vscode-markdownlint"
]
}
},
// Source code generation needs to be done before hand-over to VS Code.
// Otherwise, the Java extension will go mad.
"onCreateCommand": "./gradlew testClasses --console=plain --no-daemon",
// Forward the vncPort and noVNC port.
// They are provided by desktop-lite:
// https://github.com/devcontainers/features/tree/main/src/desktop-lite#options
"forwardPorts": [5901, 6080],
// Need to connect as root otherwise we run into issues with gradle.
// default option is "vscode". More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "root",
"features": {
// Adds a lightweight desktop that can be accessed using a VNC viewer or the web
"ghcr.io/devcontainers/features/desktop-lite:1": {},
// Install java.
// See https://github.com/devcontainers/features/tree/main/src/java#options for details.
"ghcr.io/devcontainers/features/java:1": {
"version": "23.0.1-tem",
"installGradle": false,
"jdkDistro": "Temurin"
}
}
}

13
jabref/.editorconfig Normal file
View File

@ -0,0 +1,13 @@
root = true
[*]
charset = utf-8
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{fxml,java,properties,sh}]
end_of_line = lf
[*.md]
trim_trailing_whitespace = false

View File

@ -0,0 +1,28 @@
# Automatic code reformatting
c5bcad738fe6e8dfcb62442a426c2778241515a1
# net.sf.jabref -> org.jabref
b2ad6eb279f5def38fa21be12cb5dd4545c1ba1a
dd385f4ad6dc9251bfdb1c0b75ded402f680b32a
a6e80311c6376c973b5860658f6e4ace7a3fd1f4
648a4703e80ac0dbe1ff044f354bc0e332e4064d
ac08c6a2c55e1600bf5072c0ea2e6aac920b915d
ec863166cf4f38a1a6bcc80a607fd33299b815aa
8c61577e4377746fc064db2a136bb68968cd4055
0ef3228f0c1334ff203d4ea5e698e3ad88cb7089
ce939b4ef19ca856e7ecac08275cf1ca764207b6
7f1a8069d03737c202bcb7ce352b3755c6a36f5f
dbd0cfbc8177ada414e89da038cd014657d48ed3
bc7ea00c8cc3ec9ec8b1a799b0dd96513bc51404
9a5cff44aa1e0d4b737296a30b97f7f384c8b885
bf81b595a77f0f7f254872be6f05a063c44528d8
277b40c9e79e0158d272de33e24fa7fc06af91bf
662dd326d212ecfd336a00214e969145ec501c5a
33f040cfbb16111ada117f858e98d606a6bee4fd
29fe730f64eeb62ff9de10fcb460a63297e24be6
# This commit should not exist
185d7345946c29a2a4e2726c912be0c4db4810b9
# Resulted in this problematic merge commits
7e1645978b3028df5e65af19f0f819ddfd0f24aa
a31f396765492ac12eaab228e33eb9d22487403b

14
jabref/.gitattributes vendored Normal file
View File

@ -0,0 +1,14 @@
# unix line endings at unix files
gradlew text eol=lf
*.sh text eol=lf
# windows line endings at windows files
*.bat text eol=crlf
# ensure that line endings of *.bib, *.fxml, *.java, *.properties are normalized to LF
*.bib text eol=lf
*.fxml text eol=lf
*.java text eol=lf
*.properties text eol=lf
CHANGELOG.md merge=union

12
jabref/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: JabRef
patreon: # Patreon user account
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: JabRef
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: https://github.com/JabRef/jabref/wiki/Donations # Replace with a single custom sponsorship URL

View File

@ -0,0 +1,81 @@
name: "Bug report"
description: Create a report to help us improve
body:
- type: markdown
attributes:
value:
"Please use the GitHub issue tracker only for bug reports.
Feature requests, questions and general feedback is now handled at http://discourse.jabref.org.
Please make sure you looked into our [list of existing issues](https://github.com/jabref/JabRef/issues) before creating a new issue to avoid duplicates!"
- type: dropdown
attributes:
label: JabRef version
options:
- "5.15 (latest release)"
- Latest development branch build (please note build date below)
- Other (please describe below)
description: The version as shown in the about dialog.
validations:
required: true
- type: dropdown
attributes:
label: Operating system
multiple: false
options:
- Windows
- GNU / Linux
- macOS
- Other (please describe below)
validations:
required: true
- type: input
attributes:
label: Details on version and operating system
description: OS Version, distribution, desktop environment, older JabRef version etc.
placeholder: Ubuntu 21.04 with Plasma 5.22 / Windows 10 21H1 / macOS 10.14
validations:
required: false
- type: checkboxes
attributes:
label: Checked with the latest development build (copy version output from About dialog)
description: |
Please always test if the bug is still reproducible in the latest development version. We are constantly improving JabRef and some bugs may already be fixed. If you already use a development version, ensure that you use the latest one.
You can download the latest development build at: https://builds.jabref.org/main/ . **Please make a backup of your library before you try out this version.**
options:
- label: I made a backup of my libraries before testing the latest development version.
required: true
- label: I have tested the latest development version and the problem persists
required: true
- type: textarea
attributes:
label: Steps to reproduce the behaviour
description: A clear and concise description of what the bug is and how to make it occur.
value: |
1. ...
2. ...
3. ...
validations:
required: true
- type: textarea
attributes:
label: Appendix
description: "If applicable: An excerpt of the bibliography file, a screenshot, an excerpt of log (available in the error console) etc."
value: |
...
<details>
<summary>Log File</summary>
```
Paste an excerpt of your log file here
```
</details>
validations:
required: false

View File

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Help
url: https://discourse.jabref.org/c/help/
about: Questions and requests for help are handled at https://discourse.jabref.org
- name: Feature requests
url: https://discourse.jabref.org/c/features/
about: If you are missing an important feature? Let us know!

View File

@ -0,0 +1,23 @@
---
name: Suggestion for improvement
about: Suggest an enhancement
title: ''
labels: ''
assignees: ''
---
<!--
Please use the GitHub issue tracker only for bug reports and smaller suggestions for improvements.
Requests for completely new features, questions and general feedback is now handled at http://discourse.jabref.org.
Thanks!
-->
**Is your suggestion for improvement related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.

17
jabref/.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,17 @@
Describe the changes you have made here: what, why, ...
Link the issue that will be closed, e.g., "Closes #333". If your PR closes a koppor issue, link it using its URL, e.g., "Closes https://github.com/koppor/jabref/issues/47".
### Mandatory checks
<!--
- Go through the list below. Please don't remove any items.
- [x] done; [ ] not done / not applicable
-->
- [x] I own the copyright of the code submitted and I licence it under the [MIT license](https://github.com/JabRef/jabref/blob/main/LICENSE)
- [ ] Change in `CHANGELOG.md` described in a way that is understandable for the average user (if change is visible to the user)
- [ ] Tests created for changes (if applicable)
- [ ] Manually tested changed features in running JabRef (always required)
- [ ] Screenshots added in PR description (for UI changes)
- [ ] [Checked developer's documentation](https://devdocs.jabref.org/): Is the information available and up to date? If not, I outlined it in this pull request.
- [ ] [Checked documentation](https://docs.jabref.org/): Is the information available and up to date? If not, I created an issue at <https://github.com/JabRef/user-documentation/issues> or, even better, I submitted a pull request to the documentation repository.

31
jabref/.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,31 @@
version: 2
updates:
- package-ecosystem: gradle
directory: "/"
schedule:
interval: weekly
labels:
- "dependencies"
ignore:
- dependency-name: com.microsoft.azure:applicationinsights-core
versions:
- ">= 2.5.a" # Blocked by https://github.com/microsoft/ApplicationInsights-Java/issues/1155
- dependency-name: com.microsoft.azure:applicationinsights-logging-log4j2
versions:
- ">= 2.5.a" # Blocked by https://github.com/microsoft/ApplicationInsights-Java/issues/1155
- package-ecosystem: gradle
directory: "buildSrc/"
schedule:
interval: weekly
labels:
- "dependencies"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: weekly
labels:
- "dependencies"
- package-ecosystem: "gitsubmodule"
directory: "/"
schedule:
interval: weekly

37
jabref/.github/ghprcomment.yml vendored Normal file
View File

@ -0,0 +1,37 @@
- jobName: Checkstyle
message: |
Your code currently does not meet [JabRef's code guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html).
We use [Checkstyle](https://checkstyle.sourceforge.io/) to identify issues.
Please carefully follow [the setup guide for the codestyle](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html).
Afterwards, please [run checkstyle locally](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html#run-checkstyle) and fix the issues.
- jobName: OpenRewrite
message: |
Your code currently does not meet JabRef's code guidelines.
We use [OpenRewrite](https://docs.openrewrite.org/) to ensure "modern" Java coding practices.
The issues found can be **automatically fixed**.
Please execute the gradle task *`rewriteRun`*, check the results, commit, and push.
You can check the detailed error output by navigating to your pull request, selecting the tab "Checks", section "Tests" (on the left), subsection "OpenRewrite".
- jobName: Modernizer
message: |
Your code currently does not meet JabRef's code guidelines.
We use [Gradle Modernizer Plugin](https://github.com/andygoossens/gradle-modernizer-plugin#gradle-modernizer-plugin) to ensure "modern" Java coding practices.
Please fix the detected errors, commit, and push.
You can check the detailed error output by navigating to your pull request, selecting the tab "Checks", section "Tests" (on the left), subsection "Modernizer".
- jobName: Markdown
message: |
You modified Markdown (`*.md`) files and did not meet JabRef's rules for consistently formatted Markdown files.
To ensure consistent styling, we have [markdown-lint](https://github.com/DavidAnson/markdownlint) in place.
[Markdown lint's rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#rules) help to keep our Markdown files consistent within this repository and consistent with the Markdown files outside here.
You can check the detailed error output by navigating to your pull request, selecting the tab "Checks", section "Tests" (on the left), subsection "Markdown".
- jobName: CHANGELOG.md
message: |
While the PR was in progress, a new version of JabRef has been released.
You have to merge `upstream/main` and move your entry in `CHANGELOG.md` up to the section `## [Unreleased]`.
- jobName: 'Unit tests'
message: |
JUnit tests are failing. In the area "Some checks were not successful", locate "Tests / Unit tests (pull_request)" and click on "Details". This brings you to the test output.
You can then run these tests in IntelliJ to reproduce the failing tests locally. We offer a quick test running howto in the section [Final build system checks](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-12-build.html#final-build-system-checks) in our setup guide.

View File

@ -0,0 +1,57 @@
name: Assign Issue
on:
schedule:
- cron: 4 12 * * *
issue_comment:
types: [created]
workflow_dispatch:
jobs:
assign:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Assign the user or unassign stale assignments
id: assign
uses: takanome-dev/assign-issue-action@beta
with:
github_token: '${{ secrets.GITHUB_TOKEN }}'
days_until_unassign: 30
maintainers: koppor, Siedlerchr, ThiloteE, calixtus, HoussemNasri
assigned_comment: |
👋 Hey @{{ handle }}, thank you for your interest in this issue! 🎉
We're excited to have you on board. Start by exploring our [Contributing](https://github.com/JabRef/jabref/blob/main/CONTRIBUTING.md) guidelines, and don't forget to check out our [workspace setup guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace) to get started smoothly.
In case you encounter failing tests during development, please check our [developer FAQs](https://devdocs.jabref.org/code-howtos/faq.html)!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on [JabRef's Gitter chat](https://gitter.im/JabRef/jabref). And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
Happy coding! 🚀
⏳ Please note, you will be automatically unassigned if the issue isn't closed within **{{ total_days }} days** (by **{{ unassigned_date }}**). A maintainer can also add the "**{{ pin_label }}**"" label to prevent automatic unassignment.
- name: Move Issue to "Assigned" Column in "Candidates for University Projects"
if: steps.assign.outputs.assigned == 'yes'
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Assigned" Column in "Good First Issues"
if: steps.assign.outputs.assigned == 'yes'
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true

34
jabref/.github/workflows/automerge.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: Auto Merge
on: [pull_request_target, workflow_dispatch]
permissions:
contents: write
pull-requests: write
jobs:
automerge:
runs-on: ubuntu-latest
# Run only if PR is inside JabRef's main repository and created by dependabot or by an update workflow
if: >
(github.repository == 'JabRef/jabref') &&
(github.event.pull_request.head.repo.full_name == 'JabRef/jabref') &&
(
(github.actor == 'dependabot[bot]') ||
(
startsWith(github.event.pull_request.title, '[Bot] ') ||
startsWith(github.event.pull_request.title, 'Bump ') ||
startsWith(github.event.pull_request.title, 'New Crowdin updates') ||
startsWith(github.event.pull_request.title, 'Update Gradle Wrapper from')
)
)
steps:
- name: Approve PR
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GH_TOKEN_JABREF_MACHINE_PR_APPROVE}}
- name: Merge PR
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GH_TOKEN_UPDATE_GRADLE_WRAPPER}}

View File

@ -0,0 +1,38 @@
name: Check external href links in the documentation
on:
push:
paths:
- '.github/workflows/check-links.yml'
- '.lycheeignore'
- 'lychee.toml'
- '**/*.md'
schedule:
# Run on the first of each month at 9:00 AM (See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07)
- cron: "0 9 1 * *"
workflow_dispatch:
concurrency:
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
lychee:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
show-progress: 'false'
- name: Restore lychee cache
uses: actions/cache@v4
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}
restore-keys: cache-lychee-
- name: Link Checker
id: lychee
uses: lycheeverse/lychee-action@v2.1.0
with:
fail: true
args: --accept '200,201,202,203,204,403,429,500' --max-concurrency 1 --cache --no-progress --exclude-all-private './**/*.md'

45
jabref/.github/workflows/cleanup-pr.yml vendored Normal file
View File

@ -0,0 +1,45 @@
name: Cleanup after PR
on:
pull_request:
types: [closed]
jobs:
cleanup:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- name: Cancel deployment run
uses: styfle/cancel-workflow-action@0.12.1
with:
ignore_sha: true
workflow_id: 9813 # workflow "Deployment"
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Delete folder on builds.jabref.org
if: steps.checksecrets.outputs.secretspresent == 'YES'
uses: appleboy/ssh-action@v1.1.0
with:
script: rm -rf /var/www/builds.jabref.org/www/pull/${{ github.event.pull_request.number }} || true
host: build-upload.jabref.org
port: 9922
username: jrrsync
key: ${{ secrets.buildJabRefPrivateKey }}
- name: Update PR comment
if: steps.checksecrets.outputs.secretspresent == 'YES'
uses: thollander/actions-comment-pull-request@v3
with:
comment-tag: download-link
message: The build for this PR is no longer available. Please visit <https://builds.jabref.org/main/> for the latest build.
mode: upsert

View File

@ -0,0 +1,272 @@
name: Deployment (macOS/ARM64)
on:
push:
branches:
- main
- main-release
paths-ignore:
- 'docs/**'
- 'src/test/**'
- 'README.md'
tags:
- '*'
pull_request:
merge_group:
workflow_dispatch:
inputs:
notarization:
type: boolean
required: false
default: false
env:
SpringerNatureAPIKey: ${{ secrets.SpringerNatureAPIKey }}
AstrophysicsDataSystemAPIKey: ${{ secrets.AstrophysicsDataSystemAPIKey }}
IEEEAPIKey: ${{ secrets.IEEEAPIKey }}
BiodiversityHeritageApiKey: ${{ secrets.BiodiversityHeritageApiKey}}
OSXCERT: ${{ secrets.OSX_SIGNING_CERT }}
GRADLE_OPTS: -Xmx4g -Dorg.gradle.daemon=false -Dorg.gradle.vfs.watch=false
JAVA_OPTS: -Xmx4g
concurrency:
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
build:
if: github.repository_owner == 'JabRef'
strategy:
fail-fast: false
matrix:
include:
- os: macos-14
displayName: macOS (ARM64)
suffix: '_arm64'
runs-on: ${{ matrix.os }}
outputs:
major: ${{ steps.gitversion.outputs.Major }}
minor: ${{ steps.gitversion.outputs.Minor }}
branchname: ${{ steps.gitversion.outputs.branchName }}
name: Create installer and portable version for ${{ matrix.displayName }}
steps:
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Fetch all history for all tags and branches
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'true'
show-progress: 'false'
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v3.0.0
with:
versionSpec: "5.x"
- name: Run GitVersion
id: gitversion
uses: gittools/actions/gitversion/execute@v3.0.0
- name: Setup JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Clean up keychain
run: |
security delete-keychain signing_temp.keychain ${{runner.temp}}/keychain/notarization.keychain || true
- name: Setup OSX key chain on macOS-arm
if: (steps.checksecrets.outputs.secretspresent == 'YES')
uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d
with:
p12-file-base64: ${{ secrets.OSX_SIGNING_CERT }}
p12-password: ${{ secrets.OSX_CERT_PWD }}
keychain-password: jabref
- name: Setup OSX key chain on OSX for app id cert
if: (steps.checksecrets.outputs.secretspresent == 'YES')
uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d
with:
p12-file-base64: ${{ secrets.OSX_SIGNING_CERT_APPLICATION }}
p12-password: ${{ secrets.OSX_CERT_PWD }}
create-keychain: false
keychain-password: jabref
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Prepare merged jars and modules dir (macOS)
run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" prepareModulesDir
- name: Build dmg (macOS)
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
jpackage \
--module org.jabref/org.jabref.Launcher \
--module-path ${{env.JAVA_HOME}}/jmods/:build/jlinkbase/jlinkjars \
--add-modules org.jabref,org.jabref.merged.module \
--add-modules jdk.incubator.vector \
--dest build/distribution \
--app-content buildres/mac/jabrefHost.py \
--app-content buildres/mac/native-messaging-host \
--name JabRef \
--app-version ${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }} \
--verbose \
--mac-sign \
--vendor "JabRef e.V." \
--mac-package-identifier JabRef \
--mac-package-name JabRef \
--type dmg --mac-signing-key-user-name "JabRef e.V. (6792V39SK3)" \
--mac-package-signing-prefix org.jabref \
--mac-entitlements buildres/mac/jabref.entitlements \
--icon src/main/resources/icons/jabref.icns \
--resource-dir buildres/mac \
--file-associations buildres/mac/bibtexAssociations.properties \
--jlink-options --bind-services \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control.skin=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections.transformation=org.jabref \
--java-options --add-modules=jdk.incubator.vector
- name: Build pkg (macOS)
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
jpackage \
--module org.jabref/org.jabref.Launcher \
--module-path ${{env.JAVA_HOME}}/jmods/:build/jlinkbase/jlinkjars \
--add-modules org.jabref,org.jabref.merged.module \
--add-modules jdk.incubator.vector \
--dest build/distribution \
--app-content buildres/mac/jabrefHost.py \
--app-content buildres/mac/native-messaging-host \
--name JabRef \
--app-version ${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }} \
--verbose \
--mac-sign \
--vendor "JabRef e.V." \
--mac-package-identifier JabRef \
--mac-package-name JabRef \
--type pkg --mac-signing-key-user-name "JabRef e.V. (6792V39SK3)" \
--mac-package-signing-prefix org.jabref \
--mac-entitlements buildres/mac/jabref.entitlements \
--icon src/main/resources/icons/jabref.icns \
--resource-dir buildres/mac \
--file-associations buildres/mac/bibtexAssociations.properties \
--jlink-options --bind-services \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections.transformation=org.jabref \
--java-options --add-modules=jdk.incubator.vector
- name: Rename files with arm64 suffix as well
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
mv build/distribution/JabRef-${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}.dmg build/distribution/JabRef-${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}-arm64.dmg
mv build/distribution/JabRef-${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}.pkg build/distribution/JabRef-${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}-arm64.pkg
- name: Setup rsync (macOS)
if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'macos-14') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true))) }}
run: brew install rsync
- name: Setup SSH key
if: ${{ (steps.checksecrets.outputs.secretspresent == 'YES') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && ((matrix.os != 'macos-14') || !((startsWith(github.ref, 'refs/tags/') || (inputs.notarization == true)))) }}
run: |
echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey
chmod 600 sshkey
- name: Upload to builds.jabref.org (linux, macOS)
# macOS: Negated condition of "Upload to GitHub workflow artifacts store (macOS)"
# Reason: We either upload the non-notarized files - or notarize the files later (and upload these later)
# needs to be on one line; multi line does not work
if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'ubuntu-latest') || ((matrix.os == 'macos-14') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)))) }}
shell: bash
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
- name: Upload to GitHub workflow artifacts store (macOS)
if: (matrix.os == 'macos-14') && (steps.checksecrets.outputs.secretspresent == 'YES') && (startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)
uses: actions/upload-artifact@v4
with:
# tbn = to-be-notarized
name: JabRef-macOS-arm-tbn
path: build/distribution
compression-level: 0 # no compression
- name: Upload to GitHub workflow artifacts store
if: (steps.checksecrets.outputs.secretspresent != 'YES')
uses: actions/upload-artifact@v4
with:
# tbn = to-be-notarized
name: JabRef-${{ matrix.os }}
path: build/distribution
compression-level: 0 # no compression
notarize: # outsourced in a separate job to be able to rerun if this fails for timeouts
name: macOS notarization-arm
runs-on: macos-14
needs: [build]
if: ${{ startsWith(github.ref, 'refs/tags/') || inputs.notarization == true }}
steps:
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Download from GitHub workflow artifacts store (macOS)
if: (steps.checksecrets.outputs.secretspresent == 'YES')
uses: actions/download-artifact@master
with:
name: JabRef-macOS-arm-tbn
path: build/distribution/
- name: Notarize dmg
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
xcrun notarytool store-credentials "notarytool-profile" --apple-id "vorstand@jabref.org" --team-id "6792V39SK3" --password "${{ secrets.OSX_NOTARIZATION_APP_PWD }}"
xcrun notarytool submit build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}-arm64.dmg --keychain-profile "notarytool-profile" --wait
xcrun stapler staple build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}-arm64.dmg
- name: Notarize pkg
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
xcrun notarytool store-credentials "notarytool-profile" --apple-id "vorstand@jabref.org" --team-id "6792V39SK3" --password "${{ secrets.OSX_NOTARIZATION_APP_PWD }}"
xcrun notarytool submit build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}-arm64.pkg --keychain-profile "notarytool-profile" --wait
xcrun stapler staple build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}-arm64.pkg
- name: Upload to builds.jabref.org
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey
chmod 600 sshkey
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ needs.build.outputs.branchname }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ needs.build.outputs.branchname }}/

View File

@ -0,0 +1,282 @@
# This workflow is a clone of "deployment.yml"
# The difference is that this workflow uses JDK early access builds (jdk-ea) to check the build of JabRef
# We separated this from the main workflow as we do not want to check on each PR if the JDK build, but only on main
name: Deployment (JDK early access builds)
on:
schedule:
- cron: "0 18 * * 1"
pull_request:
paths:
- .github/workflows/deployment-jdk-ea.yml
- build.gradle
workflow_dispatch:
inputs:
notarization:
type: boolean
required: false
default: false
env:
SpringerNatureAPIKey: ${{ secrets.SpringerNatureAPIKey }}
AstrophysicsDataSystemAPIKey: ${{ secrets.AstrophysicsDataSystemAPIKey }}
IEEEAPIKey: ${{ secrets.IEEEAPIKey }}
BiodiversityHeritageApiKey: ${{ secrets.BiodiversityHeritageApiKey}}
OSXCERT: ${{ secrets.OSX_SIGNING_CERT }}
GRADLE_OPTS: -Xmx4g -Dorg.gradle.vfs.watch=false
JAVA_OPTS: -Xmx4g
concurrency:
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
build:
if: github.repository_owner == 'JabRef'
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, buildjet-8vcpu-ubuntu-2204-arm]
jdk: [23]
javafx: [24]
include:
- os: ubuntu-latest
displayName: linux
archivePortable: tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux.tar.gz && rm -R build/distribution/JabRef
- os: windows-latest
displayName: windows
archivePortable: 7z a -r build/distribution/JabRef-portable_windows.zip ./build/distribution/JabRef && rm -R build/distribution/JabRef
- os: buildjet-8vcpu-ubuntu-2204-arm
displayName: "linux-arm"
archivePortable: "tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux-arm64.tar.gz && rm -R build/distribution/JabRef"
- os: macos-latest
displayName: macOS
archivePortable: "brew install pigz && tar -c -C build/distribution JabRef.app | pigz --rsyncable > build/distribution/JabRef-portable_macos.tar.gz && rm -R build/distribution/JabRef.app"
runs-on: ${{ matrix.os }}
outputs:
major: ${{ steps.gitversion.outputs.Major }}
minor: ${{ steps.gitversion.outputs.Minor }}
branchname: ${{ steps.gitversion.outputs.branchName }}
name: "JDK ${{ matrix.jdk }}: ${{ matrix.displayName }} JavaFX ${{ matrix.javafx }}"
steps:
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Fetch all history for all tags and branches
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'true'
show-progress: 'false'
- name: Install pigz and cache (linux)
if: (matrix.os == 'ubuntu-latest') || (matrix.os == 'buildjet-8vcpu-ubuntu-2204-arm')
uses: awalsh128/cache-apt-pkgs-action@master
with:
packages: pigz
version: 1.0
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v3.0.0
with:
versionSpec: "5.x"
- name: Run GitVersion
id: gitversion
uses: gittools/actions/gitversion/execute@v3.0.0
# JDK
- name: 'Set up JDK ${{ matrix.jdk }}'
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.jdk }}
distribution: 'temurin'
- name: 'Set JDK${{ matrix.jdk }} env var'
shell: bash
run: echo "JDK${{ matrix.jdk }}=$JAVA_HOME" >> $GITHUB_ENV
- name: 'Set JDK${{ matrix.jdk }} in toolchain (linux, Windows)'
if: (matrix.os != 'macos-latest')
shell: bash
run: |
sed -i 's/JavaLanguageVersion.of(.*)/JavaLanguageVersion.of(${{ matrix.jdk }})/' build.gradle
sed -i 's/JavaVersion.VERSION_(.*)/JavaVersion.VERSION_(${{ matrix.jdk }})/' build.gradle
- name: 'Set JDK${{ matrix.jdk }} in toolchain (macOS)'
if: (matrix.os == 'macos-latest')
shell: bash
run: |
sed -i'.bak' 's/JavaLanguageVersion.of(.*)/JavaLanguageVersion.of(${{ matrix.jdk }})/' build.gradle
sed -i'.bak' 's/JavaVersion.VERSION_(.*)/JavaVersion.VERSION_(${{ matrix.jdk }})/' build.gradle
# JavaFX
- name: Download and extract JavaFX ${{ matrix.javafx }}
if: (matrix.os != 'buildjet-8vcpu-ubuntu-2204-arm')
shell: bash
run: |
cd javafx
curl --no-progress-meter https://jdk.java.net/javafx${{ matrix.javafx }}/ > javafx.html
case "${{ matrix.os }}" in
"ubuntu-latest")
OS="linux"
EXTRACT="tar xzf *.tar.gz"
EXT="tar.gz"
;;
"buildjet-8vcpu-ubuntu-2204-arm")
OS="linux"
EXTRACT="tar xzf *.tar.gz"
EXT="tar.gz"
echo "There are no ARM EA builds"
exit 0
;;
"windows-latest")
OS="windows"
EXTRACT="unzip -qq *.zip"
EXT="zip"
;;
"macos-latest")
OS="macos"
EXTRACT="tar xzf *.tar.gz"
EXT="tar.gz"
;;
*)
echo "Unsupported OS"
exit 1
;;
esac
echo "OS set to $OS"
URL_SDK=$(grep -o "https://download.java.net/java/.*/javafx.*${OS}-x64_bin-sdk.${EXT}" javafx.html | head -n 1)
echo "Downloading $URL_SDK..."
curl -OJ --no-progress-meter $URL_SDK
$EXTRACT
rm *.$EXT
URL_JMODS=$(grep -o "https://download.java.net/java/.*/javafx.*${OS}-x64_bin-jmods.${EXT}" javafx.html | head -n 1)
echo "Downloading $URL_JMODS..."
curl -OJ --no-progress-meter $URL_JMODS
$EXTRACT
rm *.$EXT
- name: 'Set JavaFX ${{ matrix.javafx }} (linux, Windows)'
if: (matrix.os != 'macos-latest') && (matrix.os != 'buildjet-8vcpu-ubuntu-2204-arm')
run: |
sed -i '/javafx {/{n;s#version = ".*"#sdk = "javafx/javafx-sdk-${{ matrix.javafx }}"#}' build.gradle
sed -i "s#jlink {#jlink { addExtraModulePath 'javafx/javafx-jmods-${{ matrix.javafx }}'#" build.gradle
cat build.gradle
- name: 'Set JavaFX ${{ matrix.javafx }} (macOS)'
if: (matrix.os == 'macos-latest') && (matrix.os != 'buildjet-8vcpu-ubuntu-2204-arm')
run: |
sed -i '.bak' -e '/javafx {/{n' -e 's#version = ".*"#sdk = "javafx/javafx-sdk-${{ matrix.javafx }}"#;}' build.gradle
sed -i '.bak' -e "s#jlink {#jlink { addExtraModulePath 'javafx/javafx-jmods-${{ matrix.javafx }}'#" build.gradle
cat build.gradle
- name: 'Set JavaFX ${{ matrix.javafx }} (linux-arm)'
if: (matrix.os == 'buildjet-8vcpu-ubuntu-2204-arm')
# No JavaFX EA build for ARM at https://jdk.java.net/javafx23/, therefore using Maven Central artifact
run: |
curl -s "https://search.maven.org/solrsearch/select?q=g:org.openjfx+AND+a:javafx&rows=10&core=gav" > /tmp/versions.json
jq '[.response.docs[] | select(.v | test(".*-ea\\+.*")) | select(.v | test("^17|^18|^19|^20|^21|^22") | not) | {version: .v}] | group_by(.version | capture("^(?<major>\\d+).*").major) | map(max_by(.version))' < /tmp/versions.json > /tmp/versions-latest.json
JAVAFX=$(jq -r '.[-1].version' /tmp/versions-latest.json)
echo "Using JavaFX ${JAVAFX}"
sed -i "/javafx {/{n;s#version = \".*\"#version = \"${JAVAFX}\"#}" build.gradle && cat build.gradle
# Gradle
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 21
distribution: 'temurin'
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Prepare merged jars and modules dir
# prepareModulesDir is executing a build, which should run through even if no upload to builds.jabref.org is made
if: (steps.checksecrets.outputs.secretspresent == 'NO')
run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" prepareModulesDir
- name: Set up macOS key chain
if: (matrix.os == 'macos-latest') && (steps.checksecrets.outputs.secretspresent == 'YES')
uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d
with:
p12-file-base64: ${{ secrets.OSX_SIGNING_CERT }}
p12-password: ${{ secrets.OSX_CERT_PWD }}
keychain-password: jabref
- name: Set up macOS key chain for app id cert
if: (matrix.os == 'macos-latest') && (steps.checksecrets.outputs.secretspresent == 'YES')
uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d
with:
p12-file-base64: ${{ secrets.OSX_SIGNING_CERT_APPLICATION }}
p12-password: ${{ secrets.OSX_CERT_PWD }}
create-keychain: false
keychain-password: jabref
- name: Build runtime image and installer
shell: bash
run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" jpackage jlinkZip
- name: Package application image
shell: bash
run: ${{ matrix.archivePortable }}
- name: Rename files
if: (matrix.os != 'macos-latest')
shell: pwsh
run: |
get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "${{ steps.gitversion.outputs.AssemblySemVer }}","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}"}
get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "portable","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}-portable"}
- name: Repack deb file for Debian
if: (matrix.os == 'ubuntu-latest')
shell: bash
run: |
cd build/distribution
ar x jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64.deb
zstd -d < control.tar.zst | xz > control.tar.xz
zstd -d < data.tar.zst | xz > data.tar.xz
ar -m -c -a sdsd jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64_repackaged.deb debian-binary control.tar.xz data.tar.xz
rm debian-binary control.tar.* data.tar.*
mv -f jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64_repackaged.deb jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64.deb
- name: Rename files with JDK version
shell: bash
run: |
for file in build/distribution/*.*; do
base=${file%.*}
ext=${file##*.}
mv "$file" "${base}-jdk${{ matrix.jdk }}-javafx${{ matrix.javafx }}.${ext}"
done
# Upload
- name: Set up rsync (macOS)
if: (matrix.os == 'macos-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main')
run: brew install rsync
- name: Set up rsync (Windows)
if: (matrix.os == 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main')
# We want to have rsync available at this place to avoid uploading and downloading from GitHub artifact store (taking > 5 minutes in total)
# We cannot use "action-rsyncer", because that requires Docker which is unavailable on Windows
# We cannot use "setup-rsync", because that does not work on Windows
# We do not use egor-tensin/setup-cygwin@v4, because it replaces the default shell
run: choco install --no-progress rsync
- name: Set up SSH key
if: (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main')
run: |
echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey
chmod 600 sshkey
- name: Upload to builds.jabref.org (Windows)
if: (matrix.os == 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main')
shell: cmd
# for rsync installed by chocolatey, we need the ssh.exe delivered with that installation
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/jdk-ea && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/jdk-ea/ || true
- name: Upload to builds.jabref.org (linux, macOS)
if: (matrix.os != 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main')
shell: bash
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/jdk-ea && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/jdk-ea/
- name: Upload to GitHub workflow artifacts store
if: (steps.checksecrets.outputs.secretspresent != 'YES') || (github.ref != 'refs/heads/main')
uses: actions/upload-artifact@v4
with:
name: JabRef-${{ matrix.os }}
path: build/distribution
compression-level: 0 # no compression

341
jabref/.github/workflows/deployment.yml vendored Normal file
View File

@ -0,0 +1,341 @@
name: Deployment
on:
push:
branches:
- main
- main-release
paths-ignore:
- 'docs/**'
- 'src/test/**'
- 'README.md'
tags:
- '*'
pull_request:
merge_group:
workflow_dispatch:
inputs:
notarization:
type: boolean
required: false
default: false
env:
SpringerNatureAPIKey: ${{ secrets.SpringerNatureAPIKey }}
AstrophysicsDataSystemAPIKey: ${{ secrets.AstrophysicsDataSystemAPIKey }}
IEEEAPIKey: ${{ secrets.IEEEAPIKey }}
BiodiversityHeritageApiKey: ${{ secrets.BiodiversityHeritageApiKey}}
OSXCERT: ${{ secrets.OSX_SIGNING_CERT }}
GRADLE_OPTS: -Xmx4g -Dorg.gradle.vfs.watch=false
JAVA_OPTS: -Xmx4g
concurrency:
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-13]
include:
- os: ubuntu-latest
displayName: linux
archivePortable: tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux.tar.gz && rm -R build/distribution/JabRef
- os: windows-latest
displayName: windows
archivePortable: 7z a -r build/distribution/JabRef-portable_windows.zip ./build/distribution/JabRef && rm -R build/distribution/JabRef
- os: macos-13 # intel image
displayName: macOS
runs-on: ${{ matrix.os }}
outputs:
major: ${{ steps.gitversion.outputs.Major }}
minor: ${{ steps.gitversion.outputs.Minor }}
branchname: ${{ steps.gitversion.outputs.branchName }}
name: ${{ matrix.displayName }} installer and portable version
steps:
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Fetch all history for all tags and branches
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'true'
show-progress: 'false'
- name: Install pigz and cache (linux)
if: (matrix.os == 'ubuntu-latest')
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: pigz
version: 1.0
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v3.0.0
with:
versionSpec: "5.x"
- name: Run GitVersion
id: gitversion
uses: gittools/actions/gitversion/execute@v3.0.0
- name: Setup JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Prepare merged jars and modules dir (macOS)
# prepareModulesDir is executing a build, which should run through even if no upload to builds.jabref.org is made
if: (matrix.os == 'macos-13') || (steps.checksecrets.outputs.secretspresent == 'NO')
run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" prepareModulesDir
- name: Setup macOS key chain
if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES')
uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d
with:
p12-file-base64: ${{ secrets.OSX_SIGNING_CERT }}
p12-password: ${{ secrets.OSX_CERT_PWD }}
keychain-password: jabref
- name: Setup macOS key chain for app id cert
if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES')
uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d
with:
p12-file-base64: ${{ secrets.OSX_SIGNING_CERT_APPLICATION }}
p12-password: ${{ secrets.OSX_CERT_PWD }}
create-keychain: false
keychain-password: jabref
- name: Build dmg (macOS)
if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
jpackage \
--module org.jabref/org.jabref.Launcher \
--module-path ${{env.JAVA_HOME}}/jmods/:build/jlinkbase/jlinkjars \
--add-modules org.jabref,org.jabref.merged.module \
--add-modules jdk.incubator.vector \
--dest build/distribution \
--app-content buildres/mac/jabrefHost.py \
--app-content buildres/mac/native-messaging-host \
--name JabRef \
--app-version ${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }} \
--verbose \
--mac-sign \
--vendor "JabRef e.V." \
--mac-package-identifier JabRef \
--mac-package-name JabRef \
--type dmg --mac-signing-key-user-name "JabRef e.V. (6792V39SK3)" \
--mac-package-signing-prefix org.jabref \
--mac-entitlements buildres/mac/jabref.entitlements \
--icon src/main/resources/icons/jabref.icns \
--resource-dir buildres/mac \
--file-associations buildres/mac/bibtexAssociations.properties \
--jlink-options --bind-services \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control.skin=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections.transformation=org.jabref \
--java-options --add-modules=jdk.incubator.vector
- name: Build pkg (macOS)
if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
jpackage \
--module org.jabref/org.jabref.Launcher \
--module-path ${{env.JAVA_HOME}}/jmods/:build/jlinkbase/jlinkjars \
--add-modules org.jabref,org.jabref.merged.module \
--add-modules jdk.incubator.vector \
--dest build/distribution \
--app-content buildres/mac/jabrefHost.py \
--app-content buildres/mac/native-messaging-host \
--name JabRef \
--app-version ${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }} \
--verbose \
--mac-sign \
--vendor "JabRef e.V." \
--mac-package-identifier JabRef \
--mac-package-name JabRef \
--type pkg --mac-signing-key-user-name "JabRef e.V. (6792V39SK3)" \
--mac-package-signing-prefix org.jabref \
--mac-entitlements buildres/mac/jabref.entitlements \
--icon src/main/resources/icons/jabref.icns \
--resource-dir buildres/mac \
--file-associations buildres/mac/bibtexAssociations.properties \
--jlink-options --bind-services \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control.skin=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref \
--java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.graphics/javafx.scene=org.jabref \
--java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections=org.jabref \
--java-options --add-opens=javafx.base/javafx.collections.transformation=org.jabref \
--java-options --add-modules=jdk.incubator.vector
- name: Build runtime image and installer (linux, Windows)
if: (matrix.os != 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" jpackage jlinkZip
- name: Package application image (linux, Windows)
if: (matrix.os != 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: ${{ matrix.archivePortable }}
- name: Rename files
if: (matrix.os != 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES')
shell: pwsh
run: |
get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "${{ steps.gitversion.outputs.AssemblySemVer }}","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}"}
get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "portable","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}-portable"}
- name: Repack deb file for Debian
if: (matrix.os == 'ubuntu-latest') && (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
cd build/distribution
ar x jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64.deb
zstd -d < control.tar.zst | xz > control.tar.xz
zstd -d < data.tar.zst | xz > data.tar.xz
ar -m -c -a sdsd jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64_repackaged.deb debian-binary control.tar.xz data.tar.xz
rm debian-binary control.tar.* data.tar.*
mv -f jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64_repackaged.deb jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64.deb
- name: Setup rsync (macOS)
if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'macos-13') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true))) }}
run: brew install rsync
- name: Setup rsync (Windows)
if: (matrix.os == 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue'))
# We want to have rsync available at this place to avoid uploading and downloading from GitHub artifact store (taking > 5 minutes in total)
# We cannot use "action-rsyncer", because that requires Docker which is unavailable on Windows
# We cannot use "setup-rsync", because that does not work on Windows
# We do not use egor-tensin/setup-cygwin@v4, because it replaces the default shell
run: choco install --no-progress rsync
- name: Setup SSH key
if: ${{ (steps.checksecrets.outputs.secretspresent == 'YES') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && ((matrix.os != 'macos-13') || !((startsWith(github.ref, 'refs/tags/') || (inputs.notarization == true)))) }}
run: |
echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey
chmod 600 sshkey
- name: Upload to builds.jabref.org (Windows)
if: (matrix.os == 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue'))
shell: cmd
# for rsync installed by chocolatey, we need the ssh.exe delivered with that installation
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
- name: Upload to builds.jabref.org (linux, macOS)
# macOS: Negated condition of "Upload to GitHub workflow artifacts store (macOS)"
# Reason: We either upload the non-notarized files - or notarize the files later (and upload these later)
# needs to be on one line; multi line does not work
if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'ubuntu-latest') || ((matrix.os == 'macos-13') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)))) }}
shell: bash
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
- name: Upload to GitHub workflow artifacts store (macOS)
if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') && (startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)
uses: actions/upload-artifact@v4
with:
# tbn = to-be-notarized
name: JabRef-macOS-tbn
path: build/distribution
compression-level: 0 # no compression
- name: Upload to GitHub workflow artifacts store
if: (steps.checksecrets.outputs.secretspresent != 'YES')
uses: actions/upload-artifact@v4
with:
name: JabRef-${{ matrix.os }}
path: build/distribution
compression-level: 0 # no compression
announce:
name: Comment on pull request
runs-on: ubuntu-latest
needs: [build]
if: ${{ github.event_name == 'pull_request' }}
steps:
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Comment PR
if: (steps.checksecrets.outputs.secretspresent == 'YES')
uses: thollander/actions-comment-pull-request@v3
with:
message: |
The build of this PR is available at <https://builds.jabref.org/pull/${{ github.event.pull_request.number }}/merge>.
comment-tag: download-link
mode: recreate
notarize: # outsourced in a separate job to be able to rerun if this fails for timeouts
name: macOS notarization
runs-on: macos-13
needs: [build]
if: ${{ startsWith(github.ref, 'refs/tags/') || inputs.notarization == true }}
steps:
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Download from GitHub workflow artifacts store (macOS)
if: (steps.checksecrets.outputs.secretspresent == 'YES')
uses: actions/download-artifact@master
with:
name: JabRef-macOS-tbn
path: build/distribution/
- name: Notarize dmg
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
xcrun notarytool store-credentials "notarytool-profile" --apple-id "vorstand@jabref.org" --team-id "6792V39SK3" --password "${{ secrets.OSX_NOTARIZATION_APP_PWD }}"
xcrun notarytool submit build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.dmg --keychain-profile "notarytool-profile" --wait
xcrun stapler staple build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.dmg
- name: Notarize pkg
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
xcrun notarytool store-credentials "notarytool-profile" --apple-id "vorstand@jabref.org" --team-id "6792V39SK3" --password "${{ secrets.OSX_NOTARIZATION_APP_PWD }}"
xcrun notarytool submit build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.pkg --keychain-profile "notarytool-profile" --wait
xcrun stapler staple build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.pkg
- name: Upload to builds.jabref.org
if: (steps.checksecrets.outputs.secretspresent == 'YES')
shell: bash
run: |
echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey
chmod 600 sshkey
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ needs.build.outputs.branchname }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ needs.build.outputs.branchname }}/

96
jabref/.github/workflows/gource.yml vendored Normal file
View File

@ -0,0 +1,96 @@
name: Gource
on:
push:
branches:
- gource
- fix-gource
schedule:
- cron: '15 3 5 * *'
workflow_dispatch:
concurrency:
group: gource
cancel-in-progress: true
jobs:
action:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- name: 'Checkout'
uses: actions/checkout@v4
with:
fetch-depth: 0
show-progress: 'false'
- name: 'Development history of current build'
uses: BoundfoxStudios/action-gource@v2
with:
gource_title: 'JabRef v5.16 (in development) | more information at contribute.jabref.org'
logo_url: 'https://www.jabref.org/img/JabRef-icon-256.png'
avatars_auto_fetch: true
# 5s * 365 / 4 = 7.5min
gource_seconds_per_day: 1
gource_start_date: '2024-07-11'
gource_file_filter: 'buildres/csl|\.csl'
- name: 'Store video'
run: |
mkdir gource-videos
mv ./gource/gource.mp4 ./gource-videos/jabref-v5.16-dev.mp4
- name: 'Development history of last release'
uses: BoundfoxStudios/action-gource@v2
with:
gource_title: 'JabRef v5.15 | more information at contribute.jabref.org'
logo_url: 'https://www.jabref.org/img/JabRef-icon-256.png'
avatars_auto_fetch: true
# 5s * 365 / 4 = 7.5min
gource_seconds_per_day: 2
gource_start_date: '2024-07-09'
gource_stop_date: '2024-07-10'
gource_file_filter: 'buildres/csl|\.csl'
- name: 'Store video'
run: |
mv ./gource/gource.mp4 ./gource-videos/jabref-v5.15.mp4
- name: 'Complete development history'
uses: BoundfoxStudios/action-gource@v2
with:
gource_title: 'JabRef | more information at contribute.jabref.org'
logo_url: 'https://www.jabref.org/img/JabRef-icon-256.png'
avatars_auto_fetch: true
# 0.01 leads to a 45 second video for the complete history until end of 2020
# 0.1 leads to a 8 minute video
gource_seconds_per_day: 0.1
gource_file_filter: 'buildres/csl|\.csl'
- name: 'Store video'
run: |
mv gource/gource.mp4 gource-videos/jabref-complete.mp4
- name: 'Upload gource video'
uses: actions/upload-artifact@v4
with:
name: Gource
path: gource-videos/
retention-days: 80
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret BUILDJABREFPRIVATEKEY not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret BUILDJABREFPRIVATEKEY present"
fi
env:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Upload to files.jabref.org
if: steps.checksecrets.outputs.secretspresent == 'YES'
uses: Pendect/action-rsyncer@v2.0.0
env:
DEPLOY_KEY: ${{ secrets.buildJabRefPrivateKey }}
with:
flags: -vaz --itemize-changes --stats --partial-dir=/tmp/partial
options: ''
ssh_options: '-p 9922'
src: 'gource-videos/'
dest: jrrsync@build-upload.jabref.org:/var/www/files.jabref.org/www/gource/

View File

@ -0,0 +1,124 @@
name: On labeled issue
on:
issues:
types:
- labeled
jobs:
Assigned:
# Triggered when manually assigned the label "📍 Assigned" to trigger the automatic unassignment after 30 days
name: "📍 Assigned"
if: ${{ github.event.label.name == '📍 Assigned' && github.repository_owner == 'JabRef' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Move Issue to "Free to take" Column in "Candidates for University Projects"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "📍 Assigned"
target-column: "Free to take"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Free to take" Column in "Good First Issues"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "📍 Assigned"
target-column: "Free to take"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
FirstTimeCodeContribution:
if: ${{ github.event.label.name == 'FirstTimeCodeContribution' && github.repository_owner == 'JabRef' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: GreetingFirstTimeCodeContribution
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number || github.event.pull_request.number }}
body: |
Welcome to the vibrant world of open-source development with JabRef!
Newcomers, we're excited to have you on board. Start by exploring our [Contributing](https://github.com/JabRef/jabref/blob/main/CONTRIBUTING.md) guidelines, and don't forget to check out our [workspace setup guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace) to get started smoothly.
In case you encounter failing tests during development, please check our [developer FAQs](https://devdocs.jabref.org/code-howtos/faq.html)!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on [JabRef's Gitter chat](https://gitter.im/JabRef/jabref). And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
⚠ Note that this issue will become unassigned if it isn't closed within **30 days**.
🔧 A maintainer can also add the **`Pinned`** label to prevent it from being unassigned automatically.
Happy coding! 🚀
- name: Move Issue to "Assigned" Column in "Candidates for University Projects"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "FirstTimeCodeContribution"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Assigned" Column in "Good First Issues"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "FirstTimeCodeContribution"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
good-first-issue:
name: "good first issue"
if: "${{ github.event.label.name == 'good first issue' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: "good first issue"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 5 --owner JabRef --url $ISSUE_URL
needs-refinement:
if: github.event.label.name == 'needs-refinement' && github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- name: needs-refinement
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 15 --owner JabRef --url $ISSUE_URL
status-freeze:
name: "status: freeze"
if: "${{ github.event.label.name == 'status: freeze' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: "status: freeze"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 9 --owner JabRef --url $ISSUE_URL
ui:
if: "${{ github.event.label.name == 'ui' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: ui
env:
GH_DEBUG: api
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
echo $ISSUE_URL
gh project item-add 8 --owner JabRef --url $ISSUE_URL

View File

@ -0,0 +1,23 @@
name: On labeled PR
on:
pull_request:
types:
- labeled
jobs:
automerge:
name: Auto Merge
if: "${{ github.event.label.name == 'automerge' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: Approve PR
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GH_TOKEN_JABREF_MACHINE_PR_APPROVE}}
- name: Merge PR
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GH_TOKEN_UPDATE_GRADLE_WRAPPER}}

View File

@ -0,0 +1,34 @@
name: On unlabeled issue
on:
issues:
types:
- unlabeled
jobs:
FirstTimeCodeContribution_or_Assigned:
if: ${{ ((github.event.label.name == 'FirstTimeCodeContribution') || (github.event.label.name == '📍 Assigned')) && github.repository_owner == 'JabRef' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Move Issue to "Free to take" Column in "Candidates for University Projects"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Free to take" Column in "Good First Issues"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true

63
jabref/.github/workflows/pages.yml vendored Normal file
View File

@ -0,0 +1,63 @@
name: Deploy Jekyll site to Pages
on:
pull_request:
paths:
- 'docs/**'
- '.github/workflows/pages.yml'
push:
branches:
main
paths:
- 'docs/**'
- '.github/workflows/pages.yml'
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
show-progress: 'false'
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3' # Not needed with a .ruby-version file
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
cache-version: 0 # Increment this number if you need to re-download cached gems
working-directory: docs/
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Build with Jekyll
run: |
cd docs
bundle exec jekyll build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/_site/
deploy:
if: github.ref == 'refs/heads/main'
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

63
jabref/.github/workflows/pr-comment.yml vendored Normal file
View File

@ -0,0 +1,63 @@
# Description: This workflow is triggered when the "Check" workflow completes.
# Since this pull request has write permissions on the target repo, we should **NOT** execute any untrusted code.
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
# Based on https://github.com/spring-projects/spring-security/pull/15477/files
---
name: Comment on PR
on:
workflow_run:
workflows: ["Tests"]
types:
- completed
jobs:
comment:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-a-workflow-based-on-the-conclusion-of-another-workflow
if: ${{ github.event.workflow_run.conclusion == 'failure' && (github.repository_owner == 'JabRef') }}
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
pull-requests: write
timeout-minutes: 10
steps:
- name: Download PR number
uses: actions/download-artifact@v4
with:
name: pr_number
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
- name: Read pr_number.txt
id: read-pr_number
run: |
PR_NUMBER=$(cat pr_number.txt)
echo "Read PR number $PR_NUMBER"
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4
- name: Is PR from forked?
if: ${{ steps.read-pr_number.outputs.pr_number != '' }}
id: isCrossRepository
run: |
isCrossRepository=$(gh pr view $pr_number --json isCrossRepository --jq '.isCrossRepository')
echo "Got isCrossRepository $isCrossRepository"
echo isCrossRepository=$isCrossRepository >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ github.token }}
pr_number: ${{ steps.read-pr_number.outputs.pr_number }}
- name: Checkout
if: ${{ steps.read-pr_number.outputs.pr_number != '' && steps.isCrossRepository.outputs.isCrossRepository == 'true' }}
uses: actions/checkout@v4
with:
fetch-depth: '0'
show-progress: 'false'
token: ${{ secrets.GITHUB_TOKEN }}
- name: jbang
if: ${{ steps.read-pr_number.outputs.pr_number != '' && steps.isCrossRepository.outputs.isCrossRepository == 'true' }}
uses: jbangdev/jbang-action@v0.119.0
with:
script: ghprcomment@koppor/ghprcomment
scriptargs: "-r JabRef/jabref -p ${{ steps.read-pr_number.outputs.pr_number }} -w ${{ github.event.workflow_run.id }}"
trust: https://github.com/koppor/ghprcomment/
env:
GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}

View File

@ -0,0 +1,60 @@
name: Fetcher Tests
on:
push:
branches:
- main
paths:
- 'src/main/java/org/jabref/logic/importer/fetcher/**'
- 'src/test/java/org/jabref/logic/importer/fetcher/**'
- 'src/main/java/org/jabref/logic/crawler/**'
- 'src/test/java/org/jabref/logic/crawler/**'
- '.github/workflows/tests-fetchers.yml'
- 'build.gradle'
pull_request:
paths:
- 'src/main/java/org/jabref/logic/importer/fetcher/**'
- 'src/test/java/org/jabref/logic/importer/fetcher/**'
- '.github/workflows/tests-fetchers.yml'
- 'build.gradle'
schedule:
# run on each Wednesday
- cron: '2 3 * * 3'
workflow_dispatch:
env:
SpringerNatureAPIKey: ${{ secrets.SPRINGERNATUREAPIKEY_FOR_TESTS }}
AstrophysicsDataSystemAPIKey: ${{ secrets.AstrophysicsDataSystemAPIKey_FOR_TESTS }}
IEEEAPIKey: ${{ secrets.IEEEAPIKey_FOR_TESTS }}
BiodiversityHeritageApiKey: ${{ secrets.BiodiversityHeritageApiKey_FOR_TESTS}}
concurrency:
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
permissions:
contents: read
jobs:
fetchertests:
name: Fetcher tests
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Run fetcher tests
run: ./gradlew fetcherTest
env:
CI: "true"

393
jabref/.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,393 @@
name: Tests
on:
push:
branches:
- main
- main-release
pull_request:
merge_group:
workflow_dispatch:
env:
SpringerNatureAPIKey: ${{ secrets.SpringerNatureAPIKey }}
AstrophysicsDataSystemAPIKey: ${{ secrets.AstrophysicsDataSystemAPIKey }}
IEEEAPIKey: ${{ secrets.IEEEAPIKey }}
BiodiversityHeritageApiKey: ${{ secrets.BiodiversityHeritageApiKey}}
GRADLE_OPTS: -Xmx4g
JAVA_OPTS: -Xmx4g
concurrency:
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
permissions:
pull-requests: write
jobs:
checkstyle:
name: Checkstyle
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Run checkstyle reporter
uses: dbelyaev/action-checkstyle@master
with:
reporter: github-pr-review
github_token: ${{ secrets.GITHUB_TOKEN }}
checkstyle_config: 'config/checkstyle/checkstyle_reviewdog.xml'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Run checkstyle using gradle
run: ./gradlew checkstyleMain checkstyleTest checkstyleJmh
openrewrite:
name: OpenRewrite
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Run OpenRewrite
run: |
./gradlew rewriteDryRun
modernizer:
name: Modernizer
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Run modernizer
run: |
# enable failing of this task if modernizer complains
sed -i "s/failOnViolations = false/failOnViolations = true/" build.gradle
./gradlew modernizer
markdown:
name: Markdown
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'false'
show-progress: 'false'
- name: markdownlint-cli2-action
uses: DavidAnson/markdownlint-cli2-action@v17
with:
globs: |
*.md
docs/**/*.md
changelog:
name: CHANGELOG.md
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'false'
show-progress: 'false'
- name: Lint CHANGELOG.md
run: |
# Install jbang
curl -Ls https://sh.jbang.dev | bash -s - app setup
export PATH=$PATH:$HOME/.jbang/bin
# run heylogs verification
jbang com.github.nbbrd.heylogs:heylogs-cli:0.9.2:bin check CHANGELOG.md > heylogs.txt || true
# improve output
sed -i 's/all-h2-contain-a-version/all-h2-contain-a-version (ignored)/' heylogs.txt
cat heylogs.txt
# exit 1 in case of error
# We have 1 "valid" issue in CHANGELOG.md
grep -q "1 problem" heylogs.txt || exit 1
changelog-unreleased-only:
name: CHANGELOG.md - only unreleased touched
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'false'
show-progress: 'false'
fetch-depth: 0
- name: Install clparse
run: |
curl -LO https://github.com/marcaddeo/clparse/releases/download/0.9.1/clparse-0.9.1-x86_64-unknown-linux-musl.tar.gz
tar xzvf clparse-0.9.1-x86_64-unknown-linux-musl.tar.gz
sudo mv clparse /usr/local/bin/clparse
- name: Check CHANGELOG.md diff
run: |
diff \
<(git show origin/main:CHANGELOG.md | clparse --format=json --separator= - | jq '.releases[] | select(.version != null)') \
<(git show HEAD:CHANGELOG.md | clparse --format=json --separator= - | jq '.releases[] | select(.version != null)')
tests:
name: Unit tests
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Run tests
run: xvfb-run --auto-servernum ./gradlew check -x checkstyleJmh -x checkstyleMain -x checkstyleTest -x modernizer
env:
CI: "true"
- name: Prepare format failed test results
if: failure()
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: xml-twig-tools xsltproc
version: 1.0
- name: Format failed test results
if: failure()
run: scripts/after-failure.sh
databasetests:
name: Database tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
# needed because the postgres container does not provide a healthcheck
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Run tests on PostgreSQL
run: ./gradlew databaseTest --rerun-tasks
env:
CI: "true"
DBMS: "postgresql"
- name: Shutdown Ubuntu MySQL
run: sudo service mysql stop # Shutdown the Default MySQL, "sudo" is necessary, please not remove it
- name: Start custom MySQL
uses: mirromutth/mysql-action@v1.1
with:
host port: 3800
container port: 3307
character set server: 'utf8'
collation server: 'utf8_general_ci'
mysql version: '8.0'
mysql database: 'jabref'
mysql root password: 'root'
- name: Run tests on MySQL
run: ./gradlew databaseTest --rerun-tasks
env:
CI: "true"
DBMS: "mysql"
guitests:
name: GUI tests
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Run GUI tests
run: xvfb-run --auto-servernum ./gradlew guiTest
env:
CI: "true"
codecoverage:
name: Code coverage
runs-on: ubuntu-latest
services:
postgres:
image: postgres:10.8
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
# needed because the postgres container does not provide a healthcheck
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Check secrets presence
id: checksecrets
if: github.ref == 'refs/heads/main'
shell: bash
run: |
if [ "$CODECOV_TOKEN" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
echo "❌ Secret CODECOV_TOKEN not present"
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
echo "✔️ Secret CODECOV_TOKEN present"
fi
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Checkout source
if: github.ref == 'refs/heads/main'
uses: actions/checkout@v4
with:
submodules: 'true'
show-progress: 'false'
- name: Set up JDK
if: github.ref == 'refs/heads/main'
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Update test coverage metrics
if: (github.ref == 'refs/heads/main') && (steps.checksecrets.outputs.secretspresent == 'YES')
run: xvfb-run --auto-servernum ./gradlew jacocoTestReport
env:
CI: "true"
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
DBMS: "postgresql"
- uses: codecov/codecov-action@v4
if: (github.ref == 'refs/heads/main') && (steps.checksecrets.outputs.secretspresent == 'YES')
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload Codacy report
if: (github.ref == 'refs/heads/main') && (steps.checksecrets.outputs.secretspresent == 'YES')
run: bash <(curl -Ls https://coverage.codacy.com/get.sh)
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
requirements_coverage:
name: "Validate requirement coverage"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
show-progress: 'false'
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- run: ./gradlew traceRequirements
- if: failure()
run: cat build/reports/tracing.txt
# This is https://github.com/marketplace/actions/gradle-wrapper-validation
# It ensures that the jar file is from gradle and not by a strange third party.
gradlevalidation:
name: "Validate Gradle Wrapper"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
show-progress: 'false'
- uses: gradle/actions/wrapper-validation@v4
# This ensures that no git merge conflict markers (<<<, ...) are contained
merge_conflict_job:
name: Find merge conflicts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
show-progress: 'false'
- name: Merge Conflict finder
uses: olivernybroe/action-conflict-finder@v4.0
other_than_main:
name: Source branch is other than "main"
runs-on: ubuntu-latest
steps:
- if: github.head_ref == 'main'
uses: actions/github-script@v7
with:
script: |
core.setFailed('Pull requests should come from a branch other than "main"\n\n👉 Please read [the CONTRIBUTING guide](https://github.com/JabRef/jabref/blob/main/CONTRIBUTING.md#contributing) carefully again. 👈')
upload-pr-number:
runs-on: ubuntu-latest
steps:
- name: Create pr_number.txt
run: echo "${{ github.event.number }}" > pr_number.txt
- uses: actions/upload-artifact@v4
with:
name: pr_number
path: pr_number.txt

View File

@ -0,0 +1,25 @@
name: Update Gradle Wrapper
on:
schedule:
- cron: "0 5 * * 1"
workflow_dispatch:
jobs:
update-gradle-wrapper:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup JDK
uses: actions/setup-java@v4
with:
java-version: 23.0.1
distribution: 'temurin'
- name: Update Gradle Wrapper
uses: gradle-update/update-gradle-wrapper-action@v2
with:
labels: dependencies
repo-token: ${{ secrets.GH_TOKEN_UPDATE_GRADLE_WRAPPER }}

View File

@ -0,0 +1,24 @@
name: Release binaries on GitHub
on:
# due to synchronization with a complete build, we need a manual trigger
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Get binaries from builds.jabref.org
run: |
mkdir build
cd build
wget -q -m -r -nH --cut-dirs 2 --no-parent --accept=tar.gz,dmg,pkg,deb,rpm,zip,msi https://builds.jabref.org/tags/
- name: Release
uses: softprops/action-gh-release@v2
with:
draft: true
files: build/**

569
jabref/.gitignore vendored Normal file
View File

@ -0,0 +1,569 @@
# no generated files in version control
src/main/gen/
src/main/generated/
src-gen/
.lycheecache
javafx/javafx-sdk-*
javafx/javafx-jmods-*
javafx/javafx.html
javafx/*.tar.gz
javafx/*.zip
# generated by https://plugins.jetbrains.com/plugin/15991-plantuml-diagram-generator
*.puml
structure101-settings.java.hsw
# private data
/buildres/jabref-cert-2016.p12
# GitBook assets
docs/book.pdf
docs/_book/
# Jekyll for docs/
docs/Gemfile.lock
# ignore the generated markdown file if the user forgets to delete it
status.md
# Install4J
install4j6/
# JDK14 (see .github/deployment.yml for details)
jdk-14/
# Python
__pycache__/
# Snap
parts/
stage/
prime/
*.snap
jabref_source.tar.bz2
snap/.snapcraft/
# flatpak
flatpak/.buildconfig
flatpak/JabRef-portable_linux.tar.gz
# Gradle
# generated when `gradlew --gui` is called
ui/
# for workspace specific gradle properties
gradle.properties
# IntelliJ IDEA
.idea/*
!.idea/runConfigurations/
*.ipr
*.iml
# UNKNWON
jabref.xml
*.sonargraph
## !! IN CASE YOU UPDATE, PLEASE KEEP THE LINES AT THE END OF THE FILE !!
# Created by https://www.toptal.com/developers/gitignore/api/gradle,java,jabref,jetbrains,eclipse,netbeans,windows,linux,macos,node,snapcraft
# Edit at https://www.toptal.com/developers/gitignore?templates=gradle,java,jabref,jetbrains,eclipse,netbeans,windows,linux,macos,node,snapcraft
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project
### Eclipse Patch ###
# Spring Boot Tooling
.sts4-cache/
### JabRef ###
# JabRef - https://www.jabref.org/
*.sav
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
### JetBrains ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### JetBrains Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### NetBeans ###
**/nbproject/private/
**/nbproject/Makefile-*.mk
**/nbproject/Package-*.bash
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
### Node ###
# Logs
logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
### Node Patch ###
# Serverless Webpack directories
.webpack/
# Optional stylelint cache
# SvelteKit build / generate output
.svelte-kit
### Snapcraft ###
/parts/
/stage/
/prime/
/*.snap
# Snapcraft global state tracking data(automatically generated)
# https://forum.snapcraft.io/t/location-to-save-global-state/768
/snap/.snapcraft/
# Source archive packed by `snapcraft cleanbuild` before pushing to the LXD container
/*_source.tar.bz2
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### Gradle ###
.gradle
**/build/
!src/**/build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Avoid ignore Gradle wrappper properties
!gradle-wrapper.properties
# Cache of project
.gradletasknamecache
# Eclipse Gradle plugin generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
### Gradle Patch ###
# Java heap dump
*.hprof
# End of https://www.toptal.com/developers/gitignore/api/gradle,java,jabref,jetbrains,eclipse,netbeans,windows,linux,macos,node,snapcraft
## !! KEEP THESE LINES !!
# we really version .jar files - needs to be go after the www.gitignore.io-generated ones, because they ignore *.jar files
!/lib/*.jar
# do not distribute Oracle's JDBC driver
lib/ojdbc.jar
# do not ignore the source of the build
!/buildSrc/src/
!/buildSrc/src/main/groovy/org/jabref/build
# do not ignore JabRef icons (they are ignored by the macos setting above)
!src/main/java/org/jabref/gui/icon
!**/autosaveandbackup/*.bak
# generated during release process
CHANGELOG.html

15
jabref/.gitmodules vendored Normal file
View File

@ -0,0 +1,15 @@
[submodule "abbrv.jabref.org"]
path = buildres/abbrv.jabref.org
url = https://github.com/JabRef/abbrv.jabref.org.git
ignore = all
shallow = true
[submodule "csl-styles"]
path = src/main/resources/csl-styles
url = https://github.com/citation-style-language/styles.git
ignore = all
shallow = true
[submodule "csl-locales"]
path = src/main/resources/csl-locales
url = https://github.com/citation-style-language/locales.git
ignore = all
shallow = true

8
jabref/.gitpod.Dockerfile vendored Normal file
View File

@ -0,0 +1,8 @@
# See https://www.gitpod.io/docs/java-in-gitpod/ for a full documentation of Java in GitPod
FROM gitpod/workspace-full
# All available versions can be listed using sdk ls java
# More information about SDKMAN available at https://github.com/sdkman/sdkman-cli#sdkman-cli
RUN bash -c ". /home/gitpod/.sdkman/bin/sdkman-init.sh \
&& sdk install java 23-open"

16
jabref/.gitpod.yml Normal file
View File

@ -0,0 +1,16 @@
image:
file: .gitpod.Dockerfile
tasks:
- init: ./gradlew assemble
jetbrains:
intellij:
plugins:
- CheckStyle-IDEA
- zielu.gittoolbox
vscode:
extensions:
- redhat.java
- richardwillis.vscode-gradle
- vscjava.vscode-java-debug
- kiteco.kite
- DavidAnson.vscode-markdownlint

16
jabref/.lycheeignore Normal file
View File

@ -0,0 +1,16 @@
https://arxiv.org/
https://chrome.google.com/
https://contribute.jabref.org/
https://donations.jabref.org/
https://pubs.acs.org/
https://scholar.archive.org/
https://web.archive.org/
https://www.researchgate.net/privacy-policy
https://www.sciencedirect.com/
https://github.com/koppor/jabref/issue
https://github.com/koppor/jabref/pull
https://github.com/JabRef/jabref/issue
https://github.com/JabRef/jabref/pull
0005-example.md

8
jabref/.markdownlint.yml Normal file
View File

@ -0,0 +1,8 @@
default: true
# allow arbitrary line length
MD013: false
MD033:
# we have <a> tags with ids and superscript
allowed_elements: ['a', 'kbd', 'sup']

6
jabref/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"recommendations": [
"davidanson.vscode-markdownlint",
"ltex-plus.vscode-ltex-plus"
]
}

View File

@ -0,0 +1,7 @@
Checkstyle
CouchDB
JabDrive
JabRef
OpenFastTrace
OpenRewrite
Temurin

6
jabref/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"java.configuration.updateBuildConfiguration": "interactive",
"java.format.settings.url": "/config/VSCode Code Style.xml",
"java.checkstyle.configuration": "${workspaceFolder}/config/checkstyle/checkstyle_reviewdog.xml",
"java.checkstyle.version": "10.3.4"
}

1498
jabref/CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

58
jabref/CITATION.cff Normal file
View File

@ -0,0 +1,58 @@
# This CITATION.cff file was generated with cffinit.
# Visit https://bit.ly/cffinit to generate yours today!
cff-version: 1.2.0
title: JabRef
message: >-
If you use this software, please cite it using the
metadata from this file.
type: software
authors:
- given-names: Oliver
family-names: Kopp
orcid: 'https://orcid.org/0000-0001-6962-4290'
- given-names: Tobias
family-names: Diez
orcid: 'https://orcid.org/0000-0002-1407-7696'
- given-names: Christoph
family-names: Schwentker
- given-names: Carl Christian
family-names: Snethlage
- given-names: Jonatan
family-names: Asketorp
- given-names: Benedikt
family-names: Tutzer
- given-names: Thilo
family-names: Ertel
- given-names: Houssem
family-names: Nasri
repository-code: 'https://github.com/jabref/jabref/'
url: 'https://www.jabref.org'
abstract: >-
JabRef is an open-source, cross-platform citation and
reference management tool.
keywords:
- reference manager
- bibtex
- biblatex
license: MIT
preferred-citation:
type: article
authors:
- family-names: "Kopp"
given-names: "Oliver"
orcid: "https://orcid.org/0000-0001-6962-4290"
- family-names: "Snethlage"
given-names: "Carl Christian"
- family-names: "Schwentker"
given-names: "Christoph"
doi: "10.47397/tb/44-3/tb138kopp-jabref"
journal: "TUGboat"
month: 11
start: 441
end: 447
title: "JabRef: BibTeX-based literature management software"
issue: 138
volume: 44
number: 3
year: 2023

198
jabref/CONTRIBUTING.md Normal file
View File

@ -0,0 +1,198 @@
# Contributing
General overview about contributing for non-programmers is available at <https://docs.jabref.org/contributing>.
We welcome contributions to JabRef and encourage you to follow the GitHub workflow specified below.
If you are not familiar with this type of workflow, take a look at GitHub's excellent overview on the [GitHub flow](https://docs.github.com/en/get-started/using-github/github-flow) and the explanation of [Feature Branch Workflow](https://atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow) for the idea behind this kind of development.
Before you start, get the JabRef code on your local machine.
Detailed instructions about this step can be found in our [guidelines for setting up a local workspace](getting-into-the-code/guidelines-for-setting-up-a-local-workspace/).
## Table of Contents
* [Choosing a task](#choosing-a-task-)
* [Getting a task assigned](#getting-a-task-assigned)
* [Pull Request Process](#pull-request-process)
* [Requirements on the pull request and code](#requirements-on-the-pull-request-and-code)
* [After submission of a pull request](#after-submission-of-a-pull-request)
* [Development hints](#development-hints)
## Choosing a task [![Join the chat at https://gitter.im/JabRef/jabref](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JabRef/jabref)
In general, we offer small issues perfect for aspiring developers.
These tasks provide an opportunity to learn how to set up your local workspace, create your first pull request on GitHub, and contribute towards solving minor problems or making small enhancements in JabRef.
It is essential to note that JabRef's issues vary in difficulty.
Some are simpler, while others are more complex. Our primary aim is to guide you through the code, ensuring that the understanding scope remains manageable. Sometimes, grasping the code might demand more effort than actually writing lines of code.
### I am a student and I want to start with something easy
We collect good issues to start with at our [list of good first issues](https://github.com/orgs/JabRef/projects/5/views/1).
### I am a student and I want to choose from a curated list of university projects
Take a look at [JabRef's candidates for university projects](https://github.com/orgs/JabRef/projects/3). There, a list of possible projects to work on during a teaching period is offered.
### I am a lecturer
If you ask yourself how to integrate JabRef into your class, please read the [documentation about how to integrate JabRef into a class of software engineering training](https://devdocs.jabref.org/teaching.html#jabref-and-software-engineering-training).
As student, you may notify your lecturer about this possibility.
### I want something with huge impact
Look at the discussions in our forum about [new features](https://discourse.jabref.org/c/features/6).
Find an interesting topic, discuss it and start contributing.
Alternatively, you can check out [JabRef's projects page at GitHub](https://github.com/JabRef/jabref/projects?query=is%3Aopen).
Although, of course, you can choose to work on ANY issue, choosing from the projects page has the advantage that these issues have already been categorized, sorted and screened by JabRef maintainers.
A typical subclassifications scheme is "priority" (high, normal and low). Fixing high priority issues is preferred.
### I want to know how to contribute code and set up my workspace
Check out the [documentation for developers](https://devdocs.jabref.org/contributing.html#contribute-code)
### I want to improve the developer's documentation
For improving developer's documentation, go on at the [docs/ subdirectory of JabRef's code](https://github.com/JabRef/jabref/tree/main/docs) and edit the file.
GitHub offers a good guide at [Editing files in another user's repository](https://help.github.com/en/github/managing-files-in-a-repository/editing-files-in-another-users-repository).
One can also add [callouts](https://just-the-docs.github.io/just-the-docs-tests/components/callouts/).
## Getting a task assigned
Comment on the issue you want to work at with `/assign-me`.
GitHub will then automatically assign you.
## Pull Request Process
1. Follow the steps at [Pre Condition 3: Code on the local machine](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/pre-03-code.html) to a) create a fork and b) have the fork checked out on your local machine
2. Ensure that you followed the [steps to set up a local workspace](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/) to have the code running properly in IntelliJ.
3. **Create a new branch** (such as `fix-for-issue-121`). Be sure to create a **separate branch** for each improvement you implement.
4. Work on the **new branch — not the `main` branch.** Refer to our [code how-tos](https://devdocs.jabref.org/code-howtos) if you have questions about your implementation.
5. Create a [pull request to JabRef main repository](https://github.com/JabRef/jabref/pulls).
For an overview on the concept of pull requests, take a look at GitHub's [pull request help documentation](https://help.github.com/articles/about-pull-requests/).
1. Ensure that you followed the requirements listed below. They are not too hard, they merely support the maintainers to focus on supportive feedback than just stating the obvious.
2. For text inspirations, consider [How to write the perfect pull request](https://github.com/blog/1943-how-to-write-the-perfect-pull-request).
3. In case your pull request is not yet complete or not yet ready for review, create a [draft pull request](https://github.blog/2019-02-14-introducing-draft-pull-requests/) instead.
6. Wait for feedback of the developers
7. Address the feedback of the developers
8. After two developers gave their green flag, the pull request will be merged.
In case you have any questions, please
1. comment on the issue,
2. show up in our [Gitter chat](https://gitter.im/JabRef/jabref), or
3. show your current code using a draft pull request and ask questions.
We favor looking into your code using a draft pull request, because we can then also load the code into our IDE.
As counterexample, if you provide us with a screenshot of your changes, we cannot run it in our IDE.
### Requirements on the pull request and code
#### Test your code
We know that writing test cases takes a lot of time.
Nevertheless, we rely on our test cases to ensure that a bug fix or a feature implementation does not break anything.
For UI changes, we know that test cases are hard to write.
Therefore, you can omit them.
However, please at least add a screenshot showing your changes to the request.
<!-- In case you do not have time to add a test case, we nevertheless ask you to at least run `gradlew check` to ensure that your change does not break anything else. -->
#### Write a good commit message
See [good commit message](https://github.com/joelparkerhenderson/git-commit-message) or [commit guidelines section of Pro Git](http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines). For the curious: [Why good commit messages matter!](https://cbea.ms/git-commit/). The first line of your commit message is automatically taken as the title for the pull-request. All other lines make up the body of the pull request. Add the words `fixes #xxx` to your PR to auto-close the corresponding issue.
#### Add your change to `CHANGELOG.md`
You should edit the [`CHANGELOG.md`](https://github.com/JabRef/jabref/blob/main/CHANGELOG.md#changelog) file located in the root directory of the JabRef source. Add a line with your changes in the appropriate section.
If you did internal refactorings or improvements not visible to the user (e.g., UI, .bib file), then you don't need to put an entry there.
#### Author credits
Please, **do not add yourself at JavaDoc's `@authors`**.
The contribution information is tracked via the version control system and shown at [https://github.com/JabRef/jabref/graphs/contributors](https://github.com/JabRef/jabref/graphs/contributors).
We also show all contributors in our blog posts. See [Release 5.15 blog post](https://blog.jabref.org/2024/07/16/JabRef5-15/) for an example.
Your contribution is considered being made under [MIT license](https://tldrlegal.com/license/mit-license).
#### Notes on AI usage
Please keep these two principles in mind when you contribute:
1. Never let an LLM speak for you.
2. Never let an LLM think for you.
More reading on that is available at <https://roe.dev/blog/using-ai-in-open-source>.
We reserve the right to reject pull requests that contain little or no genuine and original contribution from the contributor.
### After submission of a pull request
After you submitted a pull request, automated checks will run.
You may see "Some checks were not successful".
You can click on failing checks to see more information about why they failed.
Then, please look into them and handle accordingly.
Afterwards, you will receive comments on your pull request.
The pull request may be approved immediatly, or a reviewer may request changes.
In that case, please implement the requested changes.
After implementing changes, commit to the branch your pull request is *from* and push.
The pull request will automatically be updated with your changes.
Your commits will also be automatically squashed upon the pull request being accepted.
Please **Never ever close a pull request and open a new one** -
This causes unessesary work on our side, and is not in the the style of the GitHub open source community.
You can push any changes you need to make to the branch your pull request is *from*.
These changes will be automatically added to your pull request.
### Development hints
#### When adding an external dependency
Please try to use a version available at JCenter and add it to `build.gradle`.
In any case, describe the library at [`external-libraries.md`](https://github.com/JabRef/jabref/blob/main/external-libraries.md#external-libraries).
We need that information for our package maintainers (e.g., those of the [debian package](https://tracker.debian.org/pkg/jabref)).
#### When making an architectural decision
In case you add a library or do major code rewrites, we ask you to document your decision. Recommended reading: [https://adr.github.io/](https://adr.github.io).
We simply ask to create a new markdown file in `docs/adr` following the template presented at [https://adr.github.io/madr/](https://adr.github.io/madr/).
You can link that ADR using `@ADR({num})` as annotation.
#### When adding a new `Localization.lang` entry
Add new `Localization.lang("KEY")` to a Java file. The tests will fail. In the test output a snippet is generated, which must be added to the English translation file.
Example:
```text
java.lang.AssertionError: DETECTED LANGUAGE KEYS WHICH ARE NOT IN THE ENGLISH LANGUAGE FILE
PASTE THESE INTO THE ENGLISH LANGUAGE FILE
[
Opens\ JabRef's\ Twitter\ page=Opens JabRef's Twitter page
]
Expected :[]
Actual :[Opens\ JabRef's\ Twitter\ page (src\main\java\org\jabref\gui\JabRefFrame.java LANG)]
```
Add the above snippet to the English translation file located at `src/main/resources/l10n/JabRef_en.properties`.
[Crowdin](https://crowdin.com/project/jabref) will automatically pick up the new string and add it to the other translations.
You can also directly run the specific test in your IDE.
The test "`LocalizationConsistencyTest`" is placed under `src/test/java/org.jabref.logic.l10n/LocalizationConsistencyTest.java`.
Find more information in the [JabRef developer docs](https://devdocs.jabref.org/code-howtos/localization.html).
#### **Format of keyboard shortcuts**
In Markdown files (e.g., `CHANGELOG.md`), sometimes keyboard shortcuts need to be added.
Example: `<kbd>Ctrl</kbd> + <kbd>Enter</kbd>`
In case you add keys to the changelog, please follow these rules:
* `<kbd>` tag for each key
* First letter of key capitalized
* Combined keys separated by `+`
* Spaces before and after separator `+`

9
jabref/GitVersion.yml Normal file
View File

@ -0,0 +1,9 @@
assembly-versioning-format: '{major}.{minor}.{WeightedPreReleaseNumber}'
assembly-informational-format: '{major}.{minor}{PreReleaseTagWithDash}--{CommitDate}--{ShortSha}'
mode: ContinuousDeployment
branches:
main:
regex: ^main
tag: ''
pre-release-weight: 0 # 0 after stable release, 15000 before alpha release, 30000 before beta release, 50000 before stable release

21
jabref/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright © 2003-2024 JabRef Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

7
jabref/MAINTAINERS Normal file
View File

@ -0,0 +1,7 @@
Oliver Kopp (since 2011)
Tobias Diez (since 2015)
Christoph Schwentker (since 2016)
Carl Christian Snethlage (since 2020)
Jonatan Asketorp (since 2021)
Thilo Ertel (since 2021)
Houssem Nasri (since 2023)

128
jabref/PRIVACY.md Normal file
View File

@ -0,0 +1,128 @@
# Privacy Policy
Last updated: 2024-08-06
Your privacy is a fundamental right JabRef e.V. respects and supports.
By using JabRef and its related online services, you choose to share some of your personal information.
In this Privacy Policy we explain how we collect, use, and share information about you, along with the choices you have.
The term 'Personal information' in this policy means any information that either directly identifies you or can be somehow linked to you. 'JabRef' refers to the desktop application that is provided by JabRef e.V.
Please remember that no method of transmission over the Internet, or method of electronic storage is absolute secure.
While we strive to use commercially acceptable means to protect your Personal Data, we cannot guarantee its absolute security.
Also, whenever you communicate through the internet, your IP-Address will always be transmitted and retained by third parties for technical and in some cases for legal reasons.
## JabRef Desktop Application
### Collecting information
JabRef does not collect any personal information directly linked to you.
However, on certain occasions JabRef will send some information to the online services of JabRef e.V.:
- On application start, JabRef will check for the latest version online (by default *enabled*).
- Information about a journal you are citing when looking for more information about this journal, using our journal database (by default *enabled*).
- A pdf document you automatically want to extract citation information from, using our GROBID service (by default *disabled*).
- Anonymized statistical data on the use of the graphical user interface for internal analysis purposes (by default *disabled*).
### Storing information
JabRef only stores the following personal information locally on your computer:
- Your proxy username and password, if you decide to store them (by default *disabled*).
- Any personal API key you use to access third party online services (by default *disabled*).
### Sharing information
Certain operations you perform in JabRef may trigger requests to public third-party services such as Zotero, Crossref or the Library of Congress for metadata retrieval.
These third parties may log additional information besides your IP address and the search terms (e.g., DOI, ISBN or the current URL) according to their privacy policies.
These third-party services are the following:
| Service | Privacy Policy |
|------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|
| [ACM](https://www.acm.org/) | <https://www.acm.org/privacy-policy> |
| [ACS Publications](https://pubs.acs.org/) | <https://www.acs.org/privacy.html> |
| [APS Advancing Physics](https://harvest.aps.org/) | <https://www.aps.org/about/privacy.cfm#privacy> |
| [arXiv.org](https://arxiv.org/) | <https://info.arxiv.org/help/policies/privacy_policy.html> |
| [Bibliotheksverbund Bayern](https://www.bib-bvb.de/) | <https://www.bib-bvb.de/web/guest/datenschutzerklaerung-bvb-homepage> |
| [Biodiversity Heritage Library](https://www.biodiversitylibrary.org/) | <https://www.si.edu/Privacy> |
| [Collection of Computer Science Bibliographies](https://en.wikipedia.org/wiki/Collection_of_Computer_Science_Bibliographies) | **currently unavailable**, offline |
| [CrossRef](https://www.crossref.org/) | <https://www.crossref.org/operations-and-sustainability/privacy/> |
| [dblp](https://dblp.uni-trier.de/) | <https://dblp.uni-trier.de/db/about/privacy.html> |
| [DJL (Deep Java Library)](https://djl.ai/) | <https://github.com/deepjavalibrary/djl/discussions/3370#discussioncomment-10233632> |
| [Directory of Open Access Books](https://www.doabooks.org/) | <https://www.doabooks.org/en/resources/accessibility> |
| [Digitala Vetenskapliga Arkivet](https://www.diva-portal.org/) | <https://www.uu.se/en/about-uu/data-protection-policy/> |
| [DOI Foundation](https://www.doi.org/) | <https://www.doi.org/privacy-policy/> |
| [Elsevier](https://www.elsevier.com/) | <https://www.elsevier.com/legal/privacy-policy> |
| [Google Gemini](https://ai.google.dev/gemini-api) | <https://ai.google.dev/gemini-api/terms> |
| [Google Scholar](https://scholar.google.com/) | <https://policies.google.com/privacy> |
| [Gemeinsamer Verbundkatalog](https://www.gbv.de/) | <https://www.gbv.de/datenschutz> |
| [Hugging Face](https://huggingface.co/) | <https://huggingface.co/privacy> |
| [IACR](https://www.iacr.org/) | <https://www.iacr.org/privacy.html> |
| [IEEEXplore](https://ieeexplore.ieee.org/Xplore/home.jsp) | <https://www.ieee.org/security-privacy.html> |
| [INSPIRE](https://inspirehep.net/) | <https://cern.service-now.com/service-portal?id=privacy_policy&se=INSPIRE-Online&notice=main> |
| [ISIDORE](https://isidore.science/) | <https://isidore.science/credit> |
| [JSTOR](https://www.jstor.org/) | <https://www.ithaka.org/privacypolicy/> |
| [Library of Congress](https://lccn.loc.gov/) | <https://www.loc.gov/legal/> |
| [Mistral AI](https://mistral.ai/) | <https://mistral.ai/terms/#privacy-policy> |
| [National Library of Medicine](https://www.ncbi.nlm.nih.gov/) | <https://www.nlm.nih.gov/web_policies.html> |
| [MathSciNet](http://www.ams.org/mathscinet) | <https://www.ams.org/about-us/privacy> |
| [mEDRA](https://www.medra.org/) | <https://www.medra.org/stdoc/en/Servizio_DOI_Informativa_ENG.pdf> |
| [Mr. DLib](https://mr-dlib.org/) [1] | <https://support.dataverse.harvard.edu/harvard-dataverse-privacy-policy> |
| [OpenAI](https://openai.com/) | <https://openai.com/policies/privacy-policy/> |
| [Openlibrary](https://openlibrary.org) | <https://archive.org/about/terms.php> |
| [ResearchGate](https://www.researchgate.net/) | <https://www.researchgate.net/privacy-policy> |
| [IETF Datatracker](https://datatracker.ietf.org/) | <https://www.ietf.org/privacy-statement/> |
| [Semantic Scholar](https://www.semanticscholar.org/), powered by [Allen Institute for AI](https://allenai.org/) | <https://allenai.org/privacy-policy> |
| [Springer Nature](https://dev.springernature.com/) | <https://dev.springernature.com/privacy-policy/> |
| [The SAO/NASA Astrophysics Data System](https://ui.adsabs.harvard.edu/) | <https://ui.adsabs.harvard.edu/help/privacy/> |
| [Unpaywall](https://unpaywall.org/) | <https://unpaywall.org/legal/privacy> |
| [zbMATH Open](https://www.zbmath.org) | <https://zbmath.org/privacy-policy/> |
[1]: *Note: The Mr. DLib service is used for the related articles tab in the entry editor and collects also your language, your browser and operating system (*disabled* by default).*
## JabRef Browser Extension
No personal data (like name, email address, billing address or credit card) is collected by the Browser Extension itself.
But be aware that the browser Extension uses Zotero services, where [Zotero's Privacy Policy](https://www.zotero.org/support/privacy) applies.
### Collecting information
When actively used, the extension has access to the current website and its content to process citation information. In particular, the following information is used:
- the url of the current website you are visiting,
- the content of the current website.
### Storing information
No data will be stored by the Browser Extension.
### Sharing information
The Browser Extension does not share any data except with the local instance of the JabRef software application, which stores the citation data as a new entry in its library.
## Links to other Websites
Our Service may contain links to other websites that are not operated by us. If you click on a third party link, you will be directed to that third party's site. We strongly advise you to review the Privacy Policy of every site you visit.
We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.
## Changes to this Privacy Policy
This privacy policy may be changed eventually.
We encourage you to check this Privacy Policy periodically for any changes.
Any material change will be mentioned in the changelog of the desktop application and in our [blog](https://blog.jabref.org/).
This privacy policy is in effect as of the day mentioned as "last updated" above and will remain in effect except with respect to any changes in its provisions in the future, which will be in effect immediately after being posted on this page.
## Contact
If you get in touch with us, we may ask you to provide us with certain personal information (e.g. name and email address) to stay in contact with you.
For any questions or concerns regarding the privacy policy, please send us an email to <vorstand@jabref.org> or write to
JabRef e.V.
Josef-Lanner-Str. 9
71069 Sindelfingen
Germany
<!-- markdownlint-disable-file MD024 -->

101
jabref/README.md Normal file
View File

@ -0,0 +1,101 @@
# JabRef Bibliography Management
JabRef is an open-source, cross-platform citation and reference management tool.
Stay on top of your literature: JabRef helps you to collect and organize sources, find the paper you need and discover the latest research.
![main table](docs/images/jabref-mainscreen.png)
## Features
JabRef is available free of charge and is actively developed.
It supports you in every step of your research work.
### Collect
- Search across many online scientific catalogues like CiteSeer, CrossRef, Google Scholar, IEEEXplore, INSPIRE-HEP, Medline PubMed, MathSciNet, Springer, arXiv, and zbMATH
- Import options for over 15 reference formats
- Easily retrieve and link full-text articles
- Fetch complete bibliographic information based on ISBN, DOI, PubMed-ID and arXiv-ID
- Extract metadata from PDFs
- Import new references directly from the browser with one click using the [official browser extension](https://github.com/JabRef/JabRef-Browser-Extension) for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/jabref/?src=external-github), [Chrome](https://chrome.google.com/webstore/detail/jabref-browser-extension/bifehkofibaamoeaopjglfkddgkijdlh), [Edge](https://microsoftedge.microsoft.com/addons/detail/pgkajmkfgbehiomipedjhoddkejohfna), and [Vivaldi](https://chrome.google.com/webstore/detail/jabref-browser-extension/bifehkofibaamoeaopjglfkddgkijdlh)
### Organize
- Group your research into hierarchical collections and organize research items based on keywords/tags, search terms, or your manual assignments
- Advanced search and filter features
- Complete and fix bibliographic data by comparing with curated online catalogs such as Google Scholar, Springer, or MathSciNet
- Customizable citation key generator
- Customize and add new metadata fields or reference types
- Find and merge duplicates
- Attach related documents: 20 different kinds of documents supported out of the box, completely customizable and extendable
- Automatically rename and move associated documents according to customizable rules
- Keep track of what you read: ranking, priority, printed, quality-assured
### Cite
- Native BibTeX and Biblatex support
- Cite-as-you-write functionality for external applications such as Emacs, Kile, LyX, Texmaker, TeXstudio, Vim and WinEdt.
- Format references using one of thousands of built-in citation styles or create your own style
- Support for Word and LibreOffice/OpenOffice for inserting and formatting citations
### Share
- Many built-in export options or create your export format
- Library is saved as a simple text file, and thus it is easy to share with others via Dropbox and is version-control friendly
- Work in a team: sync the contents of your library via a SQL database
## Installation
Fresh development builds are available at [builds.jabref.org](https://builds.jabref.org/main/).
The [latest stable release is available at FossHub](https://downloads.jabref.org/).
Please see our [Installation Guide](https://docs.jabref.org/installation).
## Bug Reports, Suggestions, Other Feedback
[![Donation](https://img.shields.io/badge/donate%20to-jabref-orange.svg)](https://donations.jabref.org)
[![PayPal Donate](https://img.shields.io/badge/donate-paypal-00457c.svg?logo=paypal&style=flat-square)](https://paypal.me/JabRef)
We are thankful for any bug reports or other feedback.
If you have ideas for new features you want to be included in JabRef, tell us in [the feature section](http://discourse.jabref.org/c/features) of our forum!
If you need support in using JabRef, please read [the documentation](https://docs.jabref.org/) first, the [frequently asked questions (FAQ)](https://docs.jabref.org/faq) and also have a look at our [community forum](https://discourse.jabref.org/c/help/7).
You can use our [GitHub issue tracker](https://github.com/JabRef/jabref/issues) to file bug reports.
An explanation of donation possibilities and usage of donations is available at our [donations page](https://donations.jabref.org).
## Contributing
[![dev-docs](https://img.shields.io/badge/dev-docs-blue)](https://devdocs.jabref.org/)
[![Help Contribute to Open Source](https://www.codetriage.com/jabref/jabref/badges/users.svg)](https://www.codetriage.com/jabref/jabref)
[![Join the chat at https://gitter.im/JabRef/jabref](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JabRef/jabref?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![OpenHub](https://www.openhub.net/p/jabref/widgets/project_thin_badge.gif)](https://www.openhub.net/p/jabref)
[![Deployment Status](https://github.com/JabRef/jabref/workflows/Deployment/badge.svg)](https://github.com/JabRef/jabref/actions?query=workflow%3ADeployment)
[![Test Status](https://github.com/JabRef/jabref/workflows/Tests/badge.svg)](https://github.com/JabRef/jabref/actions?query=workflow%3ATests)
[![codecov.io](https://codecov.io/github/JabRef/jabref/coverage.svg?branch=master)](https://codecov.io/github/JabRef/jabref?branch=main)
Want to be part of a free and open-source project that tens of thousands of scientists use every day?
Check out the ways you can contribute, below:
- Not a programmer? Help translating JabRef at [Crowdin](https://crowdin.com/project/jabref) or learn how to help at [contribute.jabref.org](https://contribute.jabref.org)
- Quick overview on the architecture needed? Look at our [high-level documentation](https://devdocs.jabref.org/getting-into-the-code/high-level-documentation)
- For details on how to contribute, have a look at our [guidelines for contributing](CONTRIBUTING.md).
- You are welcome to contribute new features. To get your code included into JabRef, just [fork](https://help.github.com/en/articles/fork-a-repo) the JabRef repository, make your changes, and create a [pull request](https://help.github.com/en/articles/about-pull-requests).
- To work on existing JabRef issues, check out our [issue tracker](https://github.com/JabRef/jabref/issues). New to open source contributing? Look for issues with the ["good first issue"](https://github.com/JabRef/jabref/labels/good%20first%20issue) label to get started.
Please follow our [step-by-step guide on how to set-up your workspace](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace).
We use [GitHub Actions](https://github.com/JabRef/jabref/actions) for executing the tests after each commit.
For developing, it is sufficient to locally only run the associated test for the classes you changed.
GitHub will report any other failure.
We view pull requests as a collaborative process.
Submit a pull request early to get feedback from the team on work in progress.
We will discuss improvements with you and agree to merge them once the [developers](https://github.com/JabRef/jabref/blob/main/MAINTAINERS) approve.
Please also remember to discuss bigger changes early with the core developers to ensure properly spend time and work.
Some fundamental design decisions can be found within our list of [Architectural Decision Records](https://devdocs.jabref.org/decisions/).
## Sponsoring
JabRef development is powered by YourKit Java Profiler
[![YourKit Java Profiler](https://www.yourkit.com/images/yk_logo.svg)](https://www.yourkit.com/java/profiler/)

955
jabref/build.gradle Normal file
View File

@ -0,0 +1,955 @@
import org.gradle.internal.os.OperatingSystem
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
import org.jabref.build.xjc.XjcPlugin
import org.jabref.build.xjc.XjcTask
plugins {
id 'application'
id 'com.github.andygoossens.modernizer' version '1.10.0'
id 'me.champeau.jmh' version '0.7.2'
// This is https://github.com/java9-modularity/gradle-modules-plugin/pull/282
id 'com.github.koppor.gradle-modules-plugin' version 'v1.8.15-cmd-1'
id 'org.openjfx.javafxplugin' version '0.1.0'
id 'org.beryx.jlink' version '3.1.0-rc-1'
// nicer test outputs during running and completion
// Homepage: https://github.com/radarsh/gradle-test-logger-plugin
id 'com.adarshr.test-logger' version '4.0.0'
id 'jacoco'
id 'checkstyle'
id 'project-report'
id 'idea'
id 'org.openrewrite.rewrite' version '6.27.0'
id "org.itsallcode.openfasttrace" version "3.0.1"
}
// Enable following for debugging
// gradle.startParameter.showStacktrace = org.gradle.api.logging.configuration.ShowStacktrace.
apply plugin: XjcPlugin
apply from: 'eclipse.gradle'
group = "org.jabref"
version = project.findProperty('projVersion') ?: '100.0.0'
java {
sourceCompatibility = JavaVersion.VERSION_23
targetCompatibility = JavaVersion.VERSION_23
// Workaround needed for Eclipse, probably because of https://github.com/gradle/gradle/issues/16922
// Should be removed as soon as Gradle 7.0.1 is released ( https://github.com/gradle/gradle/issues/16922#issuecomment-828217060 )
modularity.inferModulePath.set(false)
toolchain {
// If this is updated, also update
// - .gitpod.Dockerfile
// - .devcontainer/devcontainer.json#L34 and
// - .github/workflows/deployment*.yml
// - .github/workflows/tests*.yml
// - .github/workflows/update-gradle-wrapper.yml
// - docs/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-12-build.md
// - build.gradle -> jacoco -> toolVersion (because JaCoCo does not support newest JDK out of the box. Check versions at https://www.jacoco.org/jacoco/trunk/doc/changes.html)
languageVersion = JavaLanguageVersion.of(23)
// See https://docs.gradle.org/current/javadoc/org/gradle/jvm/toolchain/JvmVendorSpec.html for a full list
// vendor = JvmVendorSpec.AMAZON
}
}
application {
mainClass.set('org.jabref.Launcher')
mainModule.set('org.jabref')
applicationDefaultJvmArgs = [
// On a change here, also adapt
// 1. "run > moduleOptions"
// 2. "deployment.yml" (macOS part)
// 3. "deployment-arm64.yml"
// Note that the arguments are cleared for the "run" task to avoid messages like "WARNING: Unknown module: org.jabref.merged.module specified to --add-exports"
// Fix for https://github.com/JabRef/jabref/issues/11188
'--add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module',
'--add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module',
// Fix for https://github.com/JabRef/jabref/issues/11198
'--add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module',
'--add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module',
'--add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module',
// fix for https://github.com/JabRef/jabref/issues/11426
'--add-opens=javafx.controls/javafx.scene.control.skin=org.jabref.merged.module',
// Fix for https://github.com/JabRef/jabref/issues/11225 on linux
'--add-opens=javafx.controls/javafx.scene.control=org.jabref',
'--add-exports=javafx.base/com.sun.javafx.event=org.jabref',
'--add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref',
'--add-opens=javafx.graphics/javafx.scene=org.jabref',
'--add-opens=javafx.controls/javafx.scene.control=org.jabref',
'--add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref',
'--add-opens=javafx.base/javafx.collections=org.jabref',
'--add-opens=javafx.base/javafx.collections.transformation=org.jabref'
]
}
// Workaround for https://github.com/openjfx/javafx-gradle-plugin/issues/89
// See also https://github.com/java9-modularity/gradle-modules-plugin/issues/165
modularity.disableEffectiveArgumentsAdjustment()
sourceSets {
main {
java {
// src-gen reasoning: https://stackoverflow.com/a/64612308/873282
srcDirs = ["src/main/java", "src-gen/main/java"]
}
resources {
srcDirs = ["src/main/java", "src/main/resources"]
}
}
test {
java {
srcDirs = ["src/test/java"]
}
resources {
srcDirs = ["src/test/resources"]
}
}
}
repositories {
mavenCentral()
maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url 'https://jitpack.io' }
maven { url 'https://oss.sonatype.org/content/groups/public' }
// Required for one.jpro.jproutils:tree-showing
maven { url 'https://sandec.jfrog.io/artifactory/repo' }
}
configurations {
antlr4
}
dependencyLocking {
lockAllConfigurations()
}
javafx {
version = "23.0.1"
modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.swing' ]
}
jacoco {
toolVersion = "0.8.13-SNAPSHOT"
}
dependencies {
// Include all jar-files in the 'lib' folder as dependencies
implementation fileTree(dir: 'lib', includes: ['*.jar'])
def pdfbox = "3.0.3"
implementation ("org.apache.pdfbox:pdfbox:$pdfbox") {
exclude group: 'commons-logging'
}
implementation ("org.apache.pdfbox:fontbox:$pdfbox") {
exclude group: 'commons-logging'
}
implementation ("org.apache.pdfbox:xmpbox:$pdfbox") {
exclude group: 'org.junit.jupiter'
exclude group: 'commons-logging'
}
def luceneVersion = "10.0.0"
implementation "org.apache.lucene:lucene-core:$luceneVersion"
implementation "org.apache.lucene:lucene-queryparser:$luceneVersion"
implementation "org.apache.lucene:lucene-queries:$luceneVersion"
implementation "org.apache.lucene:lucene-analysis-common:$luceneVersion"
implementation "org.apache.lucene:lucene-highlighter:$luceneVersion"
implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.12.0'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0'
implementation group: 'org.apache.commons', name: 'commons-text', version: '1.12.0'
implementation 'commons-logging:commons-logging:1.3.4'
implementation 'com.h2database:h2-mvstore:2.3.232'
// required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635
implementation 'org.bouncycastle:bcprov-jdk18on:1.79'
implementation 'commons-cli:commons-cli:1.9.0'
// region: LibreOffice
implementation 'org.libreoffice:unoloader:24.2.3'
implementation 'org.libreoffice:libreoffice:24.2.3'
// Required for ID generation
implementation 'io.github.thibaultmeyer:cuid:2.0.3'
// endregion
implementation 'io.github.java-diff-utils:java-diff-utils:4.12'
implementation 'info.debatty:java-string-similarity:2.0.0'
implementation 'com.github.javakeyring:java-keyring:1.0.4'
antlr4 'org.antlr:antlr4:4.13.2'
implementation 'org.antlr:antlr4-runtime:4.13.2'
implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '7.0.0.202409031743-r'
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.18.1'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.18.1'
implementation 'com.fasterxml:aalto-xml:1.3.3'
implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.9'
implementation 'org.postgresql:postgresql:42.7.4'
// Support unix socket connection types
implementation 'com.kohlschutter.junixsocket:junixsocket-core:2.10.1'
implementation 'com.kohlschutter.junixsocket:junixsocket-mysql:2.10.1'
implementation ('com.oracle.ojdbc:ojdbc10:19.3.0.0') {
// causing module issues
exclude module: 'oraclepki'
}
implementation ('com.google.guava:guava:33.1.0-jre') {
// TODO: Remove this as soon as https://github.com/google/guava/issues/2960 is fixed
exclude module: "jsr305"
}
implementation 'jakarta.annotation:jakarta.annotation-api:2.1.1'
implementation 'jakarta.inject:jakarta.inject-api:2.0.1'
implementation('org.jabref:afterburner.fx:2.0.0') {
exclude group: 'org.openjfx'
}
implementation 'org.kordamp.ikonli:ikonli-javafx:12.3.1'
implementation 'org.kordamp.ikonli:ikonli-materialdesign2-pack:12.3.1'
implementation 'com.github.sialcasa.mvvmFX:mvvmfx-validation:f195849ca9' //jitpack
implementation 'de.saxsys:mvvmfx:1.8.0'
implementation('org.jabref:easybind:2.2.1-SNAPSHOT') {
exclude group: 'org.openjfx'
}
implementation 'org.fxmisc.flowless:flowless:0.7.3'
implementation 'org.fxmisc.richtext:richtextfx:0.11.3'
implementation (group: 'com.dlsc.gemsfx', name: 'gemsfx', version: '2.64.0') {
exclude module: 'javax.inject' // Split package, use only jakarta.inject
exclude module: 'commons-lang3'
exclude group: 'org.apache.commons.validator'
exclude group: 'org.apache.commons.commons-logging'
exclude module: 'kotlin-stdlib-jdk8'
exclude group: 'com.squareup.retrofit2'
exclude group: 'org.openjfx'
exclude group: 'org.apache.logging.log4j'
exclude group: 'tech.units'
}
// Required by gemsfx
implementation 'tech.units:indriya:2.2'
// Required by gemsfx and langchain4j
implementation ('com.squareup.retrofit2:retrofit:2.11.0') {
exclude group: 'com.squareup.okhttp3'
}
implementation 'org.controlsfx:controlsfx:11.2.1'
// region HTTP clients
implementation 'org.jsoup:jsoup:1.18.1'
implementation 'com.konghq:unirest-java-core:4.4.4'
implementation 'com.konghq:unirest-modules-gson:4.4.5'
implementation 'org.apache.httpcomponents.client5:httpclient5:5.4'
// endregion
implementation 'org.slf4j:slf4j-api:2.0.16'
implementation 'org.tinylog:tinylog-api:2.7.0'
implementation 'org.tinylog:slf4j-tinylog:2.7.0'
implementation 'org.tinylog:tinylog-impl:2.7.0'
// route all requests to java.util.logging to SLF4J (which in turn routes to tinylog)
implementation 'org.slf4j:jul-to-slf4j:2.0.16'
// route all requests to log4j to SLF4J
implementation 'org.apache.logging.log4j:log4j-to-slf4j:2.24.1'
implementation('de.undercouch:citeproc-java:3.1.0') {
exclude group: 'org.antlr'
}
// jakarta.activation is already dependency of glassfish
implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '4.0.2'
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '4.0.3'
implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') {
exclude module: 'fastparse_2.13'
}
implementation "de.rototor.snuggletex:snuggletex:1.3.0"
implementation ("de.rototor.snuggletex:snuggletex-jeuclid:1.3.0") {
exclude group: "org.apache.xmlgraphics"
}
implementation 'com.vladsch.flexmark:flexmark:0.64.8'
implementation 'com.vladsch.flexmark:flexmark-html2md-converter:0.64.8'
implementation group: 'net.harawata', name: 'appdirs', version: '1.2.2'
implementation group: 'org.jooq', name: 'jool', version: '0.9.15'
// JAX-RS implemented by Jersey
// API
implementation 'jakarta.ws.rs:jakarta.ws.rs-api:4.0.0'
// Implementation of the API
implementation 'org.glassfish.jersey.core:jersey-server:3.1.9'
// injection framework
implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.9'
implementation 'org.glassfish.hk2:hk2-api:3.1.1'
// testImplementation 'org.glassfish.hk2:hk2-testing:3.0.4'
// implementation 'org.glassfish.hk2:hk2-testing-jersey:3.0.4'
// testImplementation 'org.glassfish.hk2:hk2-junitrunner:3.0.4'
// HTTP server
// implementation 'org.glassfish.jersey.containers:jersey-container-netty-http:3.1.1'
implementation 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:3.1.9'
testImplementation 'org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:3.1.9'
// Allow objects "magically" to be mapped to JSON using GSON
// implementation 'org.glassfish.jersey.media:jersey-media-json-gson:3.1.1'
// Because of GraalVM quirks, we need to ship that. See https://github.com/jspecify/jspecify/issues/389#issuecomment-1661130973 for details
implementation 'org.jspecify:jspecify:1.0.0'
// parse plist files
implementation 'com.googlecode.plist:dd-plist:1.28'
// Parse lnk files
implementation 'com.github.vatbub:mslinks:1.0.6.2'
// YAML formatting
implementation 'org.yaml:snakeyaml:2.3'
// region AI
implementation 'dev.langchain4j:langchain4j:0.35.0'
// Even though we use jvm-openai for LLM connection, we still need this package for tokenization.
implementation('dev.langchain4j:langchain4j-open-ai:0.35.0') {
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
exclude group: 'org.jetbrains.kotlin'
}
implementation('dev.langchain4j:langchain4j-mistral-ai:0.35.0') {
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
exclude group: 'org.jetbrains.kotlin'
}
implementation('dev.langchain4j:langchain4j-google-ai-gemini:0.35.0') {
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
}
implementation('dev.langchain4j:langchain4j-hugging-face:0.35.0') {
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
exclude group: 'org.jetbrains.kotlin'
}
implementation 'org.apache.velocity:velocity-engine-core:2.4.1'
implementation platform('ai.djl:bom:0.30.0')
implementation 'ai.djl:api'
implementation 'ai.djl.huggingface:tokenizers'
implementation 'ai.djl.pytorch:pytorch-model-zoo'
implementation 'io.github.stefanbratanov:jvm-openai:0.11.0'
// openai depends on okhttp, which needs kotlin - see https://github.com/square/okhttp/issues/5299 for details
implementation ('com.squareup.okhttp3:okhttp:4.12.0') {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
// GemxFX also (transitively) depends on kotlin
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21'
// endregion
implementation 'commons-io:commons-io:2.17.0'
// Even if "compileOnly" is used, IntelliJ always adds to module-info.java. To avoid issues during committing, we use "implementation" instead of "compileOnly"
implementation 'io.github.adr:e-adr:2.0.0-SNAPSHOT'
implementation 'io.zonky.test:embedded-postgres:2.0.7'
implementation enforcedPlatform('io.zonky.test.postgres:embedded-postgres-binaries-bom:17.0.0')
testImplementation 'io.github.classgraph:classgraph:4.8.177'
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0'
testImplementation 'org.junit.platform:junit-platform-launcher:1.10.3'
testImplementation 'org.mockito:mockito-core:5.14.2'
testImplementation 'org.xmlunit:xmlunit-core:2.10.0'
testImplementation 'org.xmlunit:xmlunit-matchers:2.10.0'
testRuntimeOnly 'com.tngtech.archunit:archunit-junit5-engine:1.3.0'
testImplementation 'com.tngtech.archunit:archunit-junit5-api:1.3.0'
testImplementation "org.testfx:testfx-core:4.0.16-alpha"
testImplementation "org.testfx:testfx-junit5:4.0.16-alpha"
testImplementation "org.hamcrest:hamcrest-library:3.0"
testImplementation "com.github.javaparser:javaparser-symbol-solver-core:3.26.2"
// recommended by https://github.com/wiremock/wiremock/issues/2149#issuecomment-1835775954
testImplementation 'org.wiremock:wiremock-standalone:3.3.1'
checkstyle 'com.puppycrawl.tools:checkstyle:10.20.1'
// xjc needs the runtime as well for the ant task, otherwise it fails
xjc group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: '3.0.2'
xjc group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2'
rewrite(platform("org.openrewrite.recipe:rewrite-recipe-bom:2.19.0"))
rewrite("org.openrewrite.recipe:rewrite-static-analysis")
rewrite("org.openrewrite.recipe:rewrite-logging-frameworks")
rewrite("org.openrewrite.recipe:rewrite-testing-frameworks")
rewrite("org.openrewrite.recipe:rewrite-migrate-java")
configurations.checkstyle {
resolutionStrategy.capabilitiesResolution.withCapability("com.google.collections:google-collections") {
select("com.google.guava:guava:0")
}
}
configurations
.matching(c -> c.name.contains("downloadSources"))
.configureEach {
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
attribute(OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE, objects.named(OperatingSystemFamily, DefaultNativePlatform.getCurrentOperatingSystem().getName()))
attribute(MachineArchitecture.ARCHITECTURE_ATTRIBUTE, objects.named(MachineArchitecture, DefaultNativePlatform.getCurrentArchitecture().getName()))
}
}
}
clean {
delete "src/main/generated"
delete "src-gen"
}
processResources {
filteringCharset = 'UTF-8'
filesMatching("build.properties") {
expand(version: project.findProperty('projVersionInfo') ?: '100.0.0',
"year": String.valueOf(Calendar.getInstance().get(Calendar.YEAR)),
"maintainers": new File('MAINTAINERS').readLines().findAll { !it.startsWith("#") }.join(", "),
"azureInstrumentationKey": System.getenv('AzureInstrumentationKey') ? System.getenv('AzureInstrumentationKey') : '',
"springerNatureAPIKey": System.getenv('SpringerNatureAPIKey') ? System.getenv('SpringerNatureAPIKey') : '',
"astrophysicsDataSystemAPIKey": System.getenv('AstrophysicsDataSystemAPIKey') ? System.getenv('AstrophysicsDataSystemAPIKey') : '',
"ieeeAPIKey": System.getenv('IEEEAPIKey') ? System.getenv('IEEEAPIKey') : '',
"scienceDirectApiKey": System.getenv('SCIENCEDIRECTAPIKEY') ? System.getenv('SCIENCEDIRECTAPIKEY') : '',
"biodiversityHeritageApiKey": System.getenv('BiodiversityHeritageApiKey') ? System.getenv('BiodiversityHeritageApiKey') : '',
"semanticScholarApiKey": System.getenv('SemanticScholarApiKey') ? System.getenv("SemanticScholarApiKey") : ''
)
filteringCharset = 'UTF-8'
}
filesMatching(["resources/resource/ods/meta.xml", "resources/resource/openoffice/meta.xml"]) {
expand version: project.version
}
}
tasks.register('generateSource') {
dependsOn("generateBstGrammarSource",
"generateSearchGrammarSource",
"generateCitaviSource")
group = 'JabRef'
description 'Generates all necessary (Java) source files.'
}
tasks.register("generateBstGrammarSource", JavaExec) {
group = "JabRef"
description = 'Generates BstLexer.java and BstParser.java from the Bst.g grammar file using antlr4.'
classpath = configurations.antlr4
mainClass = "org.antlr.v4.Tool"
javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
inputs.dir('src/main/antlr4/org/jabref/bst/')
outputs.dir("src-gen/main/java/org/jabref/logic/bst/")
args = ["-o", "src-gen/main/java/org/jabref/logic/bst/", "-visitor", "-no-listener", "-package", "org.jabref.logic.bst", "$projectDir/src/main/antlr4/org/jabref/bst/Bst.g4"]
}
tasks.register("generateSearchGrammarSource", JavaExec) {
group = 'JabRef'
description = "Generates java files for Search.g antlr4."
classpath = configurations.antlr4
mainClass = "org.antlr.v4.Tool"
javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
inputs.dir("src/main/antlr4/org/jabref/search/")
outputs.dir("src-gen/main/java/org/jabref/search/")
args = ["-o","src-gen/main/java/org/jabref/search" , "-visitor", "-no-listener", "-package", "org.jabref.search", "$projectDir/src/main/antlr4/org/jabref/search/Search.g4"]
}
tasks.register("generateJournalListMV", JavaExec) {
group = "JabRef"
description = "Converts the comma-separated journal abbreviation file to a H2 MVStore"
classpath = sourceSets.main.runtimeClasspath
mainClass = "org.jabref.cli.JournalListMvGenerator"
javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
onlyIf {
!file("build/resources/main/journals/journal-list.mv").exists()
}
}
jar.dependsOn("generateJournalListMV")
compileTestJava.dependsOn("generateJournalListMV")
tasks.register('generateCitaviSource', XjcTask) {
group = 'JabRef'
description = "Generates java files for the citavi importer."
schemaFile = "src/main/resources/xjc/citavi/citavi.xsd"
outputDirectory = "src-gen/main/java/"
javaPackage = "org.jabref.logic.importer.fileformat.citavi"
}
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
// hint by https://docs.gradle.org/current/userguide/performance.html#run_the_compiler_as_a_separate_process
options.fork = true
}
compileJava {
options.compilerArgs << "-Xlint:none"
dependsOn "generateSource"
options.generatedSourceOutputDirectory.set(file("src-gen/main/java"))
moduleOptions {
addExports = [
// TODO: Remove access to internal api
'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
'org.controlsfx.controls/impl.org.controlsfx.skin' : 'org.jabref'
]
}
}
// Configures "application > run" task
run {
doFirst {
// Clear the default JVM arguments, to avoid messages like "WARNING: Unknown module: org.jabref.merged.module specified to --add-exports"
application.applicationDefaultJvmArgs = []
}
moduleOptions {
// On a change here, also adapt "application > applicationDefaultJvmArgs"
addExports = [
// TODO: Remove access to internal api
'javafx.base/com.sun.javafx.event' : 'org.jabref.merged.module',
'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
// We need to restate the ControlsFX exports, because we get following error otherwise:
// java.lang.IllegalAccessError:
// class org.controlsfx.control.textfield.AutoCompletionBinding (in module org.controlsfx.controls)
// cannot access class com.sun.javafx.event.EventHandlerManager (in module javafx.base) because
// module javafx.base does not export com.sun.javafx.event to module org.controlsfx.controls
// Taken from here: https://github.com/controlsfx/controlsfx/blob/9.0.0/build.gradle#L1
'javafx.graphics/com.sun.javafx.scene' : 'org.controlsfx.controls',
'javafx.graphics/com.sun.javafx.scene.traversal' : 'org.controlsfx.controls',
'javafx.graphics/com.sun.javafx.css' : 'org.controlsfx.controls',
'javafx.controls/com.sun.javafx.scene.control' : 'org.controlsfx.controls',
'javafx.controls/com.sun.javafx.scene.control.behavior' : 'org.controlsfx.controls',
'javafx.controls/com.sun.javafx.scene.control.inputmap' : 'org.controlsfx.controls',
'javafx.base/com.sun.javafx.event' : 'org.controlsfx.controls',
'javafx.base/com.sun.javafx.collections' : 'org.controlsfx.controls',
'javafx.base/com.sun.javafx.runtime': 'org.controlsfx.controls',
'javafx.web/com.sun.webkit' : 'org.controlsfx.controls',
]
addOpens = [
'javafx.controls/javafx.scene.control' : 'org.jabref',
'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
'org.controlsfx.controls/impl.org.controlsfx.skin' : 'org.jabref',
'org.controlsfx.controls/org.controlsfx.control.textfield' : 'org.jabref',
'javafx.controls/javafx.scene.control.skin' : 'org.controlsfx.controls',
'javafx.graphics/javafx.scene' : 'org.controlsfx.controls',
'javafx.base/javafx.collections' : 'org.jabref',
'javafx.base/javafx.collections.transformation' : 'org.jabref'
]
addModules = [
'jdk.incubator.vector'
]
createCommandLineArgumentFile = true
}
if (project.hasProperty('component')){
if (component == 'httpserver'){
main = 'org.jabref.http.server.Server'
}
}
}
javadoc {
options {
encoding = 'UTF-8'
version = false
author = false
addMultilineStringsOption("-add-exports").setValue([
'javafx.controls/com.sun.javafx.scene.control=org.jabref'
])
}
}
test {
useJUnitPlatform {
excludeTags 'DatabaseTest', 'FetcherTest', 'GUITest'
}
moduleOptions {
// TODO: Remove this as soon as ArchUnit is modularized
runOnClasspath = true
}
}
testlogger {
// See https://github.com/radarsh/gradle-test-logger-plugin#configuration for configuration options
theme 'standard'
showPassed false
showSkipped false
showCauses false
showStackTraces false
}
tasks.withType(Test).configureEach {
reports.html.outputLocation.set(file("${reporting.baseDir}/${name}"))
// Enable parallel tests (on desktop).
// See https://docs.gradle.org/8.1/userguide/performance.html#execute_tests_in_parallel for details.
if (!providers.environmentVariable("CI").isPresent()) {
maxParallelForks = Math.max(Runtime.runtime.availableProcessors() - 1, 1)
}
}
tasks.register('databaseTest', Test) {
useJUnitPlatform {
includeTags 'DatabaseTest'
}
testLogging {
// set options for log level LIFECYCLE
events = ["FAILED"]
exceptionFormat "full"
}
maxParallelForks = 1
}
tasks.register('fetcherTest', Test) {
useJUnitPlatform {
includeTags 'FetcherTest'
}
maxParallelForks = 1
}
tasks.register('guiTest', Test) {
useJUnitPlatform {
includeTags 'GUITest'
}
testLogging {
// set options for log level LIFECYCLE
events = ["FAILED"]
exceptionFormat "full"
}
maxParallelForks = 1
}
// Test result tasks
tasks.register('copyTestResources', Copy) {
from "${projectDir}/src/test/resources"
into "${buildDir}/classes/test"
}
processTestResources.dependsOn copyTestResources
tasks.register('jacocoPrepare') {
doFirst {
// Ignore failures of tests
tasks.withType(Test).tap {
configureEach {
ignoreFailures = true
}
}
}
}
test.mustRunAfter jacocoPrepare
databaseTest.mustRunAfter jacocoPrepare
fetcherTest.mustRunAfter jacocoPrepare
jacocoTestReport {
dependsOn jacocoPrepare, test, fetcherTest, databaseTest
executionData files(
layout.buildDirectory.file('jacoco/test.exec').get().asFile,
layout.buildDirectory.file('jacoco/fetcherTest.exec').get().asFile,
layout.buildDirectory.file('jacoco/databaseTest.exec').get().asFile)
reports {
csv.required = true
html.required = true
// coveralls plugin depends on xml format report
xml.required = true
}
}
// Code quality tasks
checkstyle {
// will only run when called explicitly from the command line
sourceSets = []
}
rewrite {
activeRecipe(
'org.jabref.config.rewrite.cleanup'
)
exclusion (
"build.gradle",
"buildSrc/build.gradle",
"eclipse.gradle",
"settings.gradle",
"src-gen/**",
"src/main/resources/**",
"src/test/resources/**",
"**/module-info.java",
"**/*.py",
"**/*.xml",
"**/*.yml"
)
plainTextMask("**/*.md")
failOnDryRunResults = true
}
modernizer {
failOnViolations = false
includeTestClasses = true
exclusions = [
'java/util/Optional.get:()Ljava/lang/Object;'
]
}
// Release tasks
tasks.register('deleteInstallerTemp', Delete) {
delete "$buildDir/installer"
}
jpackage.dependsOn deleteInstallerTemp
jlinkZip.dependsOn jpackage
jlink {
// https://github.com/beryx/badass-jlink-plugin/issues/61#issuecomment-504640018
addExtraDependencies("javafx")
addOptions('--strip-debug', '--compress', 'zip-6', '--no-header-files', '--no-man-pages')
launcher {
name = 'JabRef'
}
addOptions("--bind-services")
// TODO: Remove the following as soon as the dependencies are fixed (upstream)
// forceMerge is usually needed when some non-modular artifacts in the dependency graph use code that was previously part of the JDK
// but it was removed in the newer releases.
// The pom.xml associated with such a non-modular artifact does not mention that the artifact depends on the removed code
// (because the artifact was published when this code was still available in the JDK).
forceMerge "controlsfx", "bcprov", "jaxb", "istack", "stax"
// TODO: Remove the following correction to the merged module
// The module descriptor automatically generated by the plugin for the merged module contained some invalid entries.
// This is based on ./gradlew suggestMergedModuleInfo, sort, strip ";"", remove non-used modules, and include the suggested directives here.
mergedModule {
requires 'com.google.gson'
requires 'com.fasterxml.jackson.annotation'
requires 'com.fasterxml.jackson.databind'
requires 'com.fasterxml.jackson.core'
requires 'com.fasterxml.jackson.datatype.jdk8'
requires 'jakarta.xml.bind'
requires 'java.compiler'
requires 'java.datatransfer'
requires 'java.desktop'
requires 'java.logging'
requires 'java.management'
requires 'java.naming'
requires 'java.net.http'
requires 'java.rmi'
requires 'java.scripting'
requires 'java.security.jgss'
requires 'java.security.sasl'
requires 'java.sql'
requires 'java.sql.rowset'
requires 'java.transaction.xa'
requires 'java.xml'
requires 'javafx.base'
requires 'javafx.controls'
requires 'javafx.fxml'
requires 'javafx.graphics'
requires 'javafx.media'
requires 'javafx.swing'
requires 'jdk.jsobject'
requires 'jdk.security.jgss'
requires 'jdk.unsupported'
requires 'jdk.unsupported.desktop'
requires 'jdk.xml.dom'
requires 'org.apache.commons.lang3'
requires 'org.apache.commons.logging'
requires 'org.apache.commons.text'
requires 'org.apache.commons.codec'
requires 'org.apache.commons.io'
requires 'org.apache.commons.compress'
requires 'org.freedesktop.dbus'
requires 'org.jsoup'
requires 'org.slf4j'
requires 'org.tukaani.xz';
uses 'ai.djl.engine.EngineProvider'
uses 'ai.djl.repository.RepositoryFactory'
uses 'ai.djl.repository.zoo.ZooProvider'
uses 'dev.langchain4j.spi.prompt.PromptTemplateFactory'
uses 'kong.unirest.core.json.JsonEngine'
uses 'org.eclipse.jgit.lib.Signer'
uses 'org.eclipse.jgit.transport.SshSessionFactory'
uses 'org.mariadb.jdbc.LocalInfileInterceptor'
uses 'org.mariadb.jdbc.authentication.AuthenticationPlugin'
uses 'org.mariadb.jdbc.credential.CredentialPlugin'
uses 'org.mariadb.jdbc.tls.TlsSocketPlugin'
uses 'org.postgresql.shaded.com.ongres.stringprep.Profile'
provides 'org.mariadb.jdbc.tls.TlsSocketPlugin' with 'org.mariadb.jdbc.internal.protocol.tls.DefaultTlsSocketPlugin'
provides 'java.sql.Driver' with 'org.postgresql.Driver'
provides 'org.mariadb.jdbc.authentication.AuthenticationPlugin' with 'org.mariadb.jdbc.internal.com.send.authentication.CachingSha2PasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.ClearPasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.Ed25519PasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.NativePasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.OldPasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.SendGssApiAuthPacket',
'org.mariadb.jdbc.internal.com.send.authentication.SendPamAuthPacket',
'org.mariadb.jdbc.internal.com.send.authentication.Sha256PasswordPlugin'
provides 'org.mariadb.jdbc.credential.CredentialPlugin' with 'org.mariadb.jdbc.credential.aws.AwsIamCredentialPlugin',
'org.mariadb.jdbc.credential.env.EnvCredentialPlugin',
'org.mariadb.jdbc.credential.system.PropertiesCredentialPlugin'
provides 'java.security.Provider' with 'org.bouncycastle.jce.provider.BouncyCastleProvider',
'org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider'
provides 'kong.unirest.core.json.JsonEngine' with 'kong.unirest.modules.gson.GsonEngine';
provides 'ai.djl.repository.zoo.ZooProvider' with 'ai.djl.engine.rust.zoo.RsZooProvider',
'ai.djl.huggingface.zoo.HfZooProvider',
'ai.djl.pytorch.zoo.PtZooProvider',
'ai.djl.repository.zoo.DefaultZooProvider';
provides 'ai.djl.engine.EngineProvider' with 'ai.djl.engine.rust.RsEngineProvider',
'ai.djl.pytorch.engine.PtEngineProvider';
}
jpackage {
outputDir = "distribution"
if (OperatingSystem.current().isWindows()) {
// This requires WiX to be installed: https://github.com/wixtoolset/wix3/releases
installerType = "msi"
imageOptions = [
'--icon', "${projectDir}/src/main/resources/icons/jabref.ico",
]
installerOptions = [
'--vendor', 'JabRef',
'--app-version', "${project.version}",
'--verbose',
'--win-upgrade-uuid', 'd636b4ee-6f10-451e-bf57-c89656780e36',
'--win-dir-chooser',
'--win-shortcut',
'--win-menu',
'--win-menu-group', "JabRef",
'--temp', "$buildDir/installer",
'--resource-dir', "${projectDir}/buildres/windows",
'--license-file', "${projectDir}/buildres/LICENSE_with_Privacy.md",
'--file-associations', "${projectDir}/buildres/windows/bibtexAssociations.properties"
]
}
if (OperatingSystem.current().isLinux()) {
imageOptions = [
'--icon', "${projectDir}/src/main/resources/icons/JabRef-icon-64.png",
'--app-version', "${project.version}",
]
installerOptions = [
'--verbose',
'--vendor', 'JabRef',
'--app-version', "${project.version}",
// '--temp', "$buildDir/installer",
'--resource-dir', "${projectDir}/buildres/linux",
'--linux-menu-group', 'Office;',
'--linux-rpm-license-type', 'MIT',
// '--license-file', "${projectDir}/LICENSE.md",
'--description', 'JabRef is an open source bibliography reference manager. The native file format used by JabRef is BibTeX, the standard LaTeX bibliography format.',
'--linux-shortcut',
'--file-associations', "${projectDir}/buildres/linux/bibtexAssociations.properties"
]
}
if (OperatingSystem.current().isMacOsX()) {
imageOptions = [
'--icon', "${projectDir}/src/main/resources/icons/jabref.icns",
'--resource-dir', "${projectDir}/buildres/mac"
]
// Notarized mac images and packages are built on the pipeline only
skipInstaller = true
installerOptions = [
'--verbose',
'--vendor', 'JabRef',
'--mac-package-identifier', "JabRef",
'--mac-package-name', "JabRef",
'--app-version', "${project.version}",
'--file-associations', "${projectDir}/buildres/mac/bibtexAssociations.properties",
'--resource-dir', "${projectDir}/buildres/mac"
]
}
}
}
if (OperatingSystem.current().isWindows()) {
tasks.jpackageImage.doLast {
copy {
from("${projectDir}/buildres/windows") {
include "jabref-firefox.json", "jabref-chrome.json", "JabRefHost.bat", "JabRefHost.ps1"
}
into "$buildDir/distribution/JabRef"
}
}
}
if (OperatingSystem.current().isLinux()) {
tasks.jpackageImage.doLast {
copy {
from("${projectDir}/buildres/linux") {
include "native-messaging-host/**", "jabrefHost.py"
}
into "$buildDir/distribution/JabRef/lib"
}
}
}
if (OperatingSystem.current().isMacOsX()) {
tasks.jpackageImage.doLast {
copy {
from("${projectDir}/buildres/mac") {
include "native-messaging-host/**", "jabrefHost.py"
}
into "$buildDir/distribution/JabRef.app/Contents/Resources"
}
}
}
jmh {
warmupIterations = 5
iterations = 10
fork = 2
}
requirementTracing {
inputDirectories = files('docs', 'src/main/java', 'src/test/java')
}

View File

@ -0,0 +1,20 @@
package org.jabref.build.xjc
import org.gradle.api.Plugin
import org.gradle.api.Project
class XjcPlugin implements Plugin<Project> {
static final def CONFIGURATION_NAME = "xjc"
@Override
void apply(Project target) {
def configuration = target.configurations.create(CONFIGURATION_NAME)
configuration.description = "Dependencies needed to run the XJC tool."
target.afterEvaluate { evaluated ->
evaluated.logger.info(evaluated.configurations.xjc.asPath)
evaluated.ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: evaluated.configurations.getByName(CONFIGURATION_NAME).asPath)
}
}
}

View File

@ -0,0 +1,114 @@
package org.jabref.build.xjc
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
class XjcTask extends DefaultTask {
private def schemaFile
@Optional
private def bindingFile
private def outputDirectory
private String javaPackage
private String encoding
@Optional
private String arguments
@TaskAction
def generateClasses() {
project.mkdir(outputDirectory)
project.ant.xjc(destdir: outputDirectory, package: javaPackage, encoding: getEncoding()) {
schema(dir: schemaFile.getParent(), includes: schemaFile.getName())
if (bindingFile != null) {
binding(dir: bindingFile.getParent(), includes: bindingFile.getName())
}
if (arguments != null) {
arg(value: arguments)
}
}
}
@InputFile
File getSchemaFile() {
if (schemaFile == null) {
return null
}
return project.file(schemaFile)
}
void setSchemaFile(Object schemaFile) {
this.schemaFile = schemaFile
}
@OutputDirectory
File getOutputDirectory() {
if (outputDirectory == null) {
return null
}
return project.file(outputDirectory)
}
void setOutputDirectory(Object outputDirectory) {
this.outputDirectory = outputDirectory
updateOutput()
}
@Input
String getJavaPackage() {
return javaPackage
}
void setJavaPackage(String javaPackage) {
this.javaPackage = javaPackage
updateOutput()
}
@Input
String getEncoding() {
if(encoding == null ) {
// use UTF-8 as default encoding
return "UTF-8"
} else {
return encoding
}
}
void setEncoding(String encoding) {
this.encoding = encoding
}
@Input
String getArguments() {
return arguments
}
void setArguments(String args) {
this.arguments = args
}
@InputFile
File getBindingFile() {
if (bindingFile == null) {
return null
}
return project.file(bindingFile)
}
void setBindingFile(Object binding) {
this.bindingFile = binding
}
private void updateOutput() {
if (outputDirectory != null && javaPackage != null) {
outputs.dir(new File(getOutputDirectory(), packageAsPath(javaPackage)))
}
}
private static String packageAsPath(String pkg) {
return pkg.replace((char) '.', File.separatorChar)
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<VisualElements ForegroundText="dark" BackgroundColor="#a2aed1" ShowNameOnSquare150x150Logo="on"></VisualElements>
</Application>

View File

@ -0,0 +1,179 @@
MIT License
Copyright © 2003-2024 JabRef Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--- Privacy Policy ----
# Privacy Policy
Last updated: 2023-08-24
Your privacy is a fundamental right JabRef e.V. respects and supports.
By using JabRef and its related online services, you choose to share
some of your personal information. In this Privacy Policy we explain how
we collect, use, and share information about you, along with the choices
you have.
The term \'Personal information\' in this policy means any information
that either directly identifies you or can be somehow linked to you.
\'JabRef\' refers to the desktop application that is provided by JabRef
e.V.
Please remember that no method of transmission over the Internet, or
method of electronic storage is absolute secure. While we strive to use
commercially acceptable means to protect your Personal Data, we cannot
guarantee its absolute security. Also, whenever you communicate through
the internet, your IP-Address will always be transmitted and retained by
third parties for technical and in some cases for legal reasons.
## JabRef Desktop Application
### Collecting information
JabRef does not collect any personal information directly linked to you.
However, on certain occasions JabRef will send some information to the
online services of JabRef e.V.:
- On application start, JabRef will check for the latest version
online (by default *enabled*).
- Information about a journal you are citing when looking for more
information about this journal, using our journal database (by
default *enabled*).
- A pdf document you automatically want to extract citation
information from, using our GROBID service (by default *disabled*).
- Anonymized statistical data on the use of the graphical user
interface for internal analysis purposes (by default *disabled*).
### Storing information
JabRef only stores the following personal information locally on your
computer:
- Your proxy username and password, if you decide to store them (by
default *disabled*).
- Any personal API key you use to access third party online services
(by default *disabled*).
### Sharing information
Certain operations you perform in JabRef may trigger requests to public
third-party services such as Zotero, Crossref or the Library of Congress
for metadata retrieval. These third parties may log additional
information besides your IP address and the search terms (e.g., DOI,
ISBN or the current URL) according to their privacy policies.
These third-party services are the following:
Service;Privacy Policy
[ACM](https://www.acm.org/);<https://www.acm.org/privacy-policy>
[ACS Publications](https://pubs.acs.org/);<https://www.acs.org/privacy.html>
[APS Advancing Physics](https://harvest.aps.org/);<https://www.aps.org/about/privacy.cfm#privacy>
[arXiv.org](https://arxiv.org/);<https://info.arxiv.org/help/policies/privacy_policy.html>
[Bibliotheksverbund Bayern](https://www.bib-bvb.de/);<https://www.bib-bvb.de/web/guest/datenschutzerklaerung-bvb-homepage>
[Biodiversity Heritage Library](https://www.biodiversitylibrary.org/);<https://www.si.edu/Privacy>
[Collection of Computer Science Bibliographies](https://en.wikipedia.org/wiki/Collection_of_Computer_Science_Bibliographies);**currently unavailable**, offline
[CrossRef](https://www.crossref.org/);<https://www.crossref.org/operations-and-sustainability/privacy/>
[dblp](https://dblp.uni-trier.de/);<https://dblp.uni-trier.de/db/about/privacy.html>
[Directory of Open Access Books](https://www.doabooks.org/);<https://www.doabooks.org/en/resources/accessibility>
[Digitala Vetenskapliga Arkivet](https://www.diva-portal.org/);<https://www.uu.se/en/about-uu/data-protection-policy/>
[DOI Foundation](https://www.doi.org/);<https://www.doi.org/privacy-policy/>
[Elsevier](https://www.elsevier.com/);<https://www.elsevier.com/legal/privacy-policy>
[Google Scholar](https://scholar.google.com/);<https://policies.google.com/privacy>
[Gemeinsamer Verbundkatalog](https://www.gbv.de/);<https://www.gbv.de/datenschutz>
[IACR](https://www.iacr.org/);<https://www.iacr.org/privacy.html>
[IEEEXplore](https://ieeexplore.ieee.org/Xplore/home.jsp);<https://www.ieee.org/security-privacy.html>
[INSPIRE](https://inspirehep.net/);<https://cern.service-now.com/service-portal?id=privacy_policy&se=INSPIRE-Online&notice=main>
[JSTOR](https://www.jstor.org/);<https://www.ithaka.org/privacypolicy/>
[Library of Congress](https://lccn.loc.gov/);<https://www.loc.gov/legal/>
[National Library of Medicine](https://www.ncbi.nlm.nih.gov/);<https://www.nlm.nih.gov/web_policies.html>
[MathSciNet](http://www.ams.org/mathscinet);<https://www.ams.org/about-us/privacy>
[mEDRA](https://www.medra.org/);<https://www.medra.org/stdoc/en/Servizio_DOI_Informativa_ENG.pdf>
[Mr. DLib](https://mr-dlib.org/) [1];<https://support.dataverse.harvard.edu/harvard-dataverse-privacy-policy>
[Openlibrary](https://openlibrary.org);<https://archive.org/about/terms.php>
[ResearchGate](https://www.researchgate.net/);<https://www.researchgate.net/privacy-policy>
[IETF Datatracker](https://datatracker.ietf.org/);<https://www.ietf.org/privacy-statement/>
[Semantic Scholar](https://www.semanticscholar.org/), powered by [Allen Institute for AI](https://allenai.org/);<https://allenai.org/privacy-policy>
[Springer Nature](https://dev.springernature.com/);<https://dev.springernature.com/privacy-policy/>
[The SAO/NASA Astrophysics Data System](https://ui.adsabs.harvard.edu/);<https://ui.adsabs.harvard.edu/help/privacy/>
[Unpaywall](https://unpaywall.org/);<https://unpaywall.org/legal/privacy>
[zbMATH Open](https://www.zbmath.org);<https://zbmath.org/privacy-policy/>
[1]: *Note: The Mr. DLib service is used for the related articles tab in the entry editor and collects also your language, your browser and operating system (by default*disabled*).*;
## JabRef Browser Extension
No personal data (like name, email address, billing address or credit
card) is collected by the Browser Extension itself. But be aware that
the browser Extension uses Zotero services, where [Zotero\'s Privacy
Policy](https://www.zotero.org/support/privacy) applies.
### Collecting information
When actively used, the extension has access to the current website and
its content to process citation information. In particular, the
following information is used:
- the url of the current website you are visiting,
- the content of the current website.
### Storing information
No data will be stored by the Browser Extension.
### Sharing information
The Browser Extension does not share any data except with the local
instance of the JabRef software application, which stores the citation
data as a new entry in its library.
## Links to other Websites
Our Service may contain links to other websites that are not operated by
us. If you click on a third party link, you will be directed to that
third party\'s site. We strongly advise you to review the Privacy Policy
of every site you visit.
We have no control over and assume no responsibility for the content,
privacy policies or practices of any third party sites or services.
## Changes to this Privacy Policy
This privacy policy may be changed eventually. We encourage you to check
this Privacy Policy periodically for any changes. Any material change
will be mentioned in the changelog of the desktop application and in our
[blog](https://blog.jabref.org/).
This privacy policy is in effect as of the day mentioned as \"last
updated\" above and will remain in effect except with respect to any
changes in its provisions in the future, which will be in effect
immediately after being posted on this page.
## Contact
If you get in touch with us, we may aks you to provide us with certain
personal information (e.g. name and email address) to stay in contact
with you. For any questions or concerns regarding the privacy policy,
please send us an email to <vorstand@jabref.org> or write to
JabRef e.V.\
Josef-Lanner-Str. 9\
71069 Sindelfingen\
Germany

View File

@ -0,0 +1,12 @@
[Desktop Entry]
Name=APPLICATION_NAME
GenericName=BibTeX Editor
Comment=APPLICATION_DESCRIPTION
Exec=APPLICATION_LAUNCHER
Icon=APPLICATION_ICON
Terminal=false
Type=Application
DESKTOP_MIMES
Categories=DEPLOY_BUNDLE_CATEGORY
Keywords=bibtex;biblatex;latex;bibliography
StartupWMClass=org.jabref.gui.JabRefGUI

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,4 @@
extension=bib
mime-type=text/x-bibtex
description=BibTeX File
icon=JabRef.png

View File

@ -0,0 +1,5 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Files: *
Copyright: Copyright (C) 2003-2019 JabRef Authors
License: MIT

View File

@ -0,0 +1,81 @@
Summary: APPLICATION_SUMMARY
Name: APPLICATION_PACKAGE
Version: APPLICATION_VERSION
Release: APPLICATION_RELEASE
License: APPLICATION_LICENSE_TYPE
Vendor: APPLICATION_VENDOR
Prefix: %{dirname:APPLICATION_DIRECTORY}
Provides: APPLICATION_PACKAGE
%if "xAPPLICATION_GROUP" != "x"
Group: APPLICATION_GROUP
%endif
Autoprov: 0
Autoreq: 0
%if "xPACKAGE_DEFAULT_DEPENDENCIES" != "x" || "xPACKAGE_CUSTOM_DEPENDENCIES" != "x"
Requires: PACKAGE_DEFAULT_DEPENDENCIES PACKAGE_CUSTOM_DEPENDENCIES
%endif
#avoid ARCH subfolder
%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
#comment line below to enable effective jar compression
#it could easily get your package size from 40 to 15Mb but
#build time will substantially increase and it may require unpack200/system java to install
%define __jar_repack %{nil}
%description
APPLICATION_DESCRIPTION
%global __os_install_post %{nil}
%prep
%build
%install
rm -rf %{buildroot}
install -d -m 755 %{buildroot}APPLICATION_DIRECTORY
cp -r %{_sourcedir}APPLICATION_DIRECTORY/* %{buildroot}APPLICATION_DIRECTORY
%if "xAPPLICATION_LICENSE_FILE" != "x"
%define license_install_file %{_defaultlicensedir}/%{name}-%{version}/%{basename:APPLICATION_LICENSE_FILE}
install -d -m 755 %{buildroot}%{dirname:%{license_install_file}}
install -m 644 APPLICATION_LICENSE_FILE %{buildroot}%{license_install_file}
%endif
%files
%if "xAPPLICATION_LICENSE_FILE" != "x"
%license %{license_install_file}
%{dirname:%{license_install_file}}
%endif
# If installation directory for the application is /a/b/c, we want only root
# component of the path (/a) in the spec file to make sure all subdirectories
# are owned by the package.
%(echo APPLICATION_DIRECTORY | sed -e "s|\(^/[^/]\{1,\}\).*$|\1|")
%post
# Install the native-messaging host script for firefox/chrome/chromium
install -D -m0755 /opt/jabref/lib/native-messaging-host/firefox/org.jabref.jabref.json /usr/lib/mozilla/native-messaging-hosts/org.jabref.jabref.json
install -D -m0755 /opt/jabref/lib/native-messaging-host/chromium/org.jabref.jabref.json /etc/chromium/native-messaging-hosts/org.jabref.jabref.json
install -D -m0755 /opt/jabref/lib/native-messaging-host/chromium/org.jabref.jabref.json /etc/opt/chrome/native-messaging-hosts/org.jabref.jabref.json
# Trigger an auto-install of the browser addon for chrome/chromium browsers
install -D -m0644 /opt/jabref/lib/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json /opt/google/chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
install -D -m0644 /opt/jabref/lib/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json /usr/share/google-chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
DESKTOP_COMMANDS_INSTALL
%preun
# Remove the native-messaging hosts script only if relative to the deb package
for NATIVE_MESSAGING_JSON in "/usr/lib/mozilla/native-messaging-hosts/org.jabref.jabref.json"\
"/etc/chromium/native-messaging-hosts/org.jabref.jabref.json"\
"/etc/opt/chrome/native-messaging-hosts/org.jabref.jabref.json"; do
if [ -e $NATIVE_MESSAGING_JSON ] && grep --quiet '"path": "/opt' $NATIVE_MESSAGING_JSON; then
rm $NATIVE_MESSAGING_JSON
fi
done
# Remove the auto-install triggers of the browser addon for chrom/chromium
rm -f /opt/google/chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json || true
rm -f /usr/share/google-chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json || true
DESKTOP_SCRIPTS
DESKTOP_COMMANDS_UNINSTALL
%clean

View File

@ -0,0 +1,131 @@
#!/usr/bin/env python3
import json
import logging
import os
import platform
import shlex
import shutil
import struct
import subprocess
import sys
from pathlib import Path
def which(command):
if os.getenv("FLATPAK_ID"):
try:
return subprocess.check_output(["flatpak-spawn", "--host", "which", command]).decode().strip()
except subprocess.CalledProcessError:
pass
path = shutil.which(command)
if path != "":
return path
else:
return None
JABREF_PATH = ""
if os.getenv("FLATPAK_ID"):
try:
subprocess.check_output(["flatpak-spawn", "--host", "true"])
except subprocess.CalledProcessError:
logging.error("Failed to call JabRef: Flatpak browser missing permissions")
send_message({"message": "flatpakPermissionsError", "output": "Flatpak browser missing permissions"})
exit(-1)
JABREF_PATH = "flatpak-spawn --host "
# Try a set of possible launchers to execute JabRef
script_dir = Path(__file__).resolve().parent.parent
relpath_path = str(script_dir / "bin/JabRef")
lowercase_path = which("jabref")
uppercase_path = which("JabRef")
# Relative path used in the portable install
if which(relpath_path) is not None:
JABREF_PATH += relpath_path
# Lowercase launcher used in deb/rpm/snap packages
elif lowercase_path is not None:
JABREF_PATH += lowercase_path
# Uppercase launcher used in Arch AUR package
elif uppercase_path is not None:
JABREF_PATH += uppercase_path
# FLatpak support
elif which("/var/lib/flatpak/exports/bin/org.jabref.jabref") is not None:
JABREF_PATH += "/var/lib/flatpak/exports/bin/org.jabref.jabref"
else:
logging.error("Could not determine JABREF_PATH")
sys.exit(-1)
logging_dir = Path.home() / ".mozilla/native-messaging-hosts/"
if not logging_dir.exists():
logging_dir.mkdir(parents=True)
logging.basicConfig(filename=str(logging_dir / "jabref_browser_extension.log"))
# Read a message from stdin and decode it.
def get_message():
raw_length = sys.stdin.buffer.read(4)
if not raw_length:
logging.error("Raw_length null")
sys.exit(0)
message_length = struct.unpack("=I", raw_length)[0]
logging.info("Got length: {} bytes to be read".format(message_length))
message = sys.stdin.buffer.read(message_length).decode("utf-8")
logging.info("Got message of {} chars".format(len(message)))
data = json.loads(message)
logging.info("Successfully retrieved JSON")
return data
# Encode a message for transmission, given its content.
def encode_message(message_content):
encoded_content = json.dumps(message_content).encode("utf-8")
encoded_length = struct.pack("=I", len(encoded_content))
return {
"length": encoded_length,
"content": struct.pack(str(len(encoded_content)) + "s", encoded_content),
}
# Send an encoded message to stdout.
def send_message(message):
encoded_message = encode_message(message)
sys.stdout.buffer.write(encoded_message["length"])
sys.stdout.buffer.write(encoded_message["content"])
sys.stdout.buffer.flush()
def add_jabref_entry(data):
"""Send string via cli as literal to preserve special characters"""
cmd = str(JABREF_PATH).split() + ["--importBibtex", r"{}".format(data)]
logging.info("Try to execute command {}".format(cmd))
response = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
logging.info("Called JabRef and got: {}".format(response))
return response
logging.info("Starting JabRef backend")
try:
message = get_message()
except Exception as e:
message = str(e)
logging.info(str(message))
if "status" in message and message["status"] == "validate":
cmd = str(JABREF_PATH).split() + ["--version"]
try:
response = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output))
send_message({"message": "jarNotFound", "path": JABREF_PATH})
else:
logging.info("Response: {}".format(response))
send_message({"message": "jarFound"})
else:
entry = message["text"]
try:
output = add_jabref_entry(entry)
send_message({"message": "ok", "output": str(output)})
except subprocess.CalledProcessError as exc:
logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output))
send_message({"message": "error", "output": str(exc.output)})

View File

@ -0,0 +1,3 @@
{
"external_update_url": "https://clients2.google.com/service/update2/crx"
}

View File

@ -0,0 +1,10 @@
{
"name": "org.jabref.jabref",
"description": "JabRef",
"path": "/opt/jabref/lib/jabrefHost.py",
"type": "stdio",
"allowed_origins": [
"chrome-extension://bifehkofibaamoeaopjglfkddgkijdlh/",
"chrome-extension://pgkajmkfgbehiomipedjhoddkejohfna/"
]
}

View File

@ -0,0 +1,10 @@
{
"name": "org.jabref.jabref",
"description": "JabRef",
"path": "/opt/jabref/lib/jabrefHost.py",
"type": "stdio",
"allowed_extensions": [
"browserextension@jabref.org",
"@jabfox"
]
}

View File

@ -0,0 +1,42 @@
#!/bin/sh
# postinst script for my jabref
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
# Install the native-messaging host script for firefox/chrome/chromium
install -D -m0755 /opt/jabref/lib/native-messaging-host/firefox/org.jabref.jabref.json /usr/lib/mozilla/native-messaging-hosts/org.jabref.jabref.json
install -D -m0755 /opt/jabref/lib/native-messaging-host/chromium/org.jabref.jabref.json /etc/chromium/native-messaging-hosts/org.jabref.jabref.json
install -D -m0755 /opt/jabref/lib/native-messaging-host/chromium/org.jabref.jabref.json /etc/opt/chrome/native-messaging-hosts/org.jabref.jabref.json
install -D -m0755 /opt/jabref/lib/native-messaging-host/chromium/org.jabref.jabref.json /etc/opt/edge/native-messaging-hosts/org.jabref.jabref.json
# Trigger an auto-install of the browser addon for chrome/chromium browsers
install -D -m0644 /opt/jabref/lib/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json /opt/google/chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
install -D -m0644 /opt/jabref/lib/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json /usr/share/google-chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
DESKTOP_COMMANDS_INSTALL
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,42 @@
#!/bin/sh
# postrm script for APPLICATION_PACKAGE
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <overwriter>
# <overwriter-version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
# Remove the native-messaging hosts script only if relative to the deb package
for NATIVE_MESSAGING_JSON in "/usr/lib/mozilla/native-messaging-hosts/org.jabref.jabref.json"\
"/etc/chromium/native-messaging-hosts/org.jabref.jabref.json"\
"/etc/opt/chrome/native-messaging-hosts/org.jabref.jabref.json"\
"/etc/opt/edge/native-messaging-hosts/org.jabref.jabref.json"; do
if [ -e $NATIVE_MESSAGING_JSON ] && grep --quiet '"path": "/opt' $NATIVE_MESSAGING_JSON; then
rm -f $NATIVE_MESSAGING_JSON
fi
done
# Remove the auto-install triggers of the browser addon for chrom/chromium
rm -f /opt/google/chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
rm -f /usr/share/google-chrome/extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,39 @@
<?xml version="1.0" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSMinimumSystemVersion</key>
<string>10.9</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleExecutable</key>
<string>DEPLOY_LAUNCHER_NAME</string>
<key>CFBundleIconFile</key>
<string>DEPLOY_ICON_FILE</string>
<key>CFBundleIdentifier</key>
<string>DEPLOY_BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>DEPLOY_BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>DEPLOY_BUNDLE_SHORT_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<!-- See https://developer.apple.com/app-store/categories/ for list of AppStore categories -->
<key>LSApplicationCategoryType</key>
<string>Unknown</string>
<key>CFBundleVersion</key>
<string>DEPLOY_BUNDLE_CFBUNDLE_VERSION</string>
<key>NSHumanReadableCopyright</key>
<string>DEPLOY_BUNDLE_COPYRIGHT</string>DEPLOY_FILE_ASSOCIATIONS
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSMinimumSystemVersion</key>
<string>10.9</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleExecutable</key>
<string>DEPLOY_LAUNCHER_NAME</string>
<key>CFBundleIconFile</key>
<string>DEPLOY_ICON_FILE</string>
<key>CFBundleIdentifier</key>
<string>DEPLOY_BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>DEPLOY_BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>DEPLOY_BUNDLE_SHORT_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<!-- See https://developer.apple.com/app-store/categories/ for list of AppStore categories -->
<key>LSApplicationCategoryType</key>
<string>Unknown</string>
<key>CFBundleVersion</key>
<string>DEPLOY_BUNDLE_CFBUNDLE_VERSION</string>
<key>NSHumanReadableCopyright</key>
<string>DEPLOY_BUNDLE_COPYRIGHT</string>DEPLOY_FILE_ASSOCIATIONS
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSMinimumSystemVersion</key>
<string>10.9</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleExecutable</key>
<string>DEPLOY_LAUNCHER_NAME</string>
<key>CFBundleIconFile</key>
<string>DEPLOY_ICON_FILE</string>
<key>CFBundleIdentifier</key>
<string>DEPLOY_BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>DEPLOY_BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>DEPLOY_BUNDLE_SHORT_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<!-- See https://developer.apple.com/app-store/categories/ for list of AppStore categories -->
<key>LSApplicationCategoryType</key>
<string>Unknown</string>
<key>CFBundleVersion</key>
<string>DEPLOY_BUNDLE_CFBUNDLE_VERSION</string>
<key>NSHumanReadableCopyright</key>
<string>DEPLOY_BUNDLE_COPYRIGHT</string>DEPLOY_FILE_ASSOCIATIONS
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

View File

@ -0,0 +1,44 @@
tell application "Finder"
set theDisk to a reference to (disks whose URL = "DEPLOY_VOLUME_URL")
open theDisk
set theWindow to a reference to (container window of disks whose URL = "DEPLOY_VOLUME_URL")
set current view of theWindow to icon view
set toolbar visible of theWindow to false
set statusbar visible of theWindow to false
-- size of window should fit the size of background
set the bounds of theWindow to {346, 100, 920, 500}
set theViewOptions to a reference to the icon view options of theWindow
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to 128
set background picture of theViewOptions to POSIX file "DEPLOY_BG_FILE"
-- Create alias for install location
make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to POSIX file "DEPLOY_INSTALL_LOCATION" with properties {name:"DEPLOY_INSTALL_LOCATION"}
set allTheFiles to the name of every item of theWindow
set xpos to 120
repeat with theFile in allTheFiles
set theFilePath to POSIX path of theFile
set appFilePath to POSIX path of "/DEPLOY_TARGET"
if theFilePath is "DEPLOY_INSTALL_LOCATION" then
-- Position install location
set position of item theFile of theWindow to {430, 170}
else if theFilePath ends with appFilePath then
-- Position application or runtime
set position of item theFile of theWindow to {140, 170}
else
-- Position all other items in a second row.
set position of item theFile of theWindow to {xpos, 290}
set xpos to xpos + 150
end if
end repeat
update theDisk without registering applications
delay 5
close (get window of theDisk)
end tell

Binary file not shown.

View File

@ -0,0 +1,12 @@
# Mac Resources
## Modifying DMG Setup scpt
Rename `JabRef-dmg-setup.scpt script` to `JabRef-dmg-setup.applescript`.
Only modify the `JabRef-dmg-setup.applescript` in the macOS Script Editor. Afterwards copy over the file and rename it to `JabRef-dmg-setup.scpt`.
Normally the `scpt` file is a binary compiled variant and the `.applescript` the uncompiled format but jpackage expects the sctp in uncompiled format
## Generate iconsets
To generate icns files use the script under `src/main/resources/icons`
Install [svg2png](https://formulae.brew.sh/formula/svg2png) and call the script with the svg filename as first argument.

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>libjli.dylib</string>
<key>CFBundleIdentifier</key>
<string>CF_BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>7.0</string>
<key>CFBundleName</key>
<string>CF_BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>CF_BUNDLE_SHORT_VERSION_STRING</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>CF_BUNDLE_VERSION</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>libjli.dylib</string>
<key>CFBundleIdentifier</key>
<string>CF_BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>7.0</string>
<key>CFBundleName</key>
<string>CF_BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>CF_BUNDLE_SHORT_VERSION_STRING</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>CF_BUNDLE_VERSION</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,4 @@
extension=bib
mime-type=text/x-bibtex
description=BibTeX File
icon=jabref.icns

View File

@ -0,0 +1,39 @@
<?xml version="1.0" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSMinimumSystemVersion</key>
<string>10.9</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleExecutable</key>
<string>DEPLOY_LAUNCHER_NAME</string>
<key>CFBundleIconFile</key>
<string>DEPLOY_ICON_FILE</string>
<key>CFBundleIdentifier</key>
<string>DEPLOY_BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>DEPLOY_BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>DEPLOY_BUNDLE_SHORT_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<!-- See https://developer.apple.com/app-store/categories/ for list of AppStore categories -->
<key>LSApplicationCategoryType</key>
<string>Unknown</string>
<key>CFBundleVersion</key>
<string>DEPLOY_BUNDLE_CFBUNDLE_VERSION</string>
<key>NSHumanReadableCopyright</key>
<string>DEPLOY_BUNDLE_COPYRIGHT</string>DEPLOY_FILE_ASSOCIATIONS
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,101 @@
#!/usr/bin/python3
import json
import logging
import platform
import shlex
import shutil
import struct
import subprocess
import sys
from pathlib import Path
# We assume that this python script is located in "jabref/lib" while the executable is "jabref/bin/JabRef"
# Note that the package structure is different when installed as a .app bundle on MacOs, so the path must be altered.
script_dir = Path(__file__).resolve().parent.parent
JABREF_PATH = script_dir / "bin/JabRef"
# on mac we must only go one folder upwards
if sys.platform.startswith('darwin'):
script_dir = Path(__file__).resolve().parent
if not JABREF_PATH.exists():
JABREF_PATH = script_dir / "MacOS/JabRef"
if not JABREF_PATH.exists():
logging.error("Could not determine JABREF_PATH")
send_message({"message": "error", "output": "Could not find JabRef. Please check that it is installed correctly."})
sys.exit(-1)
logging_dir = Path.home() / ".mozilla/native-messaging-hosts/"
if not logging_dir.exists():
logging_dir.mkdir(parents=True)
logging.basicConfig(filename=str(logging_dir / "jabref_browser_extension.log"))
# Read a message from stdin and decode it.
def get_message():
raw_length = sys.stdin.buffer.read(4)
if not raw_length:
logging.error("Raw_length null")
sys.exit(0)
message_length = struct.unpack("=I", raw_length)[0]
logging.info("Got length: {} bytes to be read".format(message_length))
message = sys.stdin.buffer.read(message_length).decode("utf-8")
logging.info("Got message of {} chars".format(len(message)))
data = json.loads(message)
logging.info("Successfully retrieved JSON")
return data
# Encode a message for transmission, given its content.
def encode_message(message_content):
encoded_content = json.dumps(message_content).encode("utf-8")
encoded_length = struct.pack("=I", len(encoded_content))
return {
"length": encoded_length,
"content": struct.pack(str(len(encoded_content)) + "s", encoded_content),
}
# Send an encoded message to stdout.
def send_message(message):
encoded_message = encode_message(message)
sys.stdout.buffer.write(encoded_message["length"])
sys.stdout.buffer.write(encoded_message["content"])
sys.stdout.buffer.flush()
def add_jabref_entry(data):
"""Send string via cli as literal to preserve special characters"""
cmd = str(JABREF_PATH).split() + ["--importBibtex", r"{}".format(data)]
logging.info("Try to execute command {}".format(cmd))
response = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
logging.info("Called JabRef and got: {}".format(response))
return response
logging.info("Starting JabRef backend")
try:
message = get_message()
except Exception as e:
message = str(e)
logging.info(str(message))
if "status" in message and message["status"] == "validate":
cmd = str(JABREF_PATH).split() + ["--version"]
try:
response = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output))
send_message({"message": "jarNotFound", "path": JABREF_PATH})
else:
logging.info("Response: {}".format(response))
send_message({"message": "jarFound"})
else:
entry = message["text"]
try:
output = add_jabref_entry(entry)
send_message({"message": "ok", "output": str(output)})
except subprocess.CalledProcessError as exc:
logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output))
send_message({"message": "error", "output": str(exc.output)})

Binary file not shown.

View File

@ -0,0 +1,3 @@
{
"external_update_url": "https://clients2.google.com/service/update2/crx"
}

View File

@ -0,0 +1,10 @@
{
"name": "org.jabref.jabref",
"description": "JabRef",
"path": "/Applications/JabRef.app/Contents/jabrefHost.py",
"type": "stdio",
"allowed_origins": [
"chrome-extension://bifehkofibaamoeaopjglfkddgkijdlh/",
"chrome-extension://pgkajmkfgbehiomipedjhoddkejohfna/"
]
}

View File

@ -0,0 +1,7 @@
{
"name": "org.jabref.jabref",
"description": "JabRef",
"path": "/Applications/JabRef.app/Contents/jabrefHost.py",
"type": "stdio",
"allowed_extensions": ["browserextension@jabref.org", "@jabfox"]
}

View File

@ -0,0 +1,20 @@
#!/bin/sh
chown root:wheel "INSTALL_LOCATION"
chmod a+rX "INSTALL_LOCATION"
chmod +r "APP_LOCATION/"*.jar
# Trigger an auto-install of the browser addon for chrome/chromium browsers
# First create the necessary path, then copy the autoinstall file.
install -d /Library/Application\ Support/Google/Chrome/External\ Extensions/
install -m0644 /Applications/JabRef.app/Contents/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json /Library/Application\ Support/Google/Chrome/External\ Extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
# Install the native-messaging host script for firefox/chrome/chromium
install -d /Library/Application\ Support/Mozilla/NativeMessagingHosts/
install -m0755 /Applications/JabRef.app/Contents/native-messaging-host/firefox/org.jabref.jabref.json /Library/Application\ Support/Mozilla/NativeMessagingHosts/org.jabref.jabref.json
install -d /Library/Application\ Support/Chromium/NativeMessagingHosts/
install -m0755 /Applications/JabRef.app/Contents/native-messaging-host/chromium/org.jabref.jabref.json /Library/Application\ Support/Chromium/NativeMessagingHosts/org.jabref.jabref.json
install -d /Library/Google/Chrome/NativeMessagingHosts/
install -m0755 /Applications/JabRef.app/Contents/native-messaging-host/chromium/org.jabref.jabref.json /Library/Google/Chrome/NativeMessagingHosts/org.jabref.jabref.json
install -d /Library/Microsoft/Edge/NativeMessagingHosts/
install -m0755 /Applications/JabRef.app/Contents/native-messaging-host/chromium/org.jabref.jabref.json /Library/Microsoft/Edge/NativeMessagingHosts/org.jabref.jabref.json
exit 0

View File

@ -0,0 +1,6 @@
create pluggable database jabref admin user jabref identified by jabref
file_name_convert=('/opt/oracle/oradata/XE/pdbseed','/opt/oracle/oradata/XE/JABREF');
alter pluggable database jabref open read write;
alter pluggable database all save state;
ALTER SESSION SET CONTAINER = jabref;
grant all privileges to jabref container=current;

View File

@ -0,0 +1,36 @@
<?xml version="1.0" ?>
<package>
<job id="postImage">
<script language="jscript">
<![CDATA[
var fileSystem = new ActiveXObject("Scripting.FileSystemObject");
// The script is invoked in the "image" folder and not in "config" for some reason
// DEBUG Output
// var shell = new ActiveXObject("WScript.Shell");
// shell.Popup(fileSystem.GetFolder("."));
var jabRefRoot = fileSystem.GetFolder(".").ParentFolder.ParentFolder.ParentFolder.ParentFolder.Path;
var installerConfig = jabRefRoot + "/build/installer/config/";
// Copy additional installer resources
fileSystem.CopyFile(jabRefRoot + "/buildres/windows/JabRefTopBanner.bmp", installerConfig);
var wxsFilePath = installerConfig + "main.wxs";
wxsFile = fileSystem.OpenTextFile(wxsFilePath, 1);
var contents = wxsFile.ReadAll();
wxsFile.Close();
// Add registry values for JabRef Browser Extension
contents = contents.replace("</Product>", "<DirectoryRef Id=\"TARGETDIR\"><Component Id=\"RegistryJabRefBrowserEntries\" Guid=\"b6bc55ad-905c-4258-89b1-8b37abbe559c\" Win64=\"yes\"><RegistryKey Root=\"HKMU\" Key=\"SOFTWARE\\Mozilla\\NativeMessagingHosts\\org.jabref.jabref\" Action=\"createAndRemoveOnUninstall\" ForceCreateOnInstall=\"yes\"><RegistryValue Type=\"string\" Value=\"[INSTALLDIR]jabref-firefox.json\"/></RegistryKey><RegistryKey Root=\"HKMU\" Key=\"Software\\Google\\Chrome\\NativeMessagingHosts\\org.jabref.jabref\" Action=\"createAndRemoveOnUninstall\" ForceCreateOnInstall=\"yes\"><RegistryValue Type=\"string\" Value=\"[INSTALLDIR]jabref-chrome.json\"/></RegistryKey><RegistryKey Root=\"HKMU\" Key=\"Software\\Microsoft\\Edge\\NativeMessagingHosts\\org.jabref.jabref\" Action=\"createAndRemoveOnUninstall\" ForceCreateOnInstall=\"yes\"><RegistryValue Type=\"string\" Value=\"[INSTALLDIR]jabref-chrome.json\"/></RegistryKey><RegistryKey Root=\"HKMU\" Key=\"Software\\Google\\Chrome\\Extensions\\bifehkofibaamoeaopjglfkddgkijdlh\" Action=\"createAndRemoveOnUninstall\" ForceCreateOnInstall=\"yes\"><RegistryValue Type=\"string\" Name=\"update_url\" Value=\"https://clients2.google.com/service/update2/crx\" /></RegistryKey><RegistryKey Root=\"HKMU\" Key=\"Software\\Wow6432Node\\Google\\Chrome\\Extensions\\bifehkofibaamoeaopjglfkddgkijdlh\" Action=\"createAndRemoveOnUninstall\" ForceCreateOnInstall=\"yes\"><RegistryValue Type=\"string\" Name=\"update_url\" Value=\"https://clients2.google.com/service/update2/crx\" /></RegistryKey><RegistryKey Root=\"HKMU\" Key=\"Software\\Microsoft\\Edge\\Extensions\\pgkajmkfgbehiomipedjhoddkejohfna\" Action=\"createAndRemoveOnUninstall\" ForceCreateOnInstall=\"yes\"><RegistryValue Type=\"string\" Name=\"update_url\" Value=\"https://edge.microsoft.com/extensionwebstorebase/v1/crx\" /></RegistryKey><RegistryKey Root=\"HKMU\" Key=\"Software\\Wow6432Node\\Microsoft\\Edge\\Extensions\\pgkajmkfgbehiomipedjhoddkejohfna\" Action=\"createAndRemoveOnUninstall\" ForceCreateOnInstall=\"yes\"><RegistryValue Type=\"string\" Name=\"update_url\" Value=\"https://edge.microsoft.com/extensionwebstorebase/v1/crx\" /></RegistryKey></Component></DirectoryRef><Feature Id=\"BrowserExtension\" Level=\"1\"><ComponentRef Id=\"RegistryJabRefBrowserEntries\" /></Feature></Product>");
// Specify banner
contents = contents.replace("</Product>", "<WixVariable Id=\"WixUIBannerBmp\" Value=\"JabRefTopBanner.bmp\" /></Product>");
//contents = contents.replace("</Product>", "<WixVariable Id=\"WixUIDialogBmp\" Value=\"\" /></Product>");
wxsFile = fileSystem.OpenTextFile(wxsFilePath, 2, true);
wxsFile.Write(contents);
wxsFile.Close();
]]>
</script>
</job>
</package>

View File

@ -0,0 +1,20 @@
@echo off
pushd %~dp0
:: Test if pwsh exists
setlocal enabledelayedexpansion
where /q pwsh.exe
if !ERRORLEVEL!==0 (
@pwsh.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File ".\JabRefHost.ps1"
) else (
:: If not, test if powershell exists
where /q powershell.exe
if !ERRORLEVEL!==0 (
@powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File ".\JabRefHost.ps1"
) else (
echo "Could not find pwsh.exe or powershell.exe" 1>&2
echo "Please install PowerShell and try again." 1>&2
exit /b 1
)
)
endlocal

View File

@ -0,0 +1,54 @@
function Respond($response) {
$jsonResponse = $response | ConvertTo-Json
try {
$writer = New-Object System.IO.BinaryWriter([System.Console]::OpenStandardOutput())
$writer.Write([int]$jsonResponse.Length)
$writer.Write([System.Text.Encoding]::UTF8.GetBytes($jsonResponse))
$writer.Close()
} finally {
$writer.Dispose()
}
}
$jabRefExe = [System.IO.Path]::Combine($PSScriptRoot, "runtime\\bin\\JabRef.bat")
try {
$reader = New-Object System.IO.BinaryReader([System.Console]::OpenStandardInput())
$length = $reader.ReadInt32()
$messageRaw = [System.Text.Encoding]::UTF8.GetString($reader.ReadBytes($length))
$message = $messageRaw | ConvertFrom-Json
if ($message.Status -eq "validate") {
if (-not (Test-Path $jabRefExe)) {
return Respond @{message="jarNotFound";path=$jabRefExe}
} else {
return Respond @{message="jarFound"}
}
}
if (-not (Test-Path $jabRefExe)) {
return Respond @{message="jarNotFound"; output="Unable to locate '$jabRefExe'."}
}
$messageText = $message.Text.replace("`n"," ").replace("`r"," ")
$tempfile = New-TemporaryFile
# WriteAllLines should write the file as UTF-8 without BOM
# unlike Out-File which writes UTF-16 with BOM in ps5.1
[IO.File]::WriteAllLines($tempfile, $messageText)
$output = & $jabRefExe -importToOpen $tempfile *>&1
Remove-Item $tempfile *>$null
# For debugging: uncomment the following lines to get the output of JabRef be displayed as a popup
#$wshell = New-Object -ComObject Wscript.Shell
#$wshell.Popup("Input: $messageText; Output: $output", 0, "JabRef", 0x0 + 0x30)
return Respond @{message="ok"; output="$output"}
}
catch {
$err = $PSItem
Respond @{message="error"; output="$($err.Exception.Message)"; stacktrace="$($err.ScriptStackTrace)"}
# Still print the error to the console so that it is picked up by the browser in addition
throw $err
}
finally {
$reader.Dispose()
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -0,0 +1,4 @@
extension=bib
mime-type=text/x-bibtex
description=BibTeX File
icon=JabRef.ico

View File

@ -0,0 +1,10 @@
{
"name": "org.jabref.jabref",
"description": "JabRef",
"path": "JabRefHost.bat",
"type": "stdio",
"allowed_origins": [
"chrome-extension://bifehkofibaamoeaopjglfkddgkijdlh/",
"chrome-extension://pgkajmkfgbehiomipedjhoddkejohfna/"
]
}

View File

@ -0,0 +1,10 @@
{
"name": "org.jabref.jabref",
"description": "JabRef",
"path": "JabRefHost.bat",
"type": "stdio",
"allowed_extensions": [
"browserextension@jabref.org",
"@jabfox"
]
}

9
jabref/codecov.yml Normal file
View File

@ -0,0 +1,9 @@
coverage:
ignore:
- src/generated/.*
status:
patch: false
project:
default:
threshold: 0.01
comment: false

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,296 @@
<code_scheme name="JabRef" version="173">
<option name="RIGHT_MARGIN" value="0" />
<option name="SOFT_MARGINS" value="120" />
<JavaCodeStyleSettings>
<option name="DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION" value="true" />
<option name="SPACE_INSIDE_ONE_LINE_ENUM_BRACES" value="true" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="javafx" withSubpackages="true" static="false" />
<emptyLine />
<package name="org.jabref" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
</value>
</option>
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="WRAP_COMMENTS" value="true" />
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PROTECTED>true</PROTECTED>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PROTECTED>true</PROTECTED>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PROTECTED>true</PROTECTED>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PROTECTED>true</PROTECTED>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PRIVATE>true</PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PRIVATE>true</PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<FIELD>true</FIELD>
</match>
</rule>
</section>
<section>
<rule>
<match>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CONSTRUCTOR>true</CONSTRUCTOR>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD>true</METHOD>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<METHOD>true</METHOD>
</match>
</rule>
</section>
<section>
<rule>
<match>
<ENUM>true</ENUM>
</match>
</rule>
</section>
<section>
<rule>
<match>
<INTERFACE>true</INTERFACE>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<CLASS>true</CLASS>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CLASS>true</CLASS>
</match>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>

30
jabref/config/README.md Normal file
View File

@ -0,0 +1,30 @@
# IntelliJ IDEA Code Style Configuration
IntelliJ IDEA comes with a powerful code formatter that helps you to keep the formatting consistent with the style JabRef uses.
Style-checks are done for each pull request and installing this code style configuration helps you to ensure that this test passes. To install it, you need to do the following steps:
1. Go to *Preferences* or press <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>S</kbd> (<kbd>Cmd</kbd> + <kbd>,</kbd> on macOS)
2. Go to "Editor > Code Style"
3. Click the gear (right of "Scheme: ...")
4. Click "Import Scheme >"
5. Choose `IntelliJ IDEA code style XML`
6. Select the file `config\IntelliJ Code Style.xml`
7. Press "OK"
8. Press "OK"
9. Press "Close"
10. Press "OK"
* Please let `.editorconfig` override the settings of IntelliJ
# Eclipse:
The Eclipse code formatter style is stored in the `eclipse.gradle` file and gets imported automatically.
In case the formatter style needs to be adapted, configure it and export in eclipse.
1. Right click on the eclipse project "JabRef"
2. Select "Export > General > Preferences"
3. Select "Java Code Style preferences"
4. Choose output file
5. Compare the formatter settings in the epf file with the ones in the eclipse.gradle file (`org.eclipse.jdt.core.formatter.`)
6. Replace the Eclipse Code Style.epf with the exported epf file

View File

@ -0,0 +1,408 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="22">
<profile kind="CodeFormatterProfile" name="JabRef" version="22">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="26"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures" value="warning"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.compiler.release" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures" value="disabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="9999"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="9999"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

View File

@ -0,0 +1,162 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="charset" value="UTF-8"/>
<module name="Header">
<property name="header" value=""/>
</module>
<module name="SuppressionFilter">
<property name="file" value="${config_loc}/suppressions.xml"/>
</module>
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<module name="FileTabCharacter"/>
<module name="NewlineAtEndOfFile"/>
<!-- Prevent empty start and end of blocks - source: comments to https://stackoverflow.com/a/48027770/873282 -->
<module name="RegexpMultiline">
<property name="message" value="Blank line at start of block should be removed" />
<property name="format" value="(\(.*\)|else)\s*\{\s*[\r]?\n\s*[\r]?\n" />
<property name="fileExtensions" value="groovy,java" />
</module>
<module name="RegexpMultiline">
<property name="message" value="Blank line at end of block should be removed" />
<property name="format" value="[\r]?\n\s*[\r]?\n\s*\}" />
<property name="fileExtensions" value="groovy,java" />
</module>
<!-- Checks for size violations: https://checkstyle.sourceforge.io/config_sizes.html -->
<!-- LineLength not in place as PreviewerViewer and RelatedArticlesTab have line length with more than 500 charachters -->
<module name="TreeWalker">
<!-- Checks for Javadoc comments: https://checkstyle.org/config_javadoc.html -->
<module name="InvalidJavadocPosition"/>
<module name="JavadocMethod">
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
</module>
<module name="RequireEmptyLineBeforeBlockTagGroup"/>
<module name="JavadocMissingLeadingAsteriskCheck"/>
<!-- Checks for imports: https://checkstyle.org/config_import.html -->
<module name="UnusedImports"/>
<module name="RedundantImport"/>
<module name="AvoidStarImport"/>
<module name="IllegalImport"/>
<module name="ImportOrder">
<property name="groups" value="java,javax,javafx,org.jabref,*"/>
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="bottom"/>
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<!-- Checks for whitespace: https://checkstyle.org/config_whitespace.html -->
<module name="EmptyForInitializerPad"/>
<module name="EmptyLineSeparator">
<!-- check all except variable declarations -->
<property name="tokens"
value="IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF, STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF"/>
<property name="allowMultipleEmptyLines" value="false"/>
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
</module>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoLineWrap"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="ParenPad"/>
<module name="SeparatorWrap">
<property name="tokens" value="COMMA, SEMI, ELLIPSIS, ARRAY_DECLARATOR, RBRACK, METHOD_REF"/>
</module>
<module name="SingleSpaceSeparator"/>
<module name="NoWhitespaceBeforeCaseDefaultColon"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround">
<!-- RCULRY causes issues if classes are nested within arrays, therefore not activated -->
<property name="tokens"
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV,
DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL,
PLUS, PLUS_ASSIGN, QUESTION,
SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
</module>
<!-- Checks for Naming Conventions: https://checkstyle.org/config_naming.html -->
<module name="ConstantName">
<property name="format" value="^log(ger)?|[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
</module>
<module name="PatternVariableName" />
<module name="RecordComponentName"/>
<!-- Checks for blocks: https://checkstyle.org/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="NeedBraces"/>
<module name="EmptyBlock">
<property name="option" value="text"/>
</module>
<!-- Disallows empty catch blocks (not even having a comment): https://checkstyle.sourceforge.io/config_blocks.html#EmptyCatchBlock -->
<module name="EmptyCatchBlock"/>
<!--
following rule enforces that there are no one line statements such as
public String getTabName() { return Localization.lang("XMP metadata"); }
-->
<module name="LeftCurly"/>
<module name="RightCurly"/>
<!-- coding - https://checkstyle.sourceforge.io/config_coding.html -->
<module name="AvoidDoubleBraceInitialization"/>
<module name="CovariantEquals"/>
<module name="MultipleVariableDeclarations"/>
<module name="OneStatementPerLine">
<property name="treatTryResourcesAsStatement" value="true"/>
</module>
<module name="UnnecessarySemicolonInTryWithResources"/>
<!-- Checks for common coding problems: https://checkstyle.org/config_coding.html -->
<module name="DeclarationOrder"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<!-- force a space after // for comments -->
<module name="TodoComment">
<property name="id" value="commentStartWithSpace"/>
<property name="format" value="^([^\s\/*])"/>
<message key="todo.match" value="Comment text should start with space."/>
</module>
<module name="MissingDeprecated"/>
<!-- Checks for illegal usage of reserved names as identifier names, such as "var", "record" - https://checkstyle.sourceforge.io/config_naming.html#IllegalIdentifierName -->
<module name="IllegalIdentifierName"/>
<module name="RecordTypeParameterNameCheck"/>
</module>
</module>

View File

@ -0,0 +1,162 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="charset" value="UTF-8"/>
<module name="Header">
<property name="header" value=""/>
</module>
<module name="SuppressionFilter">
<property name="file" value="config/checkstyle/suppressions.xml"/>
</module>
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="(module\-info|heylogs)\.java$"/>
</module>
<module name="FileTabCharacter"/>
<module name="NewlineAtEndOfFile"/>
<!-- Prevent empty start and end of blocks - source: comments to https://stackoverflow.com/a/48027770/873282 -->
<module name="RegexpMultiline">
<property name="message" value="Blank line at start of block should be removed" />
<property name="format" value="(\(.*\)|else)\s*\{\s*[\r]?\n\s*[\r]?\n" />
<property name="fileExtensions" value="groovy,java" />
</module>
<module name="RegexpMultiline">
<property name="message" value="Blank line at end of block should be removed" />
<property name="format" value="[\r]?\n\s*[\r]?\n\s*\}" />
<property name="fileExtensions" value="groovy,java" />
</module>
<!-- Checks for size violations: https://checkstyle.sourceforge.io/config_sizes.html -->
<!-- LineLength not in place as PreviewerViewer and RelatedArticlesTab have line length with more than 500 charachters -->
<module name="TreeWalker">
<!-- Checks for Javadoc comments: https://checkstyle.org/config_javadoc.html -->
<module name="InvalidJavadocPosition"/>
<module name="JavadocMethod">
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
</module>
<module name="RequireEmptyLineBeforeBlockTagGroup"/>
<module name="JavadocMissingLeadingAsteriskCheck"/>
<!-- Checks for imports: https://checkstyle.org/config_import.html -->
<module name="UnusedImports"/>
<module name="RedundantImport"/>
<module name="AvoidStarImport"/>
<module name="IllegalImport"/>
<module name="ImportOrder">
<property name="groups" value="java,javax,javafx,org.jabref,*"/>
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="bottom"/>
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<!-- Checks for whitespace: https://checkstyle.org/config_whitespace.html -->
<module name="EmptyForInitializerPad"/>
<module name="EmptyLineSeparator">
<!-- check all except variable declarations -->
<property name="tokens"
value="IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF, STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF"/>
<property name="allowMultipleEmptyLines" value="false"/>
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
</module>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoLineWrap"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="ParenPad"/>
<module name="SeparatorWrap">
<property name="tokens" value="COMMA, SEMI, ELLIPSIS, ARRAY_DECLARATOR, RBRACK, METHOD_REF"/>
</module>
<module name="SingleSpaceSeparator"/>
<module name="NoWhitespaceBeforeCaseDefaultColon"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround">
<!-- RCULRY causes issues if classes are nested within arrays, therefore not activated -->
<property name="tokens"
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV,
DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL,
PLUS, PLUS_ASSIGN, QUESTION,
SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
</module>
<!-- Checks for Naming Conventions: https://checkstyle.org/config_naming.html -->
<module name="ConstantName">
<property name="format" value="^log(ger)?|[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
</module>
<module name="PatternVariableName" />
<module name="RecordComponentName"/>
<!-- Checks for blocks: https://checkstyle.org/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="NeedBraces"/>
<module name="EmptyBlock">
<property name="option" value="text"/>
</module>
<!-- Disallows empty catch blocks (not even having a comment): https://checkstyle.sourceforge.io/config_blocks.html#EmptyCatchBlock -->
<module name="EmptyCatchBlock"/>
<!--
following rule enforces that there are no one line statements such as
public String getTabName() { return Localization.lang("XMP metadata"); }
-->
<module name="LeftCurly"/>
<module name="RightCurly"/>
<!-- coding - https://checkstyle.sourceforge.io/config_coding.html -->
<module name="AvoidDoubleBraceInitialization"/>
<module name="CovariantEquals"/>
<module name="MultipleVariableDeclarations"/>
<module name="OneStatementPerLine">
<property name="treatTryResourcesAsStatement" value="true"/>
</module>
<module name="UnnecessarySemicolonInTryWithResources"/>
<!-- Checks for common coding problems: https://checkstyle.org/config_coding.html -->
<module name="DeclarationOrder"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<!-- force a space after // for comments -->
<module name="TodoComment">
<property name="id" value="commentStartWithSpace"/>
<property name="format" value="^([^\s\/*])"/>
<message key="todo.match" value="Comment text should start with space."/>
</module>
<module name="MissingDeprecated"/>
<!-- Checks for illegal usage of reserved names as identifier names, such as "var", "record" - https://checkstyle.sourceforge.io/config_naming.html#IllegalIdentifierName -->
<module name="IllegalIdentifierName"/>
<module name="RecordTypeParameterNameCheck"/>
</module>
</module>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.checkstyle.org/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress checks="[a-zA-Z0-9]*" files="[\\/]generated[\\/]" />
<suppress checks="[a-zA-Z0-9]*" files="[\\/]src-gen[\\/]" />
<!-- We ignore this file because it's a modification of the original java code https://github.com/openjdk/jfx/blob/jfx15/modules/javafx.controls/src/main/java/javafx/scene/control/skin/TitledPaneSkin.java -->
<suppress checks="[a-zA-Z0-9]*" files="CustomTitledPaneSkin.java" />
</suppressions>

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