diff --git a/RELEASE.md b/RELEASE.md index 117d18b4..d4a7ed0a 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -7,7 +7,6 @@ Unless you're a core OnionShare developer making a release, you'll probably neve ### Update the version in these places - [ ] `cli/pyproject.toml` -- [ ] `cli/onionshare_cli/resources/version.txt` - [ ] `desktop/pyproject.toml` - [ ] `desktop/setup.py` - [ ] `desktop/org.onionshare.OnionShare.appdata.xml` @@ -118,7 +117,7 @@ In `flatpak/org.onionshare.OnionShare.yaml`: # get onionshare dependencies cd flatpak-build-tools/pip - ./flatpak-pip-generator $(../../onionshare/flatpak/poetry-to-requirements.py ../../onionshare/desktop/pyproject.toml | grep -v PySide6) + ./flatpak-pip-generator $(../../onionshare/flatpak/pyproject-to-requirements.py ../../onionshare/desktop/pyproject.toml | grep -v PySide6) ../flatpak-json2yaml.py ./python3-modules.json mv python3-modules.yml onionshare-desktop.yaml ``` @@ -285,7 +284,7 @@ Now, notarize the release. You will need an app-specific Apple ID password set u ```sh export APPLE_PASSWORD="changeme" # This must be an app-specific Apple ID password, not your main Apple ID password -export VERSION=$(cat ../cli/onionshare_cli/resources/version.txt) +export VERSION=$(cat ../cli/pyproject.toml | python -c 'import tomllib,sys;print(tomllib.load(sys.stdin)["project"]["version"])') # Notarize it xcrun notarytool submit --apple-id "you@example.com" --team-id 7WLJ4UBL5L --password "$APPLE_PASSWORD" --progress --wait dist/OnionShare-$VERSION.dmg diff --git a/cli/onionshare_cli/common.py b/cli/onionshare_cli/common.py index 16f5b2fd..8cca4cf2 100644 --- a/cli/onionshare_cli/common.py +++ b/cli/onionshare_cli/common.py @@ -19,6 +19,7 @@ along with this program. If not, see . """ import base64 import hashlib +import importlib.metadata as importlib_metadata import importlib.resources as importlib_resources import os import platform @@ -59,8 +60,7 @@ class Common: self.platform = "BSD" # The current version of OnionShare - with open(self.get_resource_path("version.txt")) as f: - self.version = f.read().strip() + self.version = importlib_metadata.version(__package__) def display_banner(self): """ diff --git a/cli/onionshare_cli/resources/version.txt b/cli/onionshare_cli/resources/version.txt deleted file mode 100644 index ec1cf33c..00000000 --- a/cli/onionshare_cli/resources/version.txt +++ /dev/null @@ -1 +0,0 @@ -2.6.3 diff --git a/cli/pyproject.toml b/cli/pyproject.toml index 6ee7e64a..8371479f 100644 --- a/cli/pyproject.toml +++ b/cli/pyproject.toml @@ -1,9 +1,16 @@ -[tool.poetry] +[project] name = "onionshare_cli" version = "2.6.3" -description = "OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does _not_ require setting up a separate server or using a third party file-sharing service." -authors = ["Micah Lee "] -license = "GPLv3+" +description = "Securely and anonymously share files, host websites, and chat with friends using the Tor network" +requires-python = ">=3.10,<3.13" +authors = [ + { name = "Micah Lee", email = "micah@micahflee.com" }, +] +maintainers = [ + { name = "Micah Lee", email = "micah@micahflee.com" }, +] +license = { text = "GPL-3.0-or-later" } +keywords = [ "onion", "share", "onionshare", "tor", "anonymous", "web server" ] classifiers = [ "Programming Language :: Python :: 3", "Framework :: Flask", @@ -14,39 +21,58 @@ classifiers = [ "Operating System :: OS Independent", "Environment :: Web Environment", ] +dependencies = [ + "click", + "flask == 2.3.2", + "flask-compress >= 1.13, < 2.0", + "flask-socketio == 5.3.4", + "psutil", + "pysocks", + "requests[socks]", + "unidecode", + "urllib3 >= 2.2.2, < 3.0", + "eventlet", + "pynacl", + "colorama", + "gevent-websocket", + "stem == 1.8.1", + "waitress >= 3.0.1, < 4.0.0", + "werkzeug == 3.0.6", + "packaging >= 24", + "gevent >= 23.9.1, < 24.0.0", + "qrcode >= 7.4.2, < 8.0.0", +] -[tool.poetry.dependencies] -python = ">=3.10,<3.13" -click = "*" -flask = "2.3.2" -flask-compress = "^1.13" -flask-socketio = "5.3.4" -psutil = "*" -pysocks = "*" -requests = {extras = ["socks"], version = "*"} -unidecode = "*" -urllib3 = "^2.2.2" -eventlet = "*" -setuptools = ">=70.0.0" -pynacl = "*" -colorama = "*" -gevent-websocket = "*" -stem = "1.8.1" -waitress = "^3.0.1" -werkzeug = "3.0.6" -packaging = ">=24" -gevent = "^23.9.1" -wheel = "^0.41.2" -cffi = "^1.15.1" -cython = "^3.0.2" -qrcode = "^7.4.2" +[project.urls] +homepage = "https://onionshare.org" +repository = "https://github.com/onionshare/onionshare" +documentation = "https://docs.onionshare.org/" + +[project.scripts] +onionshare-cli = "onionshare_cli:main" + +[tool.setuptools] +packages = [ + "onionshare_cli", + "onionshare_cli.web", +] + +[tool.setuptools.package-data] +onionshare_cli = [ + "resources/*", + "resources/static/*", + "resources/static/css/*", + "resources/static/img/*", + "resources/static/js/*", + "resources/templates/*", +] [tool.poetry.group.dev.dependencies] +setuptools = ">=70.0.0" + +[tool.poetry.group.test.dependencies] pytest = ">=7.2.0" -[tool.poetry.scripts] -onionshare-cli = 'onionshare_cli:main' - [build-system] -requires = ["poetry-core"] +requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/cli/setup.py b/cli/setup.py index d401afec..3ae0deaf 100644 --- a/cli/setup.py +++ b/cli/setup.py @@ -18,55 +18,6 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import os -import setuptools +from setuptools import setup -with open(os.path.join("onionshare_cli", "resources", "version.txt")) as f: - version = f.read().strip() - -setuptools.setup( - name="onionshare-cli", - version=version, - long_description=( - "OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, " - "making it accessible as a Tor onion service, and generating an unguessable web address so others can " - "download files from you, or upload files to you. It does _not_ require setting up a separate server or " - "using a third party file-sharing service." - ), - author="Micah Lee", - author_email="micah@micahflee.com", - maintainer="Micah Lee", - maintainer_email="micah@micahflee.com", - url="https://onionshare.org", - license="GPLv3", - keywords="onion, share, onionshare, tor, anonymous, web server", - classifiers=[ - "Programming Language :: Python :: 3", - "Framework :: Flask", - "Topic :: Communications :: File Sharing", - "Topic :: Security :: Cryptography", - "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", - "Intended Audience :: End Users/Desktop", - "Operating System :: OS Independent", - "Environment :: Web Environment", - ], - packages=[ - "onionshare_cli", - "onionshare_cli.web", - ], - package_data={ - "onionshare_cli": [ - "resources/*", - "resources/static/*", - "resources/static/css/*", - "resources/static/img/*", - "resources/static/js/*", - "resources/templates/*", - ] - }, - entry_points={ - "console_scripts": [ - "onionshare-cli = onionshare_cli:main", - ], - }, -) +setup() diff --git a/desktop/pyproject.toml b/desktop/pyproject.toml index 595c15af..878d2128 100644 --- a/desktop/pyproject.toml +++ b/desktop/pyproject.toml @@ -1,31 +1,78 @@ -[tool.poetry] +[project] name = "onionshare" version = "2.6.3" -description = "OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does _not_ require setting up a separate server or using a third party file-sharing service." -authors = ["Micah Lee "] -license = "GPLv3+" +requires-python = ">=3.10,<3.13" +description = "Securely and anonymously share files, host websites, and chat with friends using the Tor network" +authors = [ + { name = "Micah Lee", email = "micah@micahflee.com" }, +] +maintainers = [ + { name = "Micah Lee", email = "micah@micahflee.com" }, +] +license = { text = "GPL-3.0-or-later" } +keywords = [ "onion", "share", "onionshare", "tor", "anonymous", "web server" ] +classifiers = [ + "Programming Language :: Python :: 3", + "Framework :: Flask", + "Topic :: Communications :: File Sharing", + "Topic :: Security :: Cryptography", + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", + "Intended Audience :: End Users/Desktop", + "Operating System :: OS Independent", + "Environment :: Web Environment", +] +dependencies = [ + "PySide6 == 6.8.2.1", + "qrcode", + "werkzeug == 3.0.6", + "python-gnupg", + "onionshare_cli", +] + +[project.urls] +homepage = "https://onionshare.org" +repository = "https://github.com/onionshare/onionshare" +documentation = "https://docs.onionshare.org/" + +[project.scripts] +onionshare = 'onionshare:main' +onionshare-cli = "onionshare_cli:main" + +[tool.setuptools] +packages = [ + "onionshare", + "onionshare.tab", + "onionshare.tab.mode", + "onionshare.tab.mode.share_mode", + "onionshare.tab.mode.receive_mode", + "onionshare.tab.mode.website_mode", + "onionshare.tab.mode.chat_mode", +] + +[tool.setuptools.package-data] +onionshare = [ + "resources/*", + "resources/images/*", + "resources/images/countries/*", + "resources/locale/*", + "resources/countries/*", +] [tool.poetry.dependencies] -python = ">=3.10,<3.13" -onionshare_cli = {path = "../cli", develop = true} -PySide6 = "6.8.2.1" -qrcode = "*" -werkzeug = "3.0.6" -python-gnupg = "*" +onionshare_cli = { path = "../cli", develop = true } [tool.poetry.group.dev.dependencies] click = "*" black = "*" +cx_freeze = "7.2.9" +importlib-metadata = "*" +tomli = { version = "^2.0.1", python = "<3.11" } + +[tool.poetry.group.test.dependencies] pytest = "*" pytest-faulthandler = "*" pytest-qt = "*" -cx_freeze = "7.2.9" -importlib-metadata = "*" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" - -[tool.poetry.scripts] -onionshare = 'onionshare:main' -onionshare-cli = 'onionshare_cli:main' diff --git a/desktop/scripts/build-macos.py b/desktop/scripts/build-macos.py index 7c709e08..3aa35b05 100644 --- a/desktop/scripts/build-macos.py +++ b/desktop/scripts/build-macos.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import os +import sys import inspect import click import platform @@ -8,6 +9,11 @@ import shutil import glob import itertools +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + from common import get_binary_arches root = os.path.dirname( @@ -270,9 +276,10 @@ def package(app_path): return print("> Create DMG") - version_filename = f"{root}/cli/onionshare_cli/resources/version.txt" - with open(version_filename) as f: - version = f.read().strip() + pyproject_filename = f"{root}/cli/pyproject.toml" + with open(pyproject_filename, "rb") as f: + pyproject = tomllib.load(f) + version = pyproject['project']['version'] os.makedirs(f"{desktop_dir}/dist", exist_ok=True) dmg_path = f"{desktop_dir}/dist/OnionShare-{version}.dmg" diff --git a/desktop/scripts/build-windows.py b/desktop/scripts/build-windows.py index 9b699918..7f263565 100644 --- a/desktop/scripts/build-windows.py +++ b/desktop/scripts/build-windows.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 -from setuptools.command.build import build -import sys import os +import sys import inspect import click import shutil @@ -10,6 +9,11 @@ import uuid import xml.etree.ElementTree as ET from glob import glob +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + root = os.path.dirname( os.path.dirname( os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) @@ -165,17 +169,13 @@ def wix_build_components_xml(root, data): return component_ids -def msi_package(build_path, msi_path, product_update_code): +def msi_package(build_path, msi_path, product_update_code, version): print(f"> Build the WiX file") - version_filename = os.path.join( - build_path, "lib", "onionshare_cli", "resources", "version.txt" - ) - with open(version_filename) as f: - version = f.read().strip() - # change a version like 2.6.dev1 to just 2.6, for cx_Freeze's sake - last_digit = version[-1] - if version.endswith(f".dev{last_digit}"): - version = version[0:-5] + + # change a version like 2.6.dev1 to just 2.6, for cx_Freeze's sake + last_digit = version[-1] + if version.endswith(f".dev{last_digit}"): + version = version[0:-5] data = { "id": "TARGETDIR", @@ -428,16 +428,18 @@ def codesign(path): @click.argument("path") def package(path): """Build the MSI package""" - version_filename = os.path.join( - root, "cli", "onionshare_cli", "resources", "version.txt" + pyproject_filename = os.path.join( + root, "cli", "pyproject.toml" ) - with open(version_filename) as f: - version = f.read().strip() + with open(pyproject_filename, "rb") as f: + pyproject = tomllib.load(f) + version = pyproject['project']['version'] msi_package( path, os.path.join(desktop_dir, "dist", f"OnionShare-win64-{version}.msi"), "ed7f9243-3528-4b4a-b85c-9943982e75eb", + version ) diff --git a/desktop/setup-freeze.py b/desktop/setup-freeze.py index 3f9059b5..e5702b6e 100644 --- a/desktop/setup-freeze.py +++ b/desktop/setup-freeze.py @@ -26,9 +26,16 @@ import cx_Freeze from cx_Freeze import setup, Executable from setuptools import find_packages +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + # Discover the version -with open(os.path.join("..", "cli", "onionshare_cli", "resources", "version.txt")) as f: - version = f.read().strip() +pyproject_filename = os.path.join("..", "cli", "pyproject.toml") +with open(pyproject_filename, "rb") as f: + pyproject = tomllib.load(f) + version = pyproject['project']['version'] # change a version like 2.6.dev1 to just 2.6, for cx_Freeze's sake last_digit = version[-1] if version.endswith(f".dev{last_digit}"): diff --git a/desktop/setup.py b/desktop/setup.py index 825b000c..b896fdac 100644 --- a/desktop/setup.py +++ b/desktop/setup.py @@ -1,53 +1,11 @@ #!/usr/bin/env python3 # This file is used to build the Snapcraft and Flatpak packages -import setuptools +from setuptools import setup # The version must be hard-coded because Snapcraft won't have access to ../cli version = "2.6.3" -setuptools.setup( +setup( name="onionshare", version=version, - long_description="Securely and anonymously share files, host websites, and chat with friends using the Tor network", - author="Micah Lee", - author_email="micah@micahflee.com", - maintainer="Micah Lee", - maintainer_email="micah@micahflee.com", - url="https://onionshare.org", - license="GPLv3", - keywords="onion, share, onionshare, tor, anonymous, web server", - classifiers=[ - "Programming Language :: Python :: 3", - "Framework :: Flask", - "Topic :: Communications :: File Sharing", - "Topic :: Security :: Cryptography", - "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", - "Intended Audience :: End Users/Desktop", - "Operating System :: OS Independent", - "Environment :: Web Environment", - ], - packages=[ - "onionshare", - "onionshare.tab", - "onionshare.tab.mode", - "onionshare.tab.mode.share_mode", - "onionshare.tab.mode.receive_mode", - "onionshare.tab.mode.website_mode", - "onionshare.tab.mode.chat_mode", - ], - package_data={ - "onionshare": [ - "resources/*", - "resources/images/*", - "resources/images/countries/*", - "resources/locale/*", - "resources/countries/*", - ] - }, - entry_points={ - "console_scripts": [ - "onionshare = onionshare:main", - "onionshare-cli = onionshare_cli:main", - ], - }, ) diff --git a/docs/build.sh b/docs/build.sh index 9019c60e..1c2b32d2 100755 --- a/docs/build.sh +++ b/docs/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -VERSION=$(cat ../cli/onionshare_cli/resources/version.txt) +VERSION=$(cat ../cli/pyproject.toml | python -c 'import tomllib,sys;print(tomllib.load(sys.stdin)["project"]["version"])') # Supported locales LOCALES="en sq bg zh_CN de el ga ja pl ru es tr uk" diff --git a/flatpak/poetry-to-requirements.py b/flatpak/pyproject-to-requirements.py old mode 100755 new mode 100644 similarity index 67% rename from flatpak/poetry-to-requirements.py rename to flatpak/pyproject-to-requirements.py index 973e3c2e..b0afb3fc --- a/flatpak/poetry-to-requirements.py +++ b/flatpak/pyproject-to-requirements.py @@ -1,7 +1,12 @@ #!/usr/bin/env python3 -import toml +import sys import click +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + def format_version(dep, version): if version == "*": @@ -30,7 +35,7 @@ def format_version(dep, version): def poetry_to_requirements(pyproject_filename): """Convert poetry dependencies in a pyproject.toml to requirements format.""" with open(pyproject_filename, "r") as f: - data = toml.load(f) + data = tomllib.load(f) dependencies = data.get("tool", {}).get("poetry", {}).get("dependencies", {}) @@ -48,5 +53,26 @@ def poetry_to_requirements(pyproject_filename): print(req) +@click.command() +@click.argument("pyproject_filename") +def pyproject_to_requirements(pyproject_filename): + """Convert PEP 631 dependencies in a pyproject.toml to requirements format.""" + with open(pyproject_filename, "r") as f: + data = tomllib.load(f) + + dependencies = data.get("project", {}).get("dependencies", []) + + requirements = [] + + for dep in dependencies: + if dep == "onionshare_cli": + continue + + requirements.append(dependencies) + + for req in requirements: + print(req) + + if __name__ == "__main__": - poetry_to_requirements() + pyproject_to_requirements()