diff --git a/CONTRIBUTORS b/CONTRIBUTORS index e69de29..52daeb8 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -0,0 +1 @@ +Thibault Allançon diff --git a/README.md b/README.md index 08b97d8..9078b9e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -swh-py-template -=============== - -Python module template, used as skeleton to create new modules. +Software Heritage virtual file system +===================================== +Virtual file system to browse the +[Software Heritage](https://www.softwareheritage.org/) [archive](https://archive.softwareheritage.org/), +built on top of [FUSE](https://github.com/libfuse/libfuse). diff --git a/requirements-swh.txt b/requirements-swh.txt index 24f0a5c..315f451 100644 --- a/requirements-swh.txt +++ b/requirements-swh.txt @@ -1,2 +1,3 @@ # Add here internal Software Heritage dependencies, one per line. -swh.core +swh.model +swh.web.client diff --git a/requirements-test.txt b/requirements-test.txt index e079f8a..93e9270 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1 +1,5 @@ pytest + +# XXX not actually needed +# XXX just a temporary workaround for https://forge.softwareheritage.org/T2634 +requests diff --git a/requirements.txt b/requirements.txt index 54ce666..a82f8e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1 @@ -# Add here external Python modules dependencies, one per line. Module names -# should match https://pypi.python.org/pypi names. For the full spec or -# dependency lines, see https://pip.readthedocs.org/en/1.1/requirements.html - +pyfuse3 diff --git a/setup.py b/setup.py index b67d745..0d8e0fa 100755 --- a/setup.py +++ b/setup.py @@ -1,74 +1,71 @@ #!/usr/bin/env python3 -# Copyright (C) 2019-2020 The Software Heritage developers +# Copyright (C) 2020 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information from io import open from os import path from setuptools import find_packages, setup here = path.abspath(path.dirname(__file__)) # Get the long description from the README file with open(path.join(here, "README.md"), encoding="utf-8") as f: long_description = f.read() def parse_requirements(name=None): if name: reqf = "requirements-%s.txt" % name else: reqf = "requirements.txt" requirements = [] if not path.exists(reqf): return requirements with open(reqf) as f: for line in f.readlines(): line = line.strip() if not line or line.startswith("#"): continue requirements.append(line) return requirements -# Edit this part to match your module. -# Full sample: -# https://forge.softwareheritage.org/diffusion/DCORE/browse/master/setup.py setup( - name="swh.", # example: swh.loader.pypi - description="Software Heritage ", + name="swh.fuse", + description="Software Heritage virtual file system", long_description=long_description, long_description_content_type="text/markdown", python_requires=">=3.7", author="Software Heritage developers", author_email="swh-devel@inria.fr", - url="https://forge.softwareheritage.org/diffusion/", + url="https://forge.softwareheritage.org/source/swh-fuse", packages=find_packages(), # packages's modules install_requires=parse_requirements() + parse_requirements("swh"), tests_require=parse_requirements("test"), setup_requires=["setuptools-scm"], use_scm_version=True, extras_require={"testing": parse_requirements("test")}, include_package_data=True, entry_points=""" [swh.cli.subcommands] - =swh..cli:cli + fuse=swh.fuse.cli:fuse """, classifiers=[ "Programming Language :: Python :: 3", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: OS Independent", "Development Status :: 3 - Alpha", ], project_urls={ "Bug Reports": "https://forge.softwareheritage.org/maniphest", "Funding": "https://www.softwareheritage.org/donate", - "Source": "https://forge.softwareheritage.org/source/swh-", - "Documentation": "https://docs.softwareheritage.org/devel/swh-/", + "Source": "https://forge.softwareheritage.org/source/swh-fuse", + "Documentation": "https://docs.softwareheritage.org/devel/swh-fuse/", }, ) diff --git a/swh/foo/cli.py b/swh/foo/cli.py deleted file mode 100644 index cd764e9..0000000 --- a/swh/foo/cli.py +++ /dev/null @@ -1,18 +0,0 @@ -import click - -from swh.core.cli import CONTEXT_SETTINGS - - -@click.group(name="foo", context_settings=CONTEXT_SETTINGS) -@click.pass_context -def cli(ctx): - """Foo main command. - """ - - -@cli.command() -@click.option("--bar", help="Something") -@click.pass_context -def bar(ctx, bar): - """Do something.""" - click.echo("bar") diff --git a/swh/foo/__init__.py b/swh/fuse/__init__.py similarity index 100% rename from swh/foo/__init__.py rename to swh/fuse/__init__.py diff --git a/swh/fuse/cli.py b/swh/fuse/cli.py new file mode 100644 index 0000000..35b4c73 --- /dev/null +++ b/swh/fuse/cli.py @@ -0,0 +1,66 @@ +# Copyright (C) 2020 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +# WARNING: do not import unnecessary things here to keep cli startup time under +# control +import os +from typing import Any, Dict + +import click + +# from swh.core import config +from swh.core.cli import CONTEXT_SETTINGS + +# All generic config code should reside in swh.core.config +DEFAULT_CONFIG_PATH = os.environ.get( + "SWH_CONFIG_FILE", os.path.join(click.get_app_dir("swh"), "global.yml") +) + +DEFAULT_CONFIG: Dict[str, Any] = { + "web-api": { + "url": "https://archive.softwareheritage.org/api/1", + "auth-token": None, + } +} + + +@click.group(name="fuse", context_settings=CONTEXT_SETTINGS) +# XXX conffile logic temporarily commented out due to: +# XXX https://forge.softwareheritage.org/T2632 +# @click.option( +# "-C", +# "--config-file", +# default=DEFAULT_CONFIG_PATH, +# type=click.Path(exists=True, dir_okay=False, path_type=str), +# help="YAML configuration file", +# ) +@click.pass_context +def fuse(ctx): + """Software Heritage virtual file system""" + + # # recursive merge not done by config.read + # conf = config.read_raw_config(config.config_basepath(config_file)) + # conf = config.merge_configs(DEFAULT_CONFIG, conf) + conf = {} + + ctx.ensure_object(dict) + ctx.obj["config"] = conf + + +@fuse.command() +@click.option( + "-u", + "--api-url", + default=DEFAULT_CONFIG["web-api"]["url"], + metavar="API_URL", + show_default=True, + help="base URL for Software Heritage Web API", +) +@click.pass_context +def mount(ctx, api_url): + """Mount the Software Heritage archive at the given mount point""" + from .fuse import fuse # XXX + + fuse() diff --git a/swh/foo/bar.py b/swh/fuse/fuse.py similarity index 53% rename from swh/foo/bar.py rename to swh/fuse/fuse.py index a86df5d..e5117f5 100644 --- a/swh/foo/bar.py +++ b/swh/fuse/fuse.py @@ -1,4 +1,13 @@ -# Copyright (C) 2019 The Software Heritage developers +# Copyright (C) 2020 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information + + +import logging +import sys + + +def fuse(): + logging.error("not implemented: FUSE mounting") + sys.exit(1) diff --git a/swh/foo/py.typed b/swh/fuse/py.typed similarity index 100% rename from swh/foo/py.typed rename to swh/fuse/py.typed diff --git a/swh/foo/tests/__init__.py b/swh/fuse/tests/__init__.py similarity index 100% rename from swh/foo/tests/__init__.py rename to swh/fuse/tests/__init__.py diff --git a/swh/fuse/tests/test_cli.py b/swh/fuse/tests/test_cli.py new file mode 100644 index 0000000..6a418d8 --- /dev/null +++ b/swh/fuse/tests/test_cli.py @@ -0,0 +1,19 @@ +# Copyright (C) 2020 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +import unittest + +from click.testing import CliRunner + +from swh.fuse import cli + + +class TestMount(unittest.TestCase): + def setUp(self): + self.runner = CliRunner() + + def test_no_args(self): + result = self.runner.invoke(cli.mount) + self.assertNotEqual(result.exit_code, 0)