Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fortran support #71

Merged
merged 6 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .somesy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ no_sync_codemeta = false
codemeta_file = "codemeta.json"
no_sync_package_json = true
no_sync_julia = true
no_sync_fortran = true
show_info = false
verbose = false
debug = true
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Please consult the changelog to inform yourself about breaking changes and secur

* added separate `documentation` URL to Project metadata model
* added support for Julia `Project.toml` file
* added support for fortran `fpm.toml` file

## [v0.3.1](https://github.com/Materials-Data-Science-and-Informatics/somesy/tree/v0.3.1) <small>(2024-01-23)</small> { id="0.3.1" }

Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ verbose = true # show detailed information about what somesy is doing
<!-- --8<-- [end:somesytoml] -->

Alternatively, you can also add the somesy configuration to an existing
`pyproject.toml`, `package.json` or `Project.toml` file. The somesy [manual](https://materials-data-science-and-informatics.github.io/somesy/main/manual/#somesy-input-file) contains examples showing how to do that.
`pyproject.toml`, `package.json`, `Project.toml`, or `fpm.toml` file. The somesy [manual](https://materials-data-science-and-informatics.github.io/somesy/main/manual/#somesy-input-file) contains examples showing how to do that.

### Using somesy

Expand All @@ -125,7 +125,7 @@ authoritative** source for project metadata, which is used to update all
supported (and enabled) *target files*. You can find an overview of supported
formats further below.

By default, `somesy` will create (if they did not exist) or update `CITATION.cff` and `codemeta.json` files in your repository. If you happen to use `pyproject.toml` (in Python projects), `package.json` (in JavaScript projects), or `Project.toml` (in Julia projects), somesy would also update the respective information there.
By default, `somesy` will create (if they did not exist) or update `CITATION.cff` and `codemeta.json` files in your repository. If you happen to use `pyproject.toml` (in Python projects), `package.json` (in JavaScript projects), `Project.toml` (in Julia projects), or `fpm.toml` (in Fortran projects) somesy would also update the respective information there.

You can see call available options with `somesy --help`,
all of these can also be conveniently set in your `somesy.toml` file.
Expand Down Expand Up @@ -168,16 +168,18 @@ Here is an overview of all the currently supported files and formats.
| -------------- | ------ |-| ----------------------------- | ------ |
| (.)somesy.toml | ✓ | | pyproject.toml _(poetry)_ | ✓ |
| pyproject.toml | ✓ | | pyproject.toml _(setuptools)_ | ✓(1.) |
| package.json | ✓ | | package.json | ✓(2.) |
| Project.toml | ✓ | | Project.toml | ✓ |
| package.json | ✓ | | package.json _(JavaScript)_ | ✓(2.) |
| Project.toml | ✓ | | Project.toml _(Julia)_ | ✓ |
| fpm.toml | ✓ | | fpm.toml _(Fortran)_ | ✓(3.) |
| | | | CITATION.cff | ✓ |
| | | | codemeta.json | ✓(3.) |
| | | | codemeta.json | ✓(4.) |

**Notes:**

1. note that `somesy` does not support setuptools *dynamic fields*
2. `package.json` only supports one author, so `somesy` will pick the *first* listed author
3. unlike other targets, `somesy` will *re-create* the `codemeta.json` (i.e. do not edit it by hand!)
3. `fpm.toml` only supports one author and maintainer, so `somesy` will pick the *first* listed author and maintainer
mustafasoylu marked this conversation as resolved.
Show resolved Hide resolved
4. unlike other targets, `somesy` will *re-create* the `codemeta.json` (i.e. do not edit it by hand!)

<!-- --8<-- [end:quickstart] -->

Expand Down
87 changes: 63 additions & 24 deletions docs/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,33 +117,33 @@ some of the currently supported formats. Bold field names are mandatory, the oth

=== "Person Metadata"

| Somesy Field | Poetry Config | SetupTools Config | Julia Config | package.json | CITATION.cff | CodeMeta |
| ---------------- | ------------- | ----------------- | ------------ | ------------ | --------------- | --------------- |
| | | | | | | |
| **given-names** | name+email | name | name+email | name | given-names | givenName |
| **family-names** | name+email | name | name+email | name | family-names | familyName |
| **email** | name+email | email | name+email | email | email | email |
| orcid | - | - | - | url | orcid | id |
| *(many others)* | - | - | - | - | *(same)* | *(same)* |
| Somesy Field | Poetry Config | SetupTools Config | Julia Config | Fortran Config | package.json | CITATION.cff | CodeMeta |
| ---------------- | ------------- | ----------------- | ------------ | -------------- | ------------ | --------------- | --------------- |
| | | | | | | | |
| **given-names** | name+email | name | name+email | name+email | name | given-names | givenName |
| **family-names** | name+email | name | name+email | name+email | name | family-names | familyName |
| **email** | name+email | email | name+email | name+email | email | email | email |
| orcid | - | - | - | - | url | orcid | id |
| *(many others)* | - | - | - | - | - | *(same)* | *(same)* |

=== "Project Metadata"

| Somesy Field | Poetry Config | SetupTools Config | Julia Config | package.json | CITATION.cff | CodeMeta |
| ----------------- | ------------- | ------------------ | ------------ | ------------ | --------------- | ----------------- |
| | | | | | |
| **name** | name | name | name | name | title | name |
| **description** | description | description | - | description | abstract | description |
| **license** | license | license | - | license | license | license |
| **version** | version | version | version | version | version | version |
| | | | | | | |
| ***author=true*** | authors | authors | authors | author | authors | author |
| *maintainer=true* | maintainers | maintainers | - | maintainers | contact | maintainer |
| *people* | - | - | - | contributors | - | contributor |
| | | | | | | |
| keywords | keywords | keywords | - | keywords | keywords | keywords |
| homepage | homepage | urls.homepage | - | homepage | url | url |
| repository | repository | urls.repository | - | repository | repository_code | codeRepository |
| documentation | documentation | urls.documentation | - | - | - | buildInstructions |
| Somesy Field | Poetry Config | SetupTools Config | Julia Config | Fortran Config | package.json | CITATION.cff | CodeMeta |
| ----------------- | ------------- | ------------------ | ------------ | -------------- | ------------ | --------------- | ----------------- |
| | | | | | | |
| **name** | name | name | name | name | name | title | name |
| **description** | description | description | - | description | description | abstract | description |
| **license** | license | license | - | license | license | license | license |
| **version** | version | version | version | version | version | version | version |
| | | | | | | | |
| ***author=true*** | authors | authors | authors | author | author | authors | author |
| *maintainer=true* | maintainers | maintainers | - | maintainer | maintainers | contact | maintainer |
| *people* | - | - | - | - | contributors | - | contributor |
| | | | | | | | |
| keywords | keywords | keywords | - | keywords | keywords | keywords | keywords |
| homepage | homepage | urls.homepage | - | homepage | homepage | url | url |
| repository | repository | urls.repository | - | - | repository | repository_code | codeRepository |
| documentation | documentation | urls.documentation | - | - | - | - | buildInstructions |

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,
Expand Down Expand Up @@ -171,6 +171,7 @@ Without an input file specifically provided, somesy will check if it can find a
* `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)

which is located in the current working directory. If you want to provide
Expand Down Expand Up @@ -260,6 +261,40 @@ one of the supported input formats:
verbose = true # show detailed information about what somesy is doing
```

=== "fpm.toml"
```toml
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"
repository = "https://github.com/username/my-amazing-project"

# This is you, the proud author of your project
[[tool.somesy.project.people]]
given-names = "Jane"
family-names = "Doe"
email = "[email protected]"
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 = "[email protected]"
orcid = "https://orcid.org/0000-0000-0000-0002"

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

=== "package.json"

```json
Expand Down Expand Up @@ -412,6 +447,10 @@ Therefore, **in such a case you will need to fix the ORCID in all configured som
before running somesy (so somesy will not create new person entries), or
after running somesy (to remove the duplicate entries with the incorrect ORCID).

!!! warning

Person identification and merging is not applied to standards with free text fields for authors or maintainers, such as `fpm.toml`.

### Codemeta

While `somesy` is modifying existing files for most supported formats and implements
Expand Down
7 changes: 7 additions & 0 deletions src/somesy/cli/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ def config():
if julia_file is not None or julia_file != "":
options["julia_file"] = julia_file

options["no_sync_fortran"] = not typer.confirm(
"Do you want to sync to a fpm.toml(fortran) file?", default=True
)
fortran_file = typer.prompt("fpm.toml(fortran) file path", default="fpm.toml")
if fortran_file is not None or fortran_file != "":
options["fortran_file"] = fortran_file

options["show_info"] = typer.confirm(
"Do you want to show info about the sync process?"
)
Expand Down
34 changes: 31 additions & 3 deletions src/somesy/cli/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ def sync(
no_sync_julia: bool = typer.Option(
None,
"--no-sync-julia",
"-M",
help="Do not sync Project.toml(Julia) file",
"-K",
help="Do not sync Project.toml(Julia) file (default: False)",
),
julia_file: Path = typer.Option(
None,
"--julia-file",
"-m",
"-k",
mustafasoylu marked this conversation as resolved.
Show resolved Hide resolved
exists=True,
file_okay=True,
dir_okay=False,
Expand All @@ -119,6 +119,24 @@ def sync(
resolve_path=True,
help="Custom Project.toml(Julia) file path",
),
no_sync_fortran: bool = typer.Option(
None,
"--no-sync-fortran",
"-F",
help="Do not sync fpm.toml(fortran) file (default: False)",
),
fortran_file: Path = typer.Option(
None,
"--fortran-file",
"-f",
exists=True,
file_okay=True,
dir_okay=False,
writable=True,
readable=True,
resolve_path=True,
help="Custom fpm.toml(fortran) file path",
),
):
"""Sync project metadata input with metadata files."""
somesy_input = resolved_somesy_input(
Expand All @@ -133,6 +151,8 @@ def sync(
codemeta_file=codemeta_file,
no_sync_julia=no_sync_julia,
julia_file=julia_file,
no_sync_fortran=no_sync_fortran,
fortran_file=fortran_file,
)
run_sync(somesy_input)

Expand All @@ -156,6 +176,14 @@ def run_sync(somesy_input: SomesyInput):
logger.info(
f" - [italic]codemeta.json[/italic]:\t[grey]{conf.codemeta_file}[/grey]\n"
)
if not conf.no_sync_julia:
logger.info(
f" - [italic]Project.toml(Julia)[/italic]:\t[grey]{conf.julia_file}[/grey]"
)
if not conf.no_sync_fortran:
logger.info(
f" - [italic]fpm.toml(fortran)[/italic]:\t[grey]{conf.fortran_file}[/grey]"
)
# ----
sync_command(somesy_input)
# ----
Expand Down
24 changes: 23 additions & 1 deletion src/somesy/commands/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from somesy.cff.writer import CFF
from somesy.codemeta import Codemeta
from somesy.core.models import ProjectMetadata, SomesyInput
from somesy.fortran.writer import Fortran
from somesy.julia.writer import Julia
from somesy.package_json.writer import PackageJSON
from somesy.pyproject.writer import Pyproject
Expand Down Expand Up @@ -40,6 +41,9 @@ def sync(somesy_input: SomesyInput):
if not conf.no_sync_julia:
_sync_julia(metadata, conf.julia_file)

if not conf.no_sync_fortran:
_sync_fortran(metadata, conf.fortran_file)


def _sync_python(
metadata: ProjectMetadata,
Expand Down Expand Up @@ -120,7 +124,7 @@ def _sync_julia(
"""Sync Project.toml file using project metadata.

Args:
metadata (ProjectMetadata): project metadata to sync pyproject.toml file.
metadata (ProjectMetadata): project metadata to sync Project.toml file.
julia_file (Path, optional): Project.toml file path if wanted to be synced. Defaults to None.
"""
logger.verbose("Loading Project.toml file.")
Expand All @@ -129,3 +133,21 @@ def _sync_julia(
cm.sync(metadata)
cm.save()
logger.verbose(f"Saved synced Project.toml file to {julia_file}.")


def _sync_fortran(
metadata: ProjectMetadata,
fortran_file: Path,
):
"""Sync fpm.toml file using project metadata.

Args:
metadata (ProjectMetadata): project metadata to sync fpm.toml file.
fortran_file (Path, optional): fpm.toml file path if wanted to be synced. Defaults to None.
"""
logger.verbose("Loading fpm.toml file.")
cm = Fortran(fortran_file)
logger.verbose("Syncing fpm.toml file.")
cm.sync(metadata)
cm.save()
logger.verbose(f"Saved synced fpm.toml file to {fortran_file}.")
8 changes: 5 additions & 3 deletions src/somesy/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"pyproject.toml",
"package.json",
"Project.toml",
"fpm.toml",
]
"""Input files ordered by priority for discovery."""

Expand Down Expand Up @@ -78,9 +79,10 @@ def get_input_content(path: Path, *, no_unwrap: bool = False) -> Dict[str, Any]:
return ret if no_unwrap else ret.unwrap()

# pyproject.toml
if (
path.suffix == ".toml" and "pyproject" in path.name
) or path.name == "Project.toml":
if (path.suffix == ".toml" and "pyproject" in path.name) or path.name in [
"Project.toml",
"fpm.toml",
]:
with open(path, "r") as f:
input_content = tomlkit.load(f)
if "tool" in input_content and "somesy" in input_content["tool"]:
Expand Down
9 changes: 8 additions & 1 deletion src/somesy/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def model_dump_json(self, *args, **kwargs):
return json.dumps(ret, ensure_ascii=False)


_SOMESY_TARGETS = ["cff", "pyproject", "package_json", "codemeta", "julia"]
_SOMESY_TARGETS = ["cff", "pyproject", "package_json", "codemeta", "julia", "fortran"]


class SomesyConfig(SomesyBaseModel):
Expand Down Expand Up @@ -190,6 +190,13 @@ def at_least_one_target(cls, values):
"Project.toml"
)

no_sync_fortran: Annotated[
bool, Field(description="Do not sync with fpm.toml.")
] = False
fortran_file: Annotated[Path, Field(description="fpm.toml file path.")] = Path(
"fpm.toml"
)

def log_level(self) -> SomesyLogLevel:
"""Return log level derived from this configuration."""
return SomesyLogLevel.from_flags(
Expand Down
4 changes: 4 additions & 0 deletions src/somesy/fortran/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""Fortran module."""
from .writer import Fortran

__all__ = ["Fortran"]
Loading
Loading