Skip to content

User Manual

This is the reference manual for somesy providing details about its configuration and behavior.

Before you proceed, make sure you have read the introduction and the quick-start guide.

Somesy Metadata Schemas

Because the same information is represented in different ways and more or less detail in different files, somesy requires to put all project information in a somesy-specific input section is located in a supported input file. Somesy will use this as the single source of truth for the supported project metadata fields and can synchronize this information into different target files.

Info

The somesy schemas are designed to allow expressing metadata in the most useful and rich form, i.e. the best form that some of the target formats supports.

Somesy project metadata consists of two main schemas - one schema for describing people (authors, maintainers, contributors), and a schema describing the project.

The somesy metadata fields (especially for people) are mostly based on Citation File Format 1.2, with some custom extensions. Somesy will try staying aligned with future revisions of CITATION.cff, unless for technical or practical reasons a deviation or extension is justified.

One useful distinction somesy does in contrast to many target formats is to allow stating all people in one place. If a person is both an author and a maintainer, that person does not need to be listed with all information twice.

This is done by adding the author and maintainer flags that can be set for every listed person. Somesy will take care of duplicating the entries where this is needed.

Furthermore somesy allows to provide more fine-grained information about the contribution of a person and acknowledge contributors that are neither full authors or maintainers.

Note

Detailed contribution information is synchronized to codemeta.json as CodeMeta roles. Other output formats may not support it.

Nevertheless, we encourage tracking granular contributor and contribution information in order to motivate and acknowledge also minor or invisible contributions to a projects.

Once CITATION.cff introduces corresponding mechanisms, somesy will be aligned with the corresponding capabilities. Furthermore, somesy might support the allcontributors tool as a target in the future.

Schemas Overview

Here is an overview of the schemas used in somesy.

The complete somesy input file (somesy.toml) or section (pyproject.toml).

Field Type Required? Default Description
project ProjectMetadata / PartialProjectMetadata yes Project metadata to be used and synchronized.
config SomesyConfig no somesy tool configuration (matches CLI flags).

Pydantic model for Project Metadata Input.

Field Type Required? Default Description
name str yes Project name.
description str yes Project description.
abstract str no Project abstract for CITATION.cff (defaults to description).
version str no Project version.
doi str no Project DOI.
license LicenseEnum / List[LicenseEnum] yes SPDX License string(s).
homepage Annotated no URL of the project homepage.
repository Annotated no URL of the project source code repository.
documentation Annotated no URL of the project documentation.
keywords List[str] no Keywords that describe the project.
people Person no Project authors, maintainers and contributors.
entities Entity no Project authors, maintainers and contributors as entities (organizations).

Metadata about a person in the context of a software project.

This schema is based on CITATION.cff 1.2, modified and extended for the needs of somesy.

Field Type Required? Default Description
email str no The person's email address.
alias str no The contributor's alias.
address str no The contributor's address.
city str no The entity's city.
country Country no The entity's country.
fax str no The person's fax number.
post_code str no The entity's post-code.
region str no The entity's region.
tel str no The entity's phone number.
author bool no false Indicates whether the entity is an author of the project (i.e. significant contributor).
publication_author bool no Indicates whether the entity is to be listed as an author in academic citations.
maintainer bool no false Indicates whether the entity is a maintainer of the project (i.e. for contact).
contribution str no Summary of how the entity contributed to the project.
contribution_types List[ContributionTypeEnum] no Relevant types of contributions (see https://allcontributors.org/docs/de/emoji-key).
contribution_begin date no Beginning date of the contribution.
contribution_end date no Ending date of the contribution.
orcid Annotated no The person's ORCID url (not required, but highly suggested).
family_names str yes The person's family names.
given_names str yes The person's given names.
name_particle str no The person's name particle, e.g., a nobiliary particle or a preposition meaning 'of' or 'from' (for example 'von' in 'Alexander von Humboldt').
name_suffix str no The person's name-suffix, e.g. 'Jr.' for Sammy Davis Jr. or 'III' for Frank Edwin Wright III.
affiliation str no The person's affiliation.

Metadata about an entity in the context of a software project ownership.

An entity, i.e., an institution, team, research group, company, conference, etc., as opposed to a single natural person. This schema is based on CITATION.cff 1.2, modified and extended for the needs of somesy.

Field Type Required? Default Description
email str no The person's email address.
alias str no The contributor's alias.
address str no The contributor's address.
city str no The entity's city.
country Country no The entity's country.
fax str no The person's fax number.
post_code str no The entity's post-code.
region str no The entity's region.
tel str no The entity's phone number.
author bool no false Indicates whether the entity is an author of the project (i.e. significant contributor).
publication_author bool no Indicates whether the entity is to be listed as an author in academic citations.
maintainer bool no false Indicates whether the entity is a maintainer of the project (i.e. for contact).
contribution str no Summary of how the entity contributed to the project.
contribution_types List[ContributionTypeEnum] no Relevant types of contributions (see https://allcontributors.org/docs/de/emoji-key).
contribution_begin date no Beginning date of the contribution.
contribution_end date no Ending date of the contribution.
date_end date no The entity's ending date, e.g., when the entity is a conference.
date_start date no The entity's starting date, e.g., when the entity is a conference.
location str no The entity's location, e.g., when the entity is a conference.
name str yes The entity's name.
website Annotated no The entity's website.
rorid Annotated no The entity's ROR ID url (not required, but highly suggested).

Pydantic model for somesy tool configuration.

Note that all fields match CLI options, and CLI options will override the values declared in a somesy input file (such as somesy.toml).

Field Type Required? Default Description
show_info bool no false Show basic information messages on run (-v flag).
verbose bool no false Show verbose messages on run (-vv flag).
debug bool no false Show debug messages on run (-vvv flag).
input_file Path no "somesy.toml" Project metadata input file path.
no_sync_pyproject bool no false Do not sync with pyproject.toml.
pyproject_file Path / List[Path] no "pyproject.toml" pyproject.toml file path.
no_sync_package_json bool no false Do not sync with package.json.
package_json_file Path / List[Path] no "package.json" package.json file path.
no_sync_julia bool no false Do not sync with Project.toml.
julia_file Path / List[Path] no "Project.toml" Project.toml file path.
no_sync_fortran bool no false Do not sync with fpm.toml.
fortran_file Path / List[Path] no "fpm.toml" fpm.toml file path.
no_sync_pom_xml bool no false Do not sync with pom.xml.
pom_xml_file Path / List[Path] no "pom.xml" pom.xml file path.
no_sync_mkdocs bool no false Do not sync with mkdocs.yml.
mkdocs_file Path / List[Path] no "mkdocs.yml" mkdocs.yml file path.
no_sync_rust bool no false Do not sync with Cargo.toml.
rust_file Path / List[Path] no "Cargo.toml" Cargo.toml file path.
no_sync_cff bool no false Do not sync with CFF.
cff_file Path / List[Path] no "CITATION.cff" CFF file path.
no_sync_codemeta bool no false Do not sync with codemeta.json.
codemeta_file Path / List[Path] no "codemeta.json" codemeta.json file path.
merge_codemeta bool no false Merge codemeta.json with with an existing codemeta.json file.
pass_validation bool no false Allow incomplete input and pass output validation.
packages Path / List[Path] no Packages (sub-folders) for monorepos with their own somesy config.

Metadata Mapping

From its own schema somesy must convert the information into the target formats. The following tables sketch how fields are mapped to corresponding other fields in some of the currently supported formats. Bold field names are mandatory, the others are optional.

Somesy Field Poetry Config PEP 621 [project] Java POM Julia Config Fortran Config package.json mkdocs.yml Rust Config CITATION.cff CodeMeta
given-names name(+email) name name name(+email) name(+email) name name(+email) name(+email) givenName name(+email)
family-names name(+email) name name name(+email) name(+email) name name(+email) name(+email) familyName name(+email)
email name(+email) email email name(+email) name(+email) email name(+email) name(+email) email name(+email)
orcid - - url - - url - - id -
(many others) - - - - - - - - (same) -
Somesy Field Poetry Config PEP 621 [project] Java POM Julia Config Fortran Config package.json mkdocs.yml Rust Config CITATION.cff CodeMeta
name name(+email) name name name(+email) name(+email) name name(+email) name(+email) givenName name(+email)
email name(+email) email email name(+email) name(+email) email name(+email) name(+email) email name(+email)
rorid - - url - - url - - - (never written) -
website - - url - - url - - id -
(many others) - - - - - - - - (same) -
Somesy Field Poetry Config PEP 621 [project] Java POM Julia Config Fortran Config package.json mkdocs.yml Rust Config CITATION.cff CodeMeta
name name name name name name name site_name name title name
description description description description - description description site_description description abstract description
abstract - - - - - - - - abstract -
doi - - - - - - - - doi identifier
license license license licenses.license - license license - license license license
version version version version version version version - version version version
author=true authors authors developers authors author author site_author authors authors author
maintainer=true maintainers maintainers - - maintainer maintainers - - contact maintainer
people - - - - - contributors - - - contributor
entities - - - - - contributors - - - contributor
keywords keywords keywords - - keywords keywords - keywords keywords keywords
homepage homepage urls.homepage urls - homepage homepage site_url homepage url url
repository repository urls.repository scm.url - - repository repo_url repository repository_code codeRepository
documentation documentation urls.documentation distributionManagement.site.url - - - - documentation - buildInstructions

If several license values are given, all of them are written: as a list in CITATION.cff and codemeta.json, as one <license> element each in pom.xml, and as an SPDX A OR B expression in pyproject.toml, package.json, Cargo.toml and fpm.toml.

If the somesy input has no homepage, repository or documentation, URLs already present in an output file are kept, not deleted.

In pom.xml, free-text <role> values are kept; somesy only manages roles that are somesy contribution types. In mkdocs.yml, repo_name is written as org/repo only when it is not already set, and site_name may be free text. Cargo.toml workspace inheritance (e.g. version.workspace = true) is kept and such values are ignored when harvesting.

Note that the mapping is often not 1-to-1. For example, CITATION.cff allows rich specification of author contact information and complex names. In contrast, poetry only supports a simple string with a name and email (like in git commits) to list authors and maintainers. Therefore somesy sometimes must do much more than just move or rename fields. This means that giving a clean and complete mapping overview is not feasible. In case of doubt or confusion, please open an issue or consult the somesy code.

Description and abstract

The description is a short, one-line summary of the project. For Python packages it becomes the package summary, which PyPI only accepts as a single line of at most 512 characters; somesy warns when the description synced into pyproject.toml breaks either rule.

For a longer text, such as a multi-paragraph abstract for citations, set the optional abstract field. It is only written to CITATION.cff (as abstract); all other files keep the short description. Without an abstract, CITATION.cff uses the description instead.

[project]
description = "Brief description of my amazing software."
abstract = """
A longer abstract of my amazing software.

It can span several paragraphs.
"""

CodeMeta Enrichment

When writing codemeta.json, Somesy first synchronizes the canonical metadata from somesy.toml. It then fills missing CodeMeta fields from enabled, configured language files and Git. This preserves the source priority:

somesy.toml > language file > Git history

The enrichment never replaces a CodeMeta field written from canonical Somesy metadata. When merge_codemeta is enabled, unrelated user-managed CodeMeta fields remain unchanged as well.

Source Enriched CodeMeta fields
pyproject.toml, lock file (uv.lock, poetry.lock or pdm.lock) Python runtime, direct dependencies, README URL, issue tracker, release notes
package.json JavaScript or TypeScript (when a tsconfig*.json is next to it), Node.js runtime, runtime/peer/optional dependencies, issue tracker
Cargo.toml, Project.toml, fpm.toml, pom.xml Programming language, runtime version where declared, dependencies
Git Repository, issue tracker for GitHub/GitLab remotes, nearest tag version, first and latest commit dates

Development and test dependencies are not included; neither PEP 735 [dependency-groups] nor [project.optional-dependencies] extras are treated as project requirements. A lock file only provides exact versions for dependencies declared by the project; transitive lock-file entries are not emitted. The nearest lock file at or above the pyproject.toml is used, so workspace members that share a lock file at the workspace root are covered. PyPI classifiers are kept in pyproject.toml because CodeMeta has no reliable equivalent.

[project.urls] key names are not standardized by PEP 621. Common spellings are recognized regardless of capitalization and separators: Issues, Issue Tracker, Bug Tracker, Bug Reports and Bugs fill issueTracker, while Changelog, Changes, Release Notes and History fill releaseNotes. When syncing homepage, repository and documentation into [project.urls], somesy likewise updates an entry that already exists under a different spelling instead of adding a second one.

The first commit date requires complete Git history. In a shallow clone, Somesy omits dateCreated rather than reporting the shallow boundary as the project creation date. For reproducible generated metadata in CI, configure a full checkout (for GitHub Actions, fetch-depth: 0).

PEP 621 dynamic fields

For pyproject.toml targets using the PEP 621 [project] table (uv, hatchling, flit, PDM, setuptools) as well as for Poetry v2, somesy respects the PEP 621 dynamic field. If version or description is listed in dynamic, it means the value is provided at build time rather than written statically in the file. In this case somesy will:

  • skip validation of that field (it is not required to be present in the file), and
  • not overwrite the field during sync, logging a warning instead.

For example, if your pyproject.toml contains:

[project]
name = "my-package"
dynamic = ["version", "description"]

somesy will sync all other managed fields as usual but leave version and description untouched, because they are expected to be set dynamically at build time.

people and entities are mapped to authors/maintainers/contributors depending on the output format. Both fields are marked as necessary but what somesy need is an author either in people or entities.

When an entity has a ror id but no website set, url related fields will be filled with the ROR URL (this is also the website in CITATION.cff, which never contains a rorid key).

The somesy CLI tool

You can see all supported somesy CLI command options using somesy --help:

somesy sync --help
                                                                                
 Usage: somesy sync [OPTIONS] COMMAND [ARGS]...                                 
                                                                                
 Sync project metadata input with metadata files.                               

╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --input-file           -i                 <file>       Somesy input file     │
│                                                        path (default:        │
│                                                        discovered)           │
│ --no-sync-pyproject    -P                              Do not sync           │
│                                                        pyproject.toml file   │
│                                                        (default: False)      │
│ --pyproject-file       -p                 <file>       Existing              │
│                                                        pyproject.toml file   │
│                                                        path(s) (default:     │
│                                                        pyproject.toml)       │
│ --no-sync-package-js…  -J                              Do not sync           │
│                                                        package.json file     │
│                                                        (default: False)      │
│ --package-json-file    -j                 <file>       Existing package.json │
│                                                        file path(s)          │
│                                                        (default:             │
│                                                        package.json)         │
│ --no-sync-julia        -L                              Do not sync           │
│                                                        Project.toml (Julia)  │
│                                                        file (default: False) │
│ --julia-file           -l                 <file>       Custom Project.toml   │
│                                                        (Julia) file path(s)  │
│                                                        (default:             │
│                                                        Project.toml)         │
│ --no-sync-fortran      -F                              Do not sync fpm.toml  │
│                                                        (Fortran) file        │
│                                                        (default: False)      │
│ --fortran-file         -f                 <file>       Custom fpm.toml       │
│                                                        (Fortran) file        │
│                                                        path(s) (default:     │
│                                                        fpm.toml)             │
│ --no-sync-pomxml       -X                              Do not sync pom.xml   │
│                                                        (Java Maven) file     │
│                                                        (default: False)      │
│ --pomxml-file          -x                 <file>       Custom pom.xml (Java  │
│                                                        Maven) file path(s)   │
│                                                        (default: pom.xml)    │
│ --no-sync-mkdocs       -D                              Do not sync           │
│                                                        mkdocs.yml file       │
│                                                        (default: False)      │
│ --mkdocs-file          -d                 <file>       Custom mkdocs.yml     │
│                                                        file path(s)          │
│                                                        (default: mkdocs.yml) │
│ --no-sync-rust         -R                              Do not sync           │
│                                                        Cargo.toml file       │
│                                                        (default: False)      │
│ --rust-file            -r                 <file>       Custom Cargo.toml     │
│                                                        file path(s)          │
│                                                        (default: Cargo.toml) │
│ --no-sync-cff          -C                              Do not sync           │
│                                                        CITATION.cff file     │
│                                                        (default: False)      │
│ --cff-file             -c                 <file>       CITATION.cff file     │
│                                                        path(s) (default:     │
│                                                        CITATION.cff)         │
│ --no-sync-codemeta     -M                              Do not sync           │
│                                                        codemeta.json file    │
│                                                        (default: False)      │
│ --codemeta-file        -m                 <file>       Custom codemeta.json  │
│                                                        file path(s)          │
│                                                        (default:             │
│                                                        codemeta.json)        │
│ --merge                    --overwrite                 Merge codemeta.json   │
│                                                        with with an existing │
│                                                        codemeta.json file    │
│                                                        (default: False)      │
│                                                        [default: overwrite]  │
│ --pass-validation      -V                              Allow incomplete      │
│                                                        input and pass output │
│                                                        validation (default:  │
│                                                        False)                │
│ --packages             -k                 <directory>  Packages (subfolders) │
│                                                        for monorepos with    │
│                                                        their own somesy      │
│                                                        config.               │
│ --help                                                 Show this message and │
│                                                        exit.                 │
╰──────────────────────────────────────────────────────────────────────────────╯

Everything that can be configured as a CLI flag can also be set in a somesy.toml file in the [config] section. CLI arguments set in an input file override the defaults, while options passed as CLI arguments override the configuration. The -P shortcut disables pyproject synchronization, while -V passes output validation.

Synchronization only writes a target when its parsed metadata changes. Formatter choices such as indentation, wrapping, quotes, comments, and mapping-key order are therefore preserved; list order and scalar values remain significant.

Initialize a project

Use somesy init to create a standalone somesy.toml from an existing project:

somesy init

Initialization reads metadata from all supported project files present in the current directory and harvests project information and authors from Git history. The harvested values are merged into Somesy’s general metadata model before the file is written.

Only missing required values are requested interactively:

  • project name
  • project description
  • SPDX license
  • one author, as either a person or an entity

For a person, the command asks for given names, family names, and optionally an email address. For an entity, it asks for the organization name and optionally an email address. Git authors count as project authors; therefore, the author prompt is shown only when no author was found in the harvested metadata.

For scripts, use somesy init --non-interactive. It never prompts, warns about any missing required values, and writes the harvested metadata. To synchronize an incomplete file, explicitly use somesy sync --pass-validation or set pass_validation = true in the config; missing values are omitted from output.

Git bot accounts (names ending in [bot]) are skipped. Git authors with a single-word name are not added, with a warning; add them manually.

Detected project files are enabled as synchronization targets. Targets that are not present are disabled in the generated [config] section. The generated file is not overwritten by default (somesy fails before prompting if it exists):

somesy init --output-file path/to/somesy.toml
somesy init --overwrite

Use somesy init config when you want to configure synchronization options manually instead of deriving them from the files in the project.

Update project metadata

Use somesy set to update one scalar project-metadata value in an existing somesy.toml file:

somesy set version 1.2.3

The command supports name, description, abstract, version, license, homepage, repository, and documentation. It does not update structured values such as keywords, people, or entities.

Without an input file specifically provided, somesy will check if it can find a valid

  • .somesy.toml
  • somesy.toml
  • pyproject.toml (in tool.somesy section)
  • Project.toml (in tool.somesy section)
  • fpm.toml (in tool.somesy section)
  • package.json (in somesy section)
  • Cargo.toml (in package.metadata.somesy section)

which is located in the current working directory. If you want to provide the somesy input file from a different location, you can pass it with the -i option. If the file passed with -i does not exist, somesy logs a warning and falls back to this discovery. somesy set uses the same discovery when -i is not given.

Somesy Input File

Here is an example how project metadata and somesy can be configured using one of the supported input formats:

[project]
name = "my-amazing-project"
version = "0.1.0"
description = "Brief description of my amazing software."

keywords = ["some", "descriptive", "keywords"]
license = ["MIT", "Apache-2.0"]
repository = "https://github.com/username/my-amazing-project"

# This is you, the proud author of your project:
[[project.people]]
given-names = "Jane"
family-names = "Doe"
email = "j.doe@example.com"
orcid = "https://orcid.org/0000-0000-0000-0001"
author = true      # is a full author of the project (i.e. appears in citations)
maintainer = true  # currently maintains the project (i.e. is a contact person)

# this person is an acknowledged contributor, but not author or maintainer:
[[project.people]]
given-names = "Another"
family-names = "Contributor"
email = "a.contributor@example.com"
orcid = "https://orcid.org/0000-0000-0000-0002"
# ... but for scientific publications, this contributor should be listed as author:
publication_author = true

# add an organization as a maintainer
[[project.entities]]
name = "My Super Organization"
email = "info@my-super-org.com"
website = "https://my-super-org.com"
rorid = "https://ror.org/02nv7yv05" # highly recommended set a ror id for your organization

[config]
verbose = true     # show detailed information about what somesy is doing
[project] # or [tool.poetry] in case of poetry version 1
name = "my-amazing-project"
version = "0.1.0"
...

[tool.somesy.project]
name = "my-amazing-project"
version = "0.1.0"
description = "Brief description of my amazing software."

keywords = ["some", "descriptive", "keywords"]
license = ["MIT", "Apache-2.0"]
repository = "https://github.com/username/my-amazing-project"

# Multiple licenses are supported; single-value targets use the first one.

# This is you, the proud author of your project
[[tool.somesy.project.people]]
given-names = "Jane"
family-names = "Doe"
email = "j.doe@example.com"
orcid = "https://orcid.org/0000-0000-0000-0001"
author = true      # is a full author of the project (i.e. appears in citations)
maintainer = true  # currently maintains the project (i.e. is a contact person)

# this person is a acknowledged contributor, but not author or maintainer:
[[tool.somesy.project.people]]
given-names = "Another"
family-names = "Contributor"
email = "a.contributor@example.com"
orcid = "https://orcid.org/0000-0000-0000-0002"

# add an organization as a maintainer
[[tool.somesy.project.entities]]
name = "My Super Organization"
email = "info@my-super-org.com"
website = "https://my-super-org.com"
rorid = "https://ror.org/02nv7yv05" # highly recommended set a ror id for your organization

[tool.somesy.config]
verbose = true     # show detailed information about what somesy is doing

Support for mono-repos and multi-package projects

A research software project might have multiple packages in the root repository. These packages might be in the same or different software languages or frameworks. somesy currently supports synchronizing multiple output files from one somesy project metadata input.

Sync from one somesy input

This is the case where you have only one somesy metadata set in your root folder. Output files can be set in the somesy config section.

[project]
...

[config]
pass_validation = true
package_json_file = ['package.json', 'package1/package.json']
pyproject_toml_file = 'package2/pyproject.toml'

Warning

Each output file, such as package.json file, have its required fields and these fields are enforced by somesy. However, in case of mono-repos or multi-package repositories, some of the fields could be omitted, such as version. For pyproject.toml files, the preferred solution is to list those fields under dynamic (e.g. dynamic = ["version"]) — somesy will then skip validation and sync for those fields. For other formats, or as a last resort, you can set pass_validation to true in the somesy config to bypass validation entirely. somesy will fail otherwise.

The example above shows a project with a package.json file in the root folder and 2 packages in it. Three files are set here so all of them will be updated according to ground truth of somesy project metadata.

Note

Let's remember somesy will create a CITATION.CFF and codemeta.json file in the root folder if it is set otherwise either by cli or by config.

Packages (sub-modules) with their own somesy file

A project with multiple packages inside can have completely different metadata such version and authors. Therefore, each package should have a separate metadata, in other words, separate somesy config and project metadata.

[project]
...

[config]
packages = ['package1', 'package2', 'package3']

packages (or --packages/-k on the command line) takes directories. Each package's own [config] is the base; only options explicitly passed on the root command line override it. Values from the root config file are not inherited.

Each of these packages (sub-folders) are assumed to have separate somesy metadata in the folder. These packages could be a somesy supported language/framework or it could be any other language. somesy will create at least CITATION.CFF and codemeta.json regardless if not instructed otherwise.