diff --git a/.gitignore b/.gitignore index 88b32b4..16113aa 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,7 @@ venv .venv test_result.xml .python-version +test_result_async.xml +.venv/ build/ +*.orig diff --git a/HISTORY.rst b/HISTORY.rst index aa5a4f9..29496ce 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,38 +1,84 @@ +====================== +Pure Python ADB Reborn +====================== + +Pure Python ADB was originially created by `@swind`_. +When it was no longer being maintained, it was forked to create Pure Python ADB Reborn. + +1.0.0 +----- +* Fixes #6: Fix looping in uninstall if uninstall fails due to device admin +* Fixes swind#111: Invalid escape sequence via `@eamanu`_ and `@mib1185`_ +* Fixes swind#110: Add ability to pass extra arguments to ``screencap`` commands for waydroid via `@CloCkWeRX`_ +* Fixes swind#88: Missing return in ``ppadb.command.transport`` : ``Transport.shell()`` for custom handler via `@roxen`_ +* Fixes swind#60: Close socket if the connection fails via `@JeffLIrion`_ +* Fixes swind#64: ADB reverse command via `@Hamz-a`_ +* Fixes swind#92: incorrect timestamp type in asynchronous push via `@slicen`_ and `@GeekDuanLian`_ +* Adds #2: Pull directory via `@ACButcher`_ +* Adds swind#65: Added support to remove reverses via `@Hamz-a`_ +* Adds swind#67: asynchronous install and uninstall commands via `@slicen`_ +* Adds swind#85: Include LICENSE in pip package via `@jan-janssen`_ +* Adds swind#57: Recursive directory push for DeviceAsync class via `@JeffLIrion`_ +* Adds swind#89: Call disable-user if app is device-admin via `@eybisi`_ +* Change swind#94: Device#install and DeviceAsync#install changes param from ``grand_all_permissions`` to ``grant_all_permissions`` + + +Pure Python ADB (Legacy) +======================== + 0.3.0 (Unreleased) --------------------- - -* Fixes #111: Invalid escape sequence via @eamanu and @mib1185 -* Fixes #110: Add ability to pass extra arguments to `screencap` commands for waydroid via @CloCkWeRX -* Fixes #88: Missing return in ppadb.command.transport: Transport.shell() for custom handler via @roxen -* Fixes #60: Close socket if the connection fails via @JeffLIrion -* Fixes #64: ADB reverse command via @Hamz-a -* Fixes #92: incorrect timestamp type in asynchronous push via @slicen and @GeekDuanLian -* Adds #65: Added support to remove reverses via @Hamz-a -* Adds #67: asynchronous install and uninstall commands via @slicen -* Adds #85: Include LICENSE in pip package via @jan-janssen -* Adds #57: Recursive directory push for DeviceAsync class via @JeffLIrion -* Adds #89: Call disable-user if app is device-admin via @eybisi -* Change #94: Device#install and DeviceAsync#install changes param from `grand_all_permissions` to `grant_all_permissions` +------------------ +* Fixes swind#53: Check length of screenshot before indexing into it `@JeffLIrion`_ +* Adds swind#47: Async support `@JeffLIrion`_ 0.2.1 (2019-10-14) --------------------- +------------------ -* Fixes #21: Rename the package name from "adb" to "ppadb" -* Fixes #23: Support push dir to device -* Fixes #25: Don't call logging.basicConfig() in the module +* Fixes swind#21: Rename the package name from "adb" to "ppadb" +* Fixes swind#23: Support push dir to device +* Fixes swind#25: Don't call logging.basicConfig() in the module 0.1.6 (2019-01-21) -------------------- +------------------ -* Fix #4 push does not preserve original timestap unlike equiv adb push from command line -* Fix #6 forward_list should also check serial -* Fix #8: adb/command/host/__init__.py can take an exception parsing "devices" data +* Fix swind#4: push does not preserve original timestap unlike equiv adb push from command line +* Fix swind#6: forward_list should also check serial +* Fix swind#8: adb/command/host/__init__.py can take an exception parsing "devices" data 0.1.0 (2018-06-23) -------------------- +------------------ * First release on PyPI. + +Contributors +============ + +*`@ACButcher`_ +*`@CloCkWeRX`_ +*`@eamanu`_ +*`@eybisi`_ +*`@GeekDuanLian`_ +*`@Hamz-a`_ +*`@jan-janssen`_ +*`@JeffLIrion`_ +*`@mib1185`_ +*`@roxen`_ +*`@slicen`_ +*`@swind`_ + +.. _@ACButcher: https://githib.com/ACButcher +.. _@CloCkWeRX: https://github.com/CloCkWeRX +.. _@eamanu: https://github.com/eamanu +.. _@eybisi: https://github.com/eybisi +.. _@GeekDuanLian: https://github.com/GeekDuanLian +.. _@Hamz-a: https://github.com/Hamz-a +.. _@jan-janssen: https://github.com/jan-janssen +.. _@JeffLIrion: https://github.com/JeffLIrion +.. _@mib1185: https://github.com/mib1185 +.. _@roxen: https://github.com/roxen +.. _@slicen: https://github.com/slicen +.. _@swind: https://github.com/swind diff --git a/README.rst b/README.rst index f111f98..5f3ace3 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,6 @@ -This package is a fork of ppadb (https://github.com/swind/pure-python-adb) +Pure Python ADB Reborn ========================================================= +This package is a fork of Pure Python ADB (https://github.com/swind/pure-python-adb) Pure Python ADB was not being maintained, so it was forked to give new life to it. As such, it has been renamed to ppadb-reborn on PyPi. diff --git a/docker-compose.yaml b/docker-compose.yaml index 37e5705..b8a8535 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,7 +10,7 @@ services: environment: - PYTHONPATH=/code - PYTHONUNBUFFERED=0 - command: sh -c "pip install -r requirements.txt;py.test test -s -v --junit-xml test_result.xml;py.test test_async -s -v --junit-xml test_result_async.xml;" + command: sh -c "pip install .[dev];py.test test -s -v --junit-xml test_result.xml;py.test test_async -s -v --junit-xml test_result_async.xml;" emulator: image: swind/android-emulator:android_28 diff --git a/ppadb/__init__.py b/ppadb/__init__.py index 0416103..48a0dfc 100644 --- a/ppadb/__init__.py +++ b/ppadb/__init__.py @@ -1,6 +1,3 @@ -__version__ = "0.3.0-dev" - - class InstallError(Exception): def __init__(self, path, error): super(InstallError, self).__init__( diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..50fed6d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = [ + "setuptools>=64", + "setuptools-scm>=8" +] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +exclude = ["*.test", "*.test.*", "test.*", "test"] + +[project] +name = "pure-python-adb-reborn" +maintainers = [ + {name = "Sergio Martins"}, + {name = "Andrew Butcher"}, +] +description = "Pure python implementation of the adb client." +dynamic = [ + "dependencies", + "version" +] +license = {text = "MIT"} +readme = "README.rst" +requires-python = ">= 3.12" + +keywords = [ + "adb", + "android", + "async", +] +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3', + 'Topic :: Software Development :: Testing', +] + +[tool.setuptools.dynamic] +dependencies = {file = ["requirements.txt"]} + +[tool.setuptools_scm] +fallback_version=">0.3.0" +normalize=false + +[project.urls] +Repository = "https://github.com/spm5065/pure-python-adb.git" +Issues = "https://github.com/spm5065/pure-python-adb/issues" +Changelog = "https://github.com/spm5065/pure-python-adb/blob/master/HISTORY.rst" diff --git a/requirements.txt b/requirements.txt index 0e59c78..108ef25 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,7 @@ -pytest Exscript aiofiles >= 0.4.0 + +# Dev +pytest[dev] +black[dev] +ruff[dev] diff --git a/setup.py b/setup.py deleted file mode 100644 index f2cf73b..0000000 --- a/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -"""The setup script.""" - -from setuptools import setup, find_packages - -with open("README.rst") as readme_file: - readme = readme_file.read() - -with open("HISTORY.rst") as history_file: - history = history_file.read() - -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Testing", -] - -setup( - name="pure-python-adb", - version="0.3.0-dev", - description="Pure python implementation of the adb client, forked and maintained", - long_description=readme + "\n\n" + history, - author="Sergio Martins", - author_email="", - url="https://github.com/spm5065/pure-python-adb", - license="MIT license", - packages=find_packages(exclude=["*.test", "*.test.*", "test.*", "test"]), - install_requires=[], - extras_require={"async": ["aiofiles>=0.4.0"]}, - keywords="adb", - classifiers=classifiers, -) diff --git a/test_async/test_device_async.py b/test_async/test_device_async.py index 226f38a..c0db5a6 100644 --- a/test_async/test_device_async.py +++ b/test_async/test_device_async.py @@ -99,10 +99,11 @@ def progress(*args, **kwargs): pass filedata = b"Ohayou sekai.\nGood morning world!" - with patch("os.path.exists", return_value=True), patch( - "os.path.isfile", return_value=True - ), patch("os.stat", return_value=os.stat_result((123,) * 10)), patch( - "ppadb.sync_async.aiofiles.open", async_mock_open(FILEDATA) + with ( + patch("os.path.exists", return_value=True), + patch("os.path.isfile", return_value=True), + patch("os.stat", return_value=os.stat_result((123,) * 10)), + patch("ppadb.sync_async.aiofiles.open", async_mock_open(FILEDATA)), ): with async_patch( "asyncio.open_connection", @@ -123,24 +124,34 @@ def progress(*args, **kwargs): @awaiter async def test_push_dir(self): - with patch("pathlib.Path.exists", return_value=True), patch( - "os.path.isfile", return_value=False - ), patch("os.path.isdir", return_value=True), patch( - "os.walk", - return_value=[("root1", "dirs1", "files1"), ("root2", "dirs2", "files2")], + with ( + patch("pathlib.Path.exists", return_value=True), + patch("os.path.isfile", return_value=False), + patch("os.path.isdir", return_value=True), + patch( + "os.walk", + return_value=[ + ("root1", "dirs1", "files1"), + ("root2", "dirs2", "files2"), + ], + ), ): - with async_patch("ppadb.device_async.DeviceAsync.shell"), async_patch( - "ppadb.device_async.DeviceAsync._push" + with ( + async_patch("ppadb.device_async.DeviceAsync.shell"), + async_patch("ppadb.device_async.DeviceAsync._push"), ): await self.device.push("src", "dest") @awaiter async def test_pull(self): - with async_patch( - "asyncio.open_connection", - return_value=(FakeStreamReader(), FakeStreamWriter()), - ), async_patch( - "ppadb.device_async.DeviceAsync.shell", return_value=["", "IS_FILE"] + with ( + async_patch( + "asyncio.open_connection", + return_value=(FakeStreamReader(), FakeStreamWriter()), + ), + async_patch( + "ppadb.device_async.DeviceAsync.shell", return_value=["", "IS_FILE"] + ), ): with async_patch( "{}.FakeStreamReader.read".format(__name__), @@ -159,11 +170,14 @@ async def test_pull(self): @awaiter async def test_pull_fail(self): - with async_patch( - "asyncio.open_connection", - return_value=(FakeStreamReader(), FakeStreamWriter()), - ), async_patch( - "ppadb.device_async.DeviceAsync.shell", return_value=["", "IS_FILE"] + with ( + async_patch( + "asyncio.open_connection", + return_value=(FakeStreamReader(), FakeStreamWriter()), + ), + async_patch( + "ppadb.device_async.DeviceAsync.shell", return_value=["", "IS_FILE"] + ), ): with async_patch( "{}.FakeStreamReader.read".format(__name__),