ResearchSoftwareMetadata documentation
Documentation for ResearchSoftwareMetadata.
Summary
ResearchSoftwareMetadata is a Julia package that provides a crosswalk between Project.toml, codemeta.json, .zenodo.json and the package LICENSE file, giving a consistent way of providing metadata for research software, so that the Julia General Registry, GitHub and Zenodo all pick up the same metadata, following the Research Software MetaData guidelines.
Installation
The package is registered in the General registry so can be built and installed with add. For example:
(@v1.12) pkg> add ResearchSoftwareMetadata
Resolving package versions...
Updating `~/.julia/environments/v1.12/Project.toml`
[58378933] + ResearchSoftwareMetadata v0.4.0
Updating `~/.julia/environments/v1.12/Manifest.toml`
(@v1.12) pkg>Usage
The crosswalk runs on a package that is a git repository with a remote. The one piece of metadata it cannot do without is a license. To capture the license you are using and propagate it throughout the metadata files and through your julia code, add an SPDX license identifier to your Project.toml file:
license = "BSD-2-Clause"A package has to have a license: the crosswalk stops with an error if it finds none, or one that is not an identifier from that list. You can also set the license when you run the crosswalk, as shown below.
If the package has no license file, the crosswalk writes a LICENSE for that license, naming the people in the authors field of Project.toml as the copyright holders, so make sure authors is right first. A license file you already have is left exactly as it is, provided it holds that license.
The crosswalk records the license on the first line of every julia file, as # SPDX-License-Identifier: BSD-2-Clause. If some files are deliberately under a different license, give each of them its own first line naming that license, and list those licenses in the [rsmd] table described below, so that the crosswalk knows they are intended and leaves them alone:
[rsmd]
additional_licenses = ["MIT"]A file marked with a license that is neither the package's nor in that list stops the crosswalk with an error.
Then, from the root of your package, you can just run a crosswalk:
using Pkg
# Create a new project with ResearchSoftwareMetadata in it
Pkg.activate(temp = true)
Pkg.add("ResearchSoftwareMetadata")
# Carry out a crosswalk between the different metadata formats
using ResearchSoftwareMetadata
ResearchSoftwareMetadata.crosswalk()The first crosswalk writes codemeta.json and .zenodo.json, and creates an [rsmd] table in Project.toml, which is where all of the other metadata that this package uses lives. It warns about whatever it still needs for a complete record: work through those warnings as described below, running the crosswalk again until there are none.
The crosswalk makes an [[rsmd.author_details]] block for each person in the authors field. To supplement the metadata on the authors of the package, add to those blocks the ORCID for each author and the ROR for the organisation(s) they are affiliated with. You can add as many authors and as much or as little information as you like about each one by adding additional [[rsmd.author_details]] blocks.
[rsmd]
[[rsmd.author_details]]
name = "Richard Reeve"
orcid = "0000-0003-2589-8091"
[[rsmd.author_details.affiliation]]
ror = "00vtgdb53"The crosswalk warns until the package has a description and the software category it belongs to. You can also add keywords associated with the package, its repostatus.org development_status, and the DOIs of any publications associated with it; if you do not, the keywords start as ["julia"] and the development status as "active". All of these are propagated into codemeta.json and .zenodo.json, and any values already in codemeta.json but missing from Project.toml will be backfilled into it. Any of these keys found at the top level of Project.toml (the old layout) are automatically migrated into [rsmd]:
[rsmd]
keywords = ["julia", "metadata"]
category = "metadata"
description = "A package that does things"
development_status = "active"
publications = ["10.5281/zenodo.12789179"]The crosswalk also warns until it has been told where the build instructions for the package are, which you do once, when you run it: build = true if they are in the README, or their address if they are somewhere else.
If you want to pass in some additional metadata (the category of the software or the keywords associated with it, both of which are written back into [rsmd] in Project.toml, or its license), or you want to increase the package version during the crosswalk, you can do that as follows:
# Say that the build instructions are in the README
ResearchSoftwareMetadata.crosswalk(build = true)
# Add in additional metadata
ResearchSoftwareMetadata.crosswalk(category = "metadata", keywords = ["julia", "metadata", "research software", "RSMD"])
# Set the license, or change it
ResearchSoftwareMetadata.crosswalk(license = "BSD-2-Clause")
# Increase version number during crosswalk
ResearchSoftwareMetadata.increase_patch() # Bump patch version (e.g. 0.4.1 -> 0.4.2)
ResearchSoftwareMetadata.increase_minor() # Bump minor version (e.g. 0.4.2 -> 0.5.0)
ResearchSoftwareMetadata.increase_major() # Bump major version (e.g. 0.5.0 -> 1.0.0)If you later change the metadata in Project.toml on purpose (a new description or keywords, a removed author, a different license), run the crosswalk with update = true so that it knows the change is intended:
ResearchSoftwareMetadata.crosswalk(update = true)The change is then carried into the other files and reported as information. Without update = true the crosswalk treats a disagreement between Project.toml and the other files as a possible mistake: it still brings the other files into line, but reports each change as a warning or an error, and it refuses a changed license altogether, rewriting nothing, because a license should never change by accident. The increase_patch(), increase_minor() and increase_major() functions run the crosswalk with update = true themselves.
To move a package to a different license, or to start again when its licensing has got into a tangle, use relicense!:
# Move the package to a new license
ResearchSoftwareMetadata.relicense!("MIT")
# Put everything under the new license, whatever it was under before
ResearchSoftwareMetadata.relicense!("MIT", overwrite_all = true)The first form is the same as crosswalk(license = "MIT"): files listed under additional_licenses keep their own license, and a file marked with a license you have not declared still stops it. The second form overrides all of that: it removes additional_licenses, replaces every license file with a newly written LICENSE, and marks every julia file with the new license. It relabels files whoever wrote them, so make sure you are entitled to relicense them first.
You might also consider reformatting all of your julia code to a consistent format. A .JuliaFormatter.toml file in the package root defines what the formatting standard should be. From the root of your package:
Pkg.add("JuliaFormatter")
using JuliaFormatter
format(".")Automated checking
You can also make your package's own test suite check automatically that the metadata crosswalk is clean and the code is well formatted, by copying a few files from this package's test/ directory into your own. See Automated package checks for instructions.
Reference guide
These are the functions to call. None of them is exported, so each is called by its full name, such as ResearchSoftwareMetadata.crosswalk().
ResearchSoftwareMetadata.ResearchSoftwareMetadata — Module
ResearchSoftwareMetadataResearchSoftwareMetadata provides a crosswalk between Project.toml, codemeta.json, .zenodo.json and the package LICENSE file, so that consistent research software metadata can be picked up from a package by Julia's General registry, GitHub and Zenodo, following the FAIR-IMPACT Research Software MetaData (RSMD) guidelines. Project.toml is treated as the authoritative source of metadata wherever possible.
The entry points are ResearchSoftwareMetadata.crosswalk(), which enforces consistency across the metadata files and the julia source code, and ResearchSoftwareMetadata.increase_patch(), ResearchSoftwareMetadata.increase_minor() and ResearchSoftwareMetadata.increase_major(), which bump the package version and then re-run the crosswalk, and ResearchSoftwareMetadata.relicense!(), which moves the package to a new license.
ResearchSoftwareMetadata.crosswalk — Function
crosswalk(git_dir; category = nothing, keywords = nothing,
license = nothing, build = false, update = false)Run a crosswalk across Project.toml, codemeta.json, .zenodo.json, the license file and the julia source files of a package, to enforce consistency between the different metadata formats, and return nothing.
Project.toml is the authoritative source of metadata: as well as its standard fields, the optional keys description, keywords, category, development_status and publications (a vector of DOIs of associated papers) in its [rsmd] table are propagated into codemeta.json and .zenodo.json; values found only in codemeta.json are backfilled into Project.toml. Legacy top-level copies of these keys are migrated into [rsmd]. The crosswalk logs warnings and errors if it identifies inconsistencies while it is editing the files.
Arguments
git_dir: the repository holding the package. It defaults to the repository that the working directory is in.category: the software category. It takes precedence over the one inProject.tomland is written back into it.keywords: a vector of keyword strings, which likewise takes precedence and is written back.license: an SPDX identifier such as"MIT", to set the license of the package or to change it. It is written back intoProject.toml.build: where the build instructions are, for thebuildInstructionsRSMD field.falseleaves the instructions as is,truesets it to the same as the README, and a string sets it to that value.update: if true, changes toProject.toml(e.g. to the version or the license) are treated as deliberate and propagated to the other metadata files with@infomessages instead of being reported as warnings or errors.
Authors
A missing author_details section in [rsmd] is constructed from codemeta.json or .zenodo.json, provided the information there is consistent with the definitive authors field, and otherwise from authors itself. New entries in authors are propagated into rsmd.author_details (with a warning to add their ORCID and ROR affiliation there), codemeta.json and .zenodo.json, while authors in codemeta.json that are missing from authors are removed with an error.
License
The license is an SPDX identifier, taken from the license argument, from license in Project.toml or, failing that, from codemeta.json; the crosswalk throws an error if there is none or if it is not one SPDX recognises. A license in Project.toml that differs from the one already in codemeta.json is an error, and nothing is changed, unless update is true or the license argument is given.
If the package has no license file, a LICENSE is written. A license file that the crosswalk did not write is left as it is if it holds the license, and is an error if it does not, unless the license is being changed.
Every julia source file is given a first line naming the license. A file that is deliberately under a different license keeps its own first line, provided that license is listed under additional_licenses in the [rsmd] table; a file marked with any other license is an error, and nothing is changed.
Dates
The dates of a version that has no release tag yet are today's date, in UTC, whenever the crosswalk is run on the repository's default branch or with update true; on any other branch the dates already recorded for that version are kept.
Failure
If any remote metadata query (orcid.org, ror.org, spdx.org, doi.org or Julia's General registry) cannot be completed, the crosswalk throws an error and all files are left in their original state.
ResearchSoftwareMetadata.relicense! — Function
relicense!(license, git_dir; overwrite_all = false)Relicense a package, and run a crosswalk to carry the change into every metadata file.
Arguments
license: the SPDX identifier of the new license, such as"MIT".git_dir: the repository holding the package. It defaults to the repository that the working directory is in.overwrite_all: if true, replace every existing license file and source file header and dropadditional_licenses, keeping nothing of the existing licensing. The default, false, respects what the package has declared.
Keeping or overwriting the existing licensing
As it stands this is crosswalk(git_dir, license = license): Project.toml, codemeta.json and .zenodo.json take the new license, the LICENSE file is written for it, and the julia source files that were marked with the old license are marked with the new one. Files marked with one of the additional_licenses of the [rsmd] table are left as they are, and the crosswalk still stops, changing nothing, if a file is marked with a license that has not been declared.
If overwrite_all is true, nothing about the existing licensing is kept, and none of it can stop the crosswalk: additional_licenses is removed, every license file (LICENSE, LICENCE or COPYING, with or without a .md or .txt extension) is removed and LICENSE written in their place, even where one already held license in its own words, and every julia source file is marked with license whatever it was marked with before. This is the way out when the licensing of a repository has become inconsistent, and the way to hand over a license file of your own to be maintained by the crosswalk. It relabels files regardless of who wrote them, so whether they may be relicensed is for you to establish first; what it replaces can be recovered from git if it had been committed.
Failure
The crosswalk throws an error, and nothing is changed, if license is not an identifier SPDX recognises or a remote metadata query cannot be completed.
ResearchSoftwareMetadata.increase_patch — Function
increase_patch(git_dir)Increase the version number in the Project.toml of a package by a patch (e.g. 0.4.1 to 0.4.2), and then run ResearchSoftwareMetadata.crosswalk(git_dir, update = true) to propagate the new version to the other metadata files. If the crosswalk fails, Project.toml is left as it was.
Arguments
git_dir: the repository holding the package. It defaults to the repository that the working directory is in.
ResearchSoftwareMetadata.increase_minor — Function
increase_minor(git_dir)Increase the version number in the Project.toml of a package by a minor number (e.g. 0.4.1 to 0.5.0), and then run ResearchSoftwareMetadata.crosswalk(git_dir, update = true) to propagate the new version to the other metadata files. If the crosswalk fails, Project.toml is left as it was.
Arguments
git_dir: the repository holding the package. It defaults to the repository that the working directory is in.
ResearchSoftwareMetadata.increase_major — Function
increase_major(git_dir)Increase the version number in the Project.toml of a package by a major number (e.g. 0.4.1 to 1.0.0), and then run ResearchSoftwareMetadata.crosswalk(git_dir, update = true) to propagate the new version to the other metadata files. If the crosswalk fails, Project.toml is left as it was.
Arguments
git_dir: the repository holding the package. It defaults to the repository that the working directory is in.
Internals
Everything else in the package is internal: it is documented here for those working on the package itself, and may change without notice.
ResearchSoftwareMetadata.ResearchSoftwareMetadataResearchSoftwareMetadata.author_details_consistentResearchSoftwareMetadata.author_details_from_codemetaResearchSoftwareMetadata.author_details_from_zenodoResearchSoftwareMetadata.base_identifierResearchSoftwareMetadata.called_workflowResearchSoftwareMetadata.check_doiResearchSoftwareMetadata.crosswalkResearchSoftwareMetadata.default_branchResearchSoftwareMetadata.describe_license_filesResearchSoftwareMetadata.expression_valuesResearchSoftwareMetadata.get_ci_workflowResearchSoftwareMetadata.get_first_release_dateResearchSoftwareMetadata.get_license_from_spdxResearchSoftwareMetadata.get_organisation_from_rorResearchSoftwareMetadata.get_os_from_workflowsResearchSoftwareMetadata.get_person_from_orcidResearchSoftwareMetadata.has_triggerResearchSoftwareMetadata.header_changesResearchSoftwareMetadata.header_licensesResearchSoftwareMetadata.holds_licenseResearchSoftwareMetadata.increase_majorResearchSoftwareMetadata.increase_minorResearchSoftwareMetadata.increase_patchResearchSoftwareMetadata.is_generatedResearchSoftwareMetadata.job_runnersResearchSoftwareMetadata.license_file_changesResearchSoftwareMetadata.license_filesResearchSoftwareMetadata.license_textResearchSoftwareMetadata.licenses_foundResearchSoftwareMetadata.matrix_contextResearchSoftwareMetadata.migrate_rsmd!ResearchSoftwareMetadata.on_default_branchResearchSoftwareMetadata.order_projectResearchSoftwareMetadata.parse_authorResearchSoftwareMetadata.project_key_orderResearchSoftwareMetadata.read_jsonResearchSoftwareMetadata.read_projectResearchSoftwareMetadata.read_workflowsResearchSoftwareMetadata.reconcile!ResearchSoftwareMetadata.release_tagsResearchSoftwareMetadata.relicense!ResearchSoftwareMetadata.repository_urlResearchSoftwareMetadata.runner_labelsResearchSoftwareMetadata.runner_osResearchSoftwareMetadata.runs_testsResearchSoftwareMetadata.source_filesResearchSoftwareMetadata.spdx_identifierResearchSoftwareMetadata.split_nameResearchSoftwareMetadata.utc_todayResearchSoftwareMetadata.workflow_inputsResearchSoftwareMetadata.workflow_runners
ResearchSoftwareMetadata.author_details_consistent — Method
ResearchSoftwareMetadata.author_details_consistent(details, proj_authors)Check whether a reconstructed author_details array is consistent with the definitive authors entries in Project.toml. Every entry must match an author string by name (and email when it has one), and the counts must agree.
ResearchSoftwareMetadata.author_details_from_codemeta — Method
ResearchSoftwareMetadata.author_details_from_codemeta(cm_authors)Reconstruct a Project.toml author_details array from the author array of a codemeta.json file. Each entry contains a name, plus an orcid, an email and an affiliation array where available.
ResearchSoftwareMetadata.author_details_from_zenodo — Method
ResearchSoftwareMetadata.author_details_from_zenodo(creators)Reconstruct a Project.toml author_details array from the creators array of a .zenodo.json file. Each entry contains a name (reversing Zenodo's "Family, Given" format), plus an orcid and an affiliation array where available. Zenodo does not record email addresses.
ResearchSoftwareMetadata.base_identifier — Method
ResearchSoftwareMetadata.base_identifier(license::AbstractString)Return an SPDX identifier without the -only, -or-later or + that says which versions of a license apply. The text of a license is the same whichever is meant, so a license file can only be matched this far.
ResearchSoftwareMetadata.called_workflow — Method
ResearchSoftwareMetadata.called_workflow(job::AbstractDict,
git_dir::AbstractString,
depth::Int)Return the reusable workflow a job calls, or nothing if the job calls none that can be read: only a workflow in the same repository can be, and only while fewer than MAX_WORKFLOW_DEPTH have been followed to reach the job, which depth counts.
ResearchSoftwareMetadata.check_doi — Method
ResearchSoftwareMetadata.check_doi(doi::String)Check that a DOI resolves by querying the doi.org handle API. Returns true if it resolves and false if it does not exist. Throws an error if doi.org cannot be reached or returns an unexpected HTTP status.
ResearchSoftwareMetadata.default_branch — Method
ResearchSoftwareMetadata.default_branch(git_dir::AbstractString,
remote::AbstractString)Return the name of the default branch of a remote of the repository at git_dir, or nothing if it cannot be found. The remote itself is asked, which is the only sure answer. If it cannot be reached, the default branch that the repository recorded when it was cloned is used, if there is one.
ResearchSoftwareMetadata.describe_license_files — Method
ResearchSoftwareMetadata.describe_license_files(git_dir::AbstractString)Return sentences saying which licenses the license files of the repository at git_dir hold, and for a file holding a single license how to declare it, to help a package that has declared none. The string is empty if there are no license files or none can be recognised.
ResearchSoftwareMetadata.expression_values — Method
ResearchSoftwareMetadata.expression_values(value, context::AbstractDict)Return the values an entry of a GitHub workflow can take, as strings. A literal is its own only value; a single ${{ matrix.x }} or ${{ inputs.x }} reference takes the values context holds under "matrix.x" or "inputs.x"; a list takes the values of all of its elements that can be determined. Returns nothing when no value can be determined: for any other expression, a reference context does not hold, a mapping or an empty entry.
ResearchSoftwareMetadata.get_ci_workflow — Function
ResearchSoftwareMetadata.get_ci_workflow(git_dir)Return the file name of the GitHub workflow that carries out continuous integration for the repository at git_dir, or nothing if there is none. It is a workflow that runs in its own right, not only when called by another, and that either has a job running the package's tests (see ResearchSoftwareMetadata.runs_tests) or is named testing or CI. Where there are several, a workflow that runs the tests is chosen over one that does not, then one started by a pull request, then one started by a push, then one named testing, then one named CI, then the first in file name order.
ResearchSoftwareMetadata.get_first_release_date — Function
ResearchSoftwareMetadata.get_first_release_date()Returns the first release date of this package on Julia's General Registry, or nothing if the package has not been registered. The date is that of the repository's tag for the release. Throws an error if the repository has no such tag, or if the registry cannot be reached or returns an unexpected HTTP status.
ResearchSoftwareMetadata.get_license_from_spdx — Method
ResearchSoftwareMetadata.get_license_from_spdx(license::AbstractString)Take an SPDX license identifier and query spdx.org to return a Dict containing its record, including the text of the license under licenseText and whether the OSI approves it under isOsiApproved, or nothing if spdx.org has no license with that identifier. Throws an error if spdx.org cannot be reached or returns an unexpected HTTP status.
ResearchSoftwareMetadata.get_organisation_from_ror — Method
ResearchSoftwareMetadata.get_organisation_from_ror(ror::String)Take a ROR from the user and query the ror.org API to return a Dict containing the relevant metadata or nothing if no such ROR exists. Throws an error if ror.org cannot be reached or returns an unexpected HTTP status.
ResearchSoftwareMetadata.get_os_from_workflows — Function
ResearchSoftwareMetadata.get_os_from_workflows(git_dir)Return the sorted names of the operating systems ("Linux", "Windows", "macOS") that the GitHub workflows of the repository at git_dir run the package's tests on, which are presumed to be the ones the software runs on. If the jobs that run the tests give none, whether because no job is recognised as running them or because their runners cannot be determined, the operating systems of every job are returned in their place. The list is empty if the repository has no workflows.
A job runs the tests if it uses the julia-actions/julia-runtest action or calls Pkg.test in a script. Each job's runs-on may be a runner label, a list of labels or a runner group, and may refer to the job's matrix (${{ matrix.os }}, including values given under include) or to a workflow input (${{ inputs.os }}). A job that calls a reusable workflow in the same repository counts the runners of that workflow. A job whose operating system cannot be determined is reported and otherwise ignored: one that uses any other expression, a self-hosted runner whose labels name no operating system, or a reusable workflow from another repository. Matrix exclude entries and if conditions are not taken into account.
ResearchSoftwareMetadata.get_person_from_orcid — Method
ResearchSoftwareMetadata.get_person_from_orcid(orcid::String)Take an ORCID from the user and query the orcid.org API to return a Dict containing the relevant metadata or nothing if no such ORCID exists. Throws an error if orcid.org cannot be reached or returns an unexpected HTTP status.
ResearchSoftwareMetadata.has_trigger — Method
ResearchSoftwareMetadata.has_trigger(workflow::AbstractDict,
name::AbstractString)Check whether a GitHub workflow is started by the event name, such as workflow_call. The workflow's on entry may be a single event, a list of events or a mapping from events to their settings.
ResearchSoftwareMetadata.header_changes — Method
ResearchSoftwareMetadata.header_changes(git_dir::AbstractString,
license::AbstractString;
additional::AbstractVector = String[],
previous::AbstractVector = String[],
overwrite::Bool = false)Return the julia source files of the repository at git_dir whose first line has to change for the package to be licensed under license, as file => new content pairs. Nothing is written.
A file without an SPDX header gains one for license, followed by a blank line, and an empty file becomes the header alone. A header is left as it is if every license it names is license or one of the additional licenses the package declares. A header naming one of the previous licenses, which the package is being moved from, is changed to license. A header naming any other license is an error, listing every such file, since changing it would change the licensing of the file. If overwrite is set, every header is changed to license whatever it names. Pluto notebooks, whose first line Pluto needs, are passed over.
ResearchSoftwareMetadata.header_licenses — Method
ResearchSoftwareMetadata.header_licenses(expression::AbstractString)Return the license identifiers named in the SPDX expression of a source file header: the one identifier of a plain header, and each of those joined by AND or OR in a compound one. The exception that follows a WITH is not a license and is left out.
ResearchSoftwareMetadata.holds_license — Method
ResearchSoftwareMetadata.holds_license(file::AbstractString,
license::AbstractString)Check whether the text of license, an SPDX identifier, is found in a file, whichever versions of it the identifier allows.
ResearchSoftwareMetadata.is_generated — Method
ResearchSoftwareMetadata.is_generated(file::AbstractString,
generated::AbstractVector)Check whether a license file is one this package wrote: whether its text is one of the generated texts, apart from the copyright years.
ResearchSoftwareMetadata.job_runners — Method
ResearchSoftwareMetadata.job_runners(job::AbstractDict,
context::AbstractDict,
git_dir::AbstractString, depth::Int;
tests_only::Bool = false)Return the runner labels a workflow job can run on, or nothing if they cannot be determined. A job that calls a reusable workflow in the same repository runs on that workflow's runners, given the inputs the job passes to it, and on only those of its jobs that run the package's tests if tests_only is set; a reusable workflow in another repository cannot be read. depth counts the reusable workflows followed to reach the job.
ResearchSoftwareMetadata.license_file_changes — Method
ResearchSoftwareMetadata.license_file_changes(git_dir::AbstractString,
license::AbstractString,
generated::AbstractVector;
replace::Bool,
overwrite::Bool = false)Decide what a crosswalk does to the license files of the repository at git_dir, whose license is the SPDX identifier license, and return it as (write, remove): whether to write a generated LICENSE, and the files to remove. Nothing is written or removed here.
A file this package wrote itself (see ResearchSoftwareMetadata.is_generated, with the texts it could have written in generated) is written afresh. Any other file that contains license belongs to the user and is left as it is, in which case no LICENSE is written beside it. A file that does not contain license is removed if replace is set, and is otherwise an error, since replacing it would change the licensing of the repository. If overwrite is set none of that applies: every license file is removed and LICENSE written.
ResearchSoftwareMetadata.license_files — Method
ResearchSoftwareMetadata.license_files(git_dir::AbstractString)Return the paths of the license files in the top directory of the repository at git_dir: any called LICENSE, LICENCE or COPYING, with or without a .md or .txt extension, in upper or lower case.
ResearchSoftwareMetadata.license_text — Method
ResearchSoftwareMetadata.license_text(template::AbstractString,
years::AbstractString,
names::AbstractVector)Return the text of a license from its SPDX template, with the placeholders for the copyright years and holders filled in.
ResearchSoftwareMetadata.licenses_found — Method
ResearchSoftwareMetadata.licenses_found(file::AbstractString)Return the SPDX identifiers of the licenses whose text is found in a file, which is none if the file is not recognisable as a license.
ResearchSoftwareMetadata.matrix_context — Method
ResearchSoftwareMetadata.matrix_context(job::AbstractDict,
context::AbstractDict)Return context extended with the values each matrix.x reference can take in a workflow job: the entries of that axis of the job's strategy.matrix, together with any given for it under include. exclude is not applied, and a matrix that is itself an expression adds nothing.
ResearchSoftwareMetadata.migrate_rsmd! — Method
ResearchSoftwareMetadata.migrate_rsmd!(project_d::AbstractDict)Move any legacy top-level RSMD keys (description, keywords, category, development_status, publications, author_details) into the rsmd table, where they now live. Existing rsmd entries win on conflict. Returns the dictionary.
ResearchSoftwareMetadata.on_default_branch — Method
ResearchSoftwareMetadata.on_default_branch(git_dir::AbstractString,
remote::AbstractString)Check whether the branch checked out in the repository at git_dir is the default branch of remote, which is the branch releases are made from. It counts as being so if the default branch cannot be found, and as not being so if no branch is checked out, as when a pull request is being tested.
ResearchSoftwareMetadata.order_project — Method
ResearchSoftwareMetadata.order_project(project_d::AbstractDict)Take a parsed Project.toml dictionary and return it as an OrderedDict in canonical order, which is the order Pkg itself writes, applied recursively to nested tables, so that files written from it are not reordered when Pkg next edits them.
ResearchSoftwareMetadata.parse_author — Method
ResearchSoftwareMetadata.parse_author(author::AbstractString)Parse a Project.toml authors entry of the form "Name <email>" into a (name, email) tuple, where email is nothing if the entry contains no email address. Tolerates a missing closing bracket on the email.
ResearchSoftwareMetadata.project_key_order — Method
ResearchSoftwareMetadata.project_key_order(key)Sort key reproducing Pkg's Project.toml ordering: keys Pkg knows about sort by their position in its canonical list, all other keys sort alphabetically after them.
ResearchSoftwareMetadata.read_json — Method
ResearchSoftwareMetadata.read_json(file::AbstractString)Read a JSON metadata file such as codemeta.json into an OrderedDict. Throws an error that names the file if it cannot be parsed or does not hold a JSON object.
ResearchSoftwareMetadata.read_project — Function
ResearchSoftwareMetadata.read_project()Read a Project.toml file in, migrate any legacy top-level RSMD keys into the rsmd table, and return it in its canonical order in an OrderedDict.
ResearchSoftwareMetadata.read_workflows — Method
ResearchSoftwareMetadata.read_workflows(git_dir::AbstractString)Return the GitHub workflows of the repository at git_dir as file => workflow pairs in file name order: every .yml or .yaml file in .github/workflows that holds a mapping. The list is empty if the repository has no workflows.
ResearchSoftwareMetadata.reconcile! — Method
ResearchSoftwareMetadata.reconcile!(project, codemeta, proj_key, cm_key;
value = nothing, default = nothing,
to_cm = identity, from_cm = identity,
update = false)Reconcile a metadata field between Project.toml (authoritative) and codemeta.json. An explicit value (e.g. from a keyword argument to crosswalk) takes precedence and is written into both; otherwise the Project.toml entry is used, fixing codemeta.json with a warning if it disagrees, or with an informational message when update is true, meaning the Project.toml change is deliberate and should just propagate. If the field is missing from Project.toml but present in codemeta.json, it is backfilled into Project.toml. If it is absent from both, default (when provided) is written into both, so that the value in use can be seen and changed in Project.toml. to_cm and from_cm convert values between the Project.toml and codemeta.json representations. Returns the Project.toml-side value, or nothing if the field is absent everywhere.
ResearchSoftwareMetadata.release_tags — Method
ResearchSoftwareMetadata.release_tags(git_dir::AbstractString)Return the release tags of the repository at git_dir as (version, name) named tuples: the tags that are a v followed by a version number, which is how TagBot and Registrator tag a release. Any other tag is not a release of the package and is left out, including a version number without the v, which a repository may use for something else.
ResearchSoftwareMetadata.repository_url — Method
ResearchSoftwareMetadata.repository_url(remote::AbstractString)Return the web address of a repository from the address of one of its git remotes, in whichever form git accepts it: https://github.com/org/Pkg.jl.git, git@github.com:org/Pkg.jl.git and ssh://git@github.com/org/Pkg.jl.git all give https://github.com/org/Pkg.jl. A user name or password in the address is left out, as is the port of an ssh or git address. An address in any other form, such as a path, is returned as it is.
ResearchSoftwareMetadata.runner_labels — Method
ResearchSoftwareMetadata.runner_labels(runs_on, context::AbstractDict)Return the runner labels named by the runs-on entry of a workflow job, or nothing if they cannot be determined. The entry may be one label, a list of labels or a runner group, of which only the labels can name an operating system.
ResearchSoftwareMetadata.runner_os — Method
ResearchSoftwareMetadata.runner_os(label::AbstractString)Return the operating system named by a GitHub runner label ("Linux", "Windows" or "macOS"), or nothing if the label names none, as with self-hosted or an architecture label.
ResearchSoftwareMetadata.runs_tests — Method
ResearchSoftwareMetadata.runs_tests(job::AbstractDict,
git_dir::AbstractString, depth::Int)Check whether a workflow job runs the package's tests: one of its steps uses the julia-actions/julia-runtest action or runs a script that calls Pkg.test, or the job calls a reusable workflow in the same repository that has such a job. depth counts the reusable workflows followed to reach the job.
ResearchSoftwareMetadata.source_files — Method
ResearchSoftwareMetadata.source_files(git_dir::AbstractString)Return the paths of the julia source files of the repository at git_dir: every .jl file that git tracks, or would track because it is not ignored. Files that git ignores and the contents of submodules are not included.
ResearchSoftwareMetadata.spdx_identifier — Method
ResearchSoftwareMetadata.spdx_identifier(license::AbstractString)Return the bare SPDX identifier of a license that may be written as the address of its page on spdx.org: https://spdx.org/licenses/MIT, the same with http and the same with a trailing .html or .json all give MIT, as does MIT itself.
ResearchSoftwareMetadata.split_name — Method
ResearchSoftwareMetadata.split_name(full_name::AbstractString)Split a full name into given and family names, treating the last word as the family name. Returns a (givenName, familyName) tuple, where givenName is nothing if full_name contains only a single word.
ResearchSoftwareMetadata.utc_today — Method
ResearchSoftwareMetadata.utc_today()Return today's date in UTC, as text. A date written into the metadata is then the same wherever the crosswalk is run: on a GitHub runner, whose clock is in UTC, as on a machine in any other time zone.
ResearchSoftwareMetadata.workflow_inputs — Method
ResearchSoftwareMetadata.workflow_inputs(workflow::AbstractDict)Return the context a GitHub workflow starts with when nothing is passed to it: the default of every input it declares under workflow_dispatch or workflow_call, held under "inputs.x".
ResearchSoftwareMetadata.workflow_runners — Method
ResearchSoftwareMetadata.workflow_runners(workflow::AbstractDict,
context::AbstractDict,
git_dir::AbstractString,
depth::Int;
tests_only::Bool = false)Return the runner labels the jobs of a reusable workflow can run on when it is called with the inputs in context, or nothing if none can be determined. If tests_only is set, only the jobs that run the package's tests are counted.