From 0c3201930c13190eebade4141d314640dfe2b2f3 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Sun, 24 May 2020 11:20:19 -0400 Subject: [PATCH 01/16] feat: added github actions only working with linux for now. exact replica of travis basically. should probably try to implement the rest of tox or deprecate some functionality. --- .github/workflows/ci.yaml | 77 ++++++++++++++++++++++++++++++++ beetsplug/export.py | 14 +++--- beetsplug/lyrics.py | 4 +- beetsplug/metasync/amarok.py | 4 +- beetsplug/plexupdate.py | 4 +- beetsplug/smartplaylist.py | 8 ++-- beetsplug/subsonicplaylist.py | 9 ++-- beetsplug/thumbnails.py | 2 +- setup.py | 4 +- test/test_export.py | 4 +- tox.ini | 83 +++++++++++++++++++---------------- 11 files changed, 150 insertions(+), 63 deletions(-) create mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..cbd6381e1 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,77 @@ +name: ci +on: push +jobs: + test-27: + runs-on: ${{ matrix.platform }} + strategy: + matrix: + platform: [ ubuntu-latest ] + env: + NOSE_SHOW_SKIPPED: 1 + steps: + - uses: actions/checkout@v2 + - name: Set up python 2.7 + uses: actions/setup-python@v2 + with: + python-version: 2.7 + - uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + - name: Install base dependencies + run: | + python -m pip install --upgrade pip + pip install tox sphinx + - name: Test with tox + run: | + tox -e py27-test + tox -e docs + test-3x: + runs-on: ${{ matrix.platform }} + strategy: + matrix: + platform: [ ubuntu-latest ] + python-version: [ 5, 6, 7, 8 ] + env: + NOSE_SHOW_SKIPPED: 1 + steps: + - uses: actions/checkout@v2 + - name: Set up python 3.${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: 3.${{ matrix.python-version }} + - uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + - name: Install base dependencies + run: | + python -m pip install --upgrade pip + pip install tox sphinx + - name: Test with tox + run: | + if [[ ${{ matrix.python-version }} == '8' ]]; then + tox -e py3${{ matrix.python-version }}-test + tox -e py3${{ matrix.python-version }}-cov + tox -e py3${{ matrix.python-version }}-flake8 + else + tox -e py3${{ matrix.python-version }}-test + fi + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python to build docs with sphinx + uses: actions/setup-python@v2 + with: + python-version: 2.7 + - name: Install base dependencies + run: | + python -m pip install --upgrade pip + python -m pip install tox sphinx + - name: Build and check docs using tox + run: tox -e docs \ No newline at end of file diff --git a/beetsplug/export.py b/beetsplug/export.py index f7e84a570..0b4876bbf 100644 --- a/beetsplug/export.py +++ b/beetsplug/export.py @@ -21,7 +21,7 @@ import sys import codecs import json import csv -import xml.etree.ElementTree as ET +import xml.etree.ElementTree as et from datetime import datetime, date from beets.plugins import BeetsPlugin @@ -188,18 +188,18 @@ class XMLFormat(ExportFormat): def export(self, data, **kwargs): # Creates the XML file structure. - library = ET.Element(u'library') - tracks = ET.SubElement(library, u'tracks') + library = et.Element(u'library') + tracks = et.SubElement(library, u'tracks') if data and isinstance(data[0], dict): for index, item in enumerate(data): - track = ET.SubElement(tracks, u'track') + track = et.SubElement(tracks, u'track') for key, value in item.items(): - track_details = ET.SubElement(track, key) + track_details = et.SubElement(track, key) track_details.text = value # Depending on the version of python the encoding needs to change try: - data = ET.tostring(library, encoding='unicode', **kwargs) + data = et.tostring(library, encoding='unicode', **kwargs) except LookupError: - data = ET.tostring(library, encoding='utf-8', **kwargs) + data = et.tostring(library, encoding='utf-8', **kwargs) self.out_stream.write(data) diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index 71e1d4ef3..f73d72dfd 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -907,7 +907,7 @@ class LyricsPlugin(plugins.BeetsPlugin): return _scrape_strip_cruft(lyrics, True) def append_translation(self, text, to_lang): - import xml.etree.ElementTree as ET + import xml.etree.ElementTree as et if not self.bing_auth_token: self.bing_auth_token = self.get_bing_access_token() @@ -925,7 +925,7 @@ class LyricsPlugin(plugins.BeetsPlugin): self.bing_auth_token = None return self.append_translation(text, to_lang) return text - lines_translated = ET.fromstring(r.text.encode('utf-8')).text + lines_translated = et.fromstring(r.text.encode('utf-8')).text # Use a translation mapping dict to build resulting lyrics translations = dict(zip(text_lines, lines_translated.split('|'))) result = '' diff --git a/beetsplug/metasync/amarok.py b/beetsplug/metasync/amarok.py index 0622fc17a..1d28eb3c9 100644 --- a/beetsplug/metasync/amarok.py +++ b/beetsplug/metasync/amarok.py @@ -49,7 +49,7 @@ class Amarok(MetaSource): 'amarok_lastplayed': DateType(), } - queryXML = u' \ + query_xml = u' \ \ \ \ @@ -72,7 +72,7 @@ class Amarok(MetaSource): # of the result set. So query for the filename and then try to match # the correct item from the results we get back results = self.collection.Query( - self.queryXML % quoteattr(basename(path)) + self.query_xml % quoteattr(basename(path)) ) for result in results: if result['xesam:url'] != path: diff --git a/beetsplug/plexupdate.py b/beetsplug/plexupdate.py index 17fd8208d..d3d7caf5c 100644 --- a/beetsplug/plexupdate.py +++ b/beetsplug/plexupdate.py @@ -12,7 +12,7 @@ Put something like the following in your config.yaml to configure: from __future__ import division, absolute_import, print_function import requests -import xml.etree.ElementTree as ET +import xml.etree.ElementTree as et from six.moves.urllib.parse import urljoin, urlencode from beets import config from beets.plugins import BeetsPlugin @@ -28,7 +28,7 @@ def get_music_section(host, port, token, library_name): r = requests.get(url) # Parse xml tree and extract music section key. - tree = ET.fromstring(r.content) + tree = et.fromstring(r.content) for child in tree.findall('Directory'): if child.get('title') == library_name: return child.get('key') diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py index 4ffdd21e7..f3157c96f 100644 --- a/beetsplug/smartplaylist.py +++ b/beetsplug/smartplaylist.py @@ -105,17 +105,17 @@ class SmartPlaylistPlugin(BeetsPlugin): playlist_data = (playlist['name'],) try: - for key, Model in (('query', Item), ('album_query', Album)): + for key, model in (('query', Item), ('album_query', Album)): qs = playlist.get(key) if qs is None: query_and_sort = None, None elif isinstance(qs, six.string_types): - query_and_sort = parse_query_string(qs, Model) + query_and_sort = parse_query_string(qs, model) elif len(qs) == 1: - query_and_sort = parse_query_string(qs[0], Model) + query_and_sort = parse_query_string(qs[0], model) else: # multiple queries and sorts - queries, sorts = zip(*(parse_query_string(q, Model) + queries, sorts = zip(*(parse_query_string(q, model) for q in qs)) query = OrQuery(queries) final_sorts = [] diff --git a/beetsplug/subsonicplaylist.py b/beetsplug/subsonicplaylist.py index c537c4093..a4577278a 100644 --- a/beetsplug/subsonicplaylist.py +++ b/beetsplug/subsonicplaylist.py @@ -17,7 +17,7 @@ from __future__ import absolute_import, division, print_function import random import string -import xml.etree.ElementTree as ET +import xml.etree.ElementTree as et from hashlib import md5 from urllib.parse import urlencode @@ -85,7 +85,7 @@ class SubsonicPlaylistPlugin(BeetsPlugin): def get_playlist(self, playlist_id): xml = self.send('getPlaylist', {'id': playlist_id}).text - playlist = ET.fromstring(xml)[0] + playlist = et.fromstring(xml)[0] if playlist.attrib.get('code', '200') != '200': alt_error = 'error getting playlist, but no error message found' self._log.warn(playlist.attrib.get('message', alt_error)) @@ -101,8 +101,9 @@ class SubsonicPlaylistPlugin(BeetsPlugin): self.config.set_args(opts) ids = self.config['playlist_ids'].as_str_seq() if self.config['playlist_names'].as_str_seq(): - playlists = ET.fromstring(self.send('getPlaylists').text)[ - 0] + playlists = et.fromstring( + self.send('getPlaylists').text + )[0] if playlists.attrib.get('code', '200') != '200': alt_error = 'error getting playlists,' \ ' but no error message found' diff --git a/beetsplug/thumbnails.py b/beetsplug/thumbnails.py index fe36fbd13..01da5afff 100644 --- a/beetsplug/thumbnails.py +++ b/beetsplug/thumbnails.py @@ -25,7 +25,7 @@ from hashlib import md5 import os import shutil from itertools import chain -from pathlib import PurePosixPath +from pathlib2 import PurePosixPath import ctypes import ctypes.util diff --git a/setup.py b/setup.py index c50e65bf5..0be671f5d 100755 --- a/setup.py +++ b/setup.py @@ -122,7 +122,7 @@ setup( 'requests_oauthlib' ] + ( # Tests for the thumbnails plugin need pathlib on Python 2 too. - ['pathlib'] if (sys.version_info < (3, 4, 0)) else [] + ['pathlib2'] if (sys.version_info < (3, 4, 0)) else [] ), # Plugin (optional) dependencies: @@ -144,7 +144,7 @@ setup( 'web': ['flask', 'flask-cors'], 'import': ['rarfile'], 'thumbnails': ['pyxdg', 'Pillow'] + - (['pathlib'] if (sys.version_info < (3, 4, 0)) else []), + (['pathlib2'] if (sys.version_info < (3, 4, 0)) else []), 'metasync': ['dbus-python'], 'sonosupdate': ['soco'], 'scrub': ['mutagen>=1.33'], diff --git a/test/test_export.py b/test/test_export.py index 757212a38..18b2b17be 100644 --- a/test/test_export.py +++ b/test/test_export.py @@ -23,7 +23,7 @@ from test.helper import TestHelper import re # used to test csv format import json from xml.etree.ElementTree import Element -import xml.etree.ElementTree as ET +import xml.etree.ElementTree as et class ExportPluginTest(unittest.TestCase, TestHelper): @@ -85,7 +85,7 @@ class ExportPluginTest(unittest.TestCase, TestHelper): format_type='xml', artist=item1.artist ) - library = ET.fromstring(out) + library = et.fromstring(out) self.assertIsInstance(library, Element) for track in library[0]: for details in track: diff --git a/tox.ini b/tox.ini index 19cb3069b..06f0bda8c 100644 --- a/tox.ini +++ b/tox.ini @@ -4,54 +4,63 @@ # and then run "tox" from this directory. [tox] -envlist = py27-test, py37-test, py27-flake8, docs +envlist = + py27-{test} + py38-{test,cov,flake8} + docs -# The exhaustive list of environments is: -# envlist = py{27,34,35}-{test,cov}, py{27,34,35}-flake8, docs +# exhaustive list +# py{27,35,36,37,38}-{test,cov,flake8}, docs -[_test] -deps = - beautifulsoup4 - flask - mock - nose - nose-show-skipped - pylast - rarfile - responses>=0.3.0 - pyxdg - python-mpd2 - coverage - discogs-client - requests_oauthlib - -[_flake8] -deps = - flake8 - flake8-coding - flake8-future-import - flake8-blind-except - pep8-naming~=0.7.0 -files = beets beetsplug beet test setup.py docs +[gh-actions:env] +PLATFORM = + ubuntu-latest: linux + windows-latest: windows [testenv] passenv = NOSE_SHOW_SKIPPED # Undocumented feature of nose-show-skipped. deps = {test,cov}: {[_test]deps} - py27: pathlib - py{27,34,35,36,37,38}-flake8: {[_flake8]deps} + flake8: {[_flake8]deps} + py27: pathlib2 commands = - py27-cov: python -m nose --with-coverage {posargs} py27-test: python -m nose {posargs} - py3{4,5,6,7,8}-cov: python -bb -m nose --with-coverage {posargs} + py38-cov: python -bb -m nose --with-coverage {posargs} + py38-flake8: flake8 {posargs} {[_flake8]files} py3{4,5,6,7,8}-test: python -bb -m nose {posargs} - py27-flake8: flake8 --min-version 2.7 {posargs} {[_flake8]files} - py34-flake8: flake8 --min-version 3.4 {posargs} {[_flake8]files} - py35-flake8: flake8 --min-version 3.5 {posargs} {[_flake8]files} - py36-flake8: flake8 --min-version 3.6 {posargs} {[_flake8]files} - py37-flake8: flake8 --min-version 3.7 {posargs} {[_flake8]files} - py38-flake8: flake8 --min-version 3.8 {posargs} {[_flake8]files} + +[_test] +deps = + beautifulsoup4 + coverage + flask + discogs-client + mock + nose + nose-show-skipped + pylast + python-mpd2 + pyxdg + rarfile + requests_oauthlib + responses + sphinx + +[_flake8] +deps = + flake8 + flake8-blind-except + flake8-coding + flake8-future-import + pep8-naming +files = + beet + beets + beetsplug + docs + setup.py + test [testenv:docs] basepython = python2.7 From 9f8bd4cd3fb1a9d92a270be39d76e77f1a168647 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Mon, 25 May 2020 19:39:40 -0400 Subject: [PATCH 02/16] style: flake8 linting --- beetsplug/export.py | 14 +++++++------- beetsplug/lyrics.py | 5 +++-- beetsplug/plexupdate.py | 4 ++-- beetsplug/subsonicplaylist.py | 9 ++++----- beetsplug/thumbnails.py | 2 +- setup.py | 4 ++-- test/test_export.py | 4 ++-- tox.ini | 2 +- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/beetsplug/export.py b/beetsplug/export.py index 0b4876bbf..8d98d0ba2 100644 --- a/beetsplug/export.py +++ b/beetsplug/export.py @@ -21,7 +21,7 @@ import sys import codecs import json import csv -import xml.etree.ElementTree as et +from xml.etree import ElementTree from datetime import datetime, date from beets.plugins import BeetsPlugin @@ -188,18 +188,18 @@ class XMLFormat(ExportFormat): def export(self, data, **kwargs): # Creates the XML file structure. - library = et.Element(u'library') - tracks = et.SubElement(library, u'tracks') + library = ElementTree.Element(u'library') + tracks = ElementTree.SubElement(library, u'tracks') if data and isinstance(data[0], dict): for index, item in enumerate(data): - track = et.SubElement(tracks, u'track') + track = ElementTree.SubElement(tracks, u'track') for key, value in item.items(): - track_details = et.SubElement(track, key) + track_details = ElementTree.SubElement(track, key) track_details.text = value # Depending on the version of python the encoding needs to change try: - data = et.tostring(library, encoding='unicode', **kwargs) + data = ElementTree.tostring(library, encoding='unicode', **kwargs) except LookupError: - data = et.tostring(library, encoding='utf-8', **kwargs) + data = ElementTree.tostring(library, encoding='utf-8', **kwargs) self.out_stream.write(data) diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index f73d72dfd..8807225a9 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -907,7 +907,7 @@ class LyricsPlugin(plugins.BeetsPlugin): return _scrape_strip_cruft(lyrics, True) def append_translation(self, text, to_lang): - import xml.etree.ElementTree as et + from xml.etree import ElementTree if not self.bing_auth_token: self.bing_auth_token = self.get_bing_access_token() @@ -925,7 +925,8 @@ class LyricsPlugin(plugins.BeetsPlugin): self.bing_auth_token = None return self.append_translation(text, to_lang) return text - lines_translated = et.fromstring(r.text.encode('utf-8')).text + lines_translated = ElementTree.fromstring( + r.text.encode('utf-8')).text # Use a translation mapping dict to build resulting lyrics translations = dict(zip(text_lines, lines_translated.split('|'))) result = '' diff --git a/beetsplug/plexupdate.py b/beetsplug/plexupdate.py index d3d7caf5c..ab3396191 100644 --- a/beetsplug/plexupdate.py +++ b/beetsplug/plexupdate.py @@ -12,7 +12,7 @@ Put something like the following in your config.yaml to configure: from __future__ import division, absolute_import, print_function import requests -import xml.etree.ElementTree as et +from xml.etree import ElementTree from six.moves.urllib.parse import urljoin, urlencode from beets import config from beets.plugins import BeetsPlugin @@ -28,7 +28,7 @@ def get_music_section(host, port, token, library_name): r = requests.get(url) # Parse xml tree and extract music section key. - tree = et.fromstring(r.content) + tree = ElementTree.fromstring(r.content) for child in tree.findall('Directory'): if child.get('title') == library_name: return child.get('key') diff --git a/beetsplug/subsonicplaylist.py b/beetsplug/subsonicplaylist.py index a4577278a..732b51c2f 100644 --- a/beetsplug/subsonicplaylist.py +++ b/beetsplug/subsonicplaylist.py @@ -17,7 +17,7 @@ from __future__ import absolute_import, division, print_function import random import string -import xml.etree.ElementTree as et +from xml.etree import ElementTree from hashlib import md5 from urllib.parse import urlencode @@ -85,7 +85,7 @@ class SubsonicPlaylistPlugin(BeetsPlugin): def get_playlist(self, playlist_id): xml = self.send('getPlaylist', {'id': playlist_id}).text - playlist = et.fromstring(xml)[0] + playlist = ElementTree.fromstring(xml)[0] if playlist.attrib.get('code', '200') != '200': alt_error = 'error getting playlist, but no error message found' self._log.warn(playlist.attrib.get('message', alt_error)) @@ -101,9 +101,8 @@ class SubsonicPlaylistPlugin(BeetsPlugin): self.config.set_args(opts) ids = self.config['playlist_ids'].as_str_seq() if self.config['playlist_names'].as_str_seq(): - playlists = et.fromstring( - self.send('getPlaylists').text - )[0] + playlists = ElementTree.fromstring( + self.send('getPlaylists').text)[0] if playlists.attrib.get('code', '200') != '200': alt_error = 'error getting playlists,' \ ' but no error message found' diff --git a/beetsplug/thumbnails.py b/beetsplug/thumbnails.py index 01da5afff..fe36fbd13 100644 --- a/beetsplug/thumbnails.py +++ b/beetsplug/thumbnails.py @@ -25,7 +25,7 @@ from hashlib import md5 import os import shutil from itertools import chain -from pathlib2 import PurePosixPath +from pathlib import PurePosixPath import ctypes import ctypes.util diff --git a/setup.py b/setup.py index 0be671f5d..c50e65bf5 100755 --- a/setup.py +++ b/setup.py @@ -122,7 +122,7 @@ setup( 'requests_oauthlib' ] + ( # Tests for the thumbnails plugin need pathlib on Python 2 too. - ['pathlib2'] if (sys.version_info < (3, 4, 0)) else [] + ['pathlib'] if (sys.version_info < (3, 4, 0)) else [] ), # Plugin (optional) dependencies: @@ -144,7 +144,7 @@ setup( 'web': ['flask', 'flask-cors'], 'import': ['rarfile'], 'thumbnails': ['pyxdg', 'Pillow'] + - (['pathlib2'] if (sys.version_info < (3, 4, 0)) else []), + (['pathlib'] if (sys.version_info < (3, 4, 0)) else []), 'metasync': ['dbus-python'], 'sonosupdate': ['soco'], 'scrub': ['mutagen>=1.33'], diff --git a/test/test_export.py b/test/test_export.py index 18b2b17be..779e74423 100644 --- a/test/test_export.py +++ b/test/test_export.py @@ -23,7 +23,7 @@ from test.helper import TestHelper import re # used to test csv format import json from xml.etree.ElementTree import Element -import xml.etree.ElementTree as et +from xml.etree import ElementTree class ExportPluginTest(unittest.TestCase, TestHelper): @@ -85,7 +85,7 @@ class ExportPluginTest(unittest.TestCase, TestHelper): format_type='xml', artist=item1.artist ) - library = et.fromstring(out) + library = ElementTree.fromstring(out) self.assertIsInstance(library, Element) for track in library[0]: for details in track: diff --git a/tox.ini b/tox.ini index 06f0bda8c..92086b820 100644 --- a/tox.ini +++ b/tox.ini @@ -23,7 +23,7 @@ passenv = deps = {test,cov}: {[_test]deps} flake8: {[_flake8]deps} - py27: pathlib2 + py27: pathlib commands = py27-test: python -m nose {posargs} py38-cov: python -bb -m nose --with-coverage {posargs} From 9a67cee95f442cd831163a6b262929f811ac93a7 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Mon, 25 May 2020 21:53:22 -0400 Subject: [PATCH 03/16] ci: added windows --- .github/workflows/ci.yaml | 42 +++++++++++++++++++++++++++------------ tox.ini | 1 + 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cbd6381e1..0f9ebbeba 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,8 +5,9 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ ubuntu-latest ] + platform: [ windows-latest, ubuntu-latest ] env: + PY_COLOR: 1 NOSE_SHOW_SKIPPED: 1 steps: - uses: actions/checkout@v2 @@ -15,26 +16,33 @@ jobs: with: python-version: 2.7 - uses: actions/cache@v1 + if: startsWith(runner.os, 'Linux') with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- + - uses: actions/cache@v1 + if: startsWith(runner.os, 'Windows') + with: + path: ~\AppData\Local\pip\Cache + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- - name: Install base dependencies run: | python -m pip install --upgrade pip pip install tox sphinx - name: Test with tox - run: | - tox -e py27-test - tox -e docs + run: tox -e py27-test test-3x: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ ubuntu-latest ] + platform: [ windows-latest, ubuntu-latest ] python-version: [ 5, 6, 7, 8 ] env: + PY_COLOR: 1 NOSE_SHOW_SKIPPED: 1 steps: - uses: actions/checkout@v2 @@ -43,24 +51,32 @@ jobs: with: python-version: 3.${{ matrix.python-version }} - uses: actions/cache@v1 + if: startsWith(runner.os, 'Linux') with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- + - uses: actions/cache@v1 + if: startsWith(runner.os, 'Windows') + with: + path: ~\AppData\Local\pip\Cache + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- - name: Install base dependencies run: | python -m pip install --upgrade pip pip install tox sphinx - - name: Test with tox + - name: Test, coverage, and flake8 with tox + if: matrix.python-version == '8' run: | - if [[ ${{ matrix.python-version }} == '8' ]]; then - tox -e py3${{ matrix.python-version }}-test - tox -e py3${{ matrix.python-version }}-cov - tox -e py3${{ matrix.python-version }}-flake8 - else - tox -e py3${{ matrix.python-version }}-test - fi + tox -e py3${{ matrix.python-version }}-test + tox -e py3${{ matrix.python-version }}-cov + tox -e py3${{ matrix.python-version }}-flake8 + - name: Test with tox + if: matrix.python-version != '8' + run: tox -e py3${{ matrix.python-version }}-test docs: runs-on: ubuntu-latest steps: diff --git a/tox.ini b/tox.ini index 92086b820..b02e491fb 100644 --- a/tox.ini +++ b/tox.ini @@ -19,6 +19,7 @@ PLATFORM = [testenv] passenv = + LANG # avoids output errors NOSE_SHOW_SKIPPED # Undocumented feature of nose-show-skipped. deps = {test,cov}: {[_test]deps} From b0f456b3c3410a9af3a78169801c5f55e39e839a Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Mon, 25 May 2020 23:18:59 -0400 Subject: [PATCH 04/16] ci: removed windows for now has to do with UnicodeDecodeError --- .github/workflows/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0f9ebbeba..f38ce898e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,7 +5,7 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ windows-latest, ubuntu-latest ] + platform: [ ubuntu-latest ] env: PY_COLOR: 1 NOSE_SHOW_SKIPPED: 1 @@ -39,7 +39,7 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ windows-latest, ubuntu-latest ] + platform: [ ubuntu-latest ] python-version: [ 5, 6, 7, 8 ] env: PY_COLOR: 1 From e8693acb6ae41c1824f0258b6b1e02e9d04402e1 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Tue, 26 May 2020 10:40:10 -0400 Subject: [PATCH 05/16] docs: elaborated exhaustive list Co-authored-by: Adrian Sampson --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index b02e491fb..055f1e572 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ envlist = py38-{test,cov,flake8} docs -# exhaustive list +# The exhaustive list of environments is: # py{27,35,36,37,38}-{test,cov,flake8}, docs [gh-actions:env] From 0068afcb991a4c911142975f1a33dd3b5ab95c3b Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Tue, 26 May 2020 12:40:23 -0400 Subject: [PATCH 06/16] feat: add more options to tox --- tox.ini | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 055f1e572..7c32fc460 100644 --- a/tox.ini +++ b/tox.ini @@ -26,9 +26,11 @@ deps = flake8: {[_flake8]deps} py27: pathlib commands = + py27-cov: python -m nose --with-coverage {posargs} + py27-flake8: flake8 {posargs} {[_flake8]files} py27-test: python -m nose {posargs} - py38-cov: python -bb -m nose --with-coverage {posargs} - py38-flake8: flake8 {posargs} {[_flake8]files} + py3{4,5,6,7,8}-cov: python -bb -m nose --with-coverage {posargs} + py3{4,5,6,7,8}-flake8: flake8 {posargs} {[_flake8]files} py3{4,5,6,7,8}-test: python -bb -m nose {posargs} [_test] From 9c93b4d35652c2b0aa90f1d5b1cc67bfeebb88ef Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Wed, 27 May 2020 16:36:27 -0400 Subject: [PATCH 07/16] docs: update punctuation Co-authored-by: Adrian Sampson --- .github/workflows/ci.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f38ce898e..5c736e1ba 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,7 +11,7 @@ jobs: NOSE_SHOW_SKIPPED: 1 steps: - uses: actions/checkout@v2 - - name: Set up python 2.7 + - name: Set up Python 2.7 uses: actions/setup-python@v2 with: python-version: 2.7 @@ -46,7 +46,7 @@ jobs: NOSE_SHOW_SKIPPED: 1 steps: - uses: actions/checkout@v2 - - name: Set up python 3.${{ matrix.python-version }} + - name: Set up Python 3.${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: 3.${{ matrix.python-version }} @@ -81,7 +81,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up Python to build docs with sphinx + - name: Set up Python to build docs with Sphinx uses: actions/setup-python@v2 with: python-version: 2.7 @@ -90,4 +90,4 @@ jobs: python -m pip install --upgrade pip python -m pip install tox sphinx - name: Build and check docs using tox - run: tox -e docs \ No newline at end of file + run: tox -e docs From 18645ffbe4b406fd9d7d21d465a5b21c78672bd7 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 00:26:33 -0400 Subject: [PATCH 08/16] chore(tox): revert changes --- tox.ini | 72 ++++++++++++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/tox.ini b/tox.ini index 7c32fc460..2e56f6107 100644 --- a/tox.ini +++ b/tox.ini @@ -4,68 +4,56 @@ # and then run "tox" from this directory. [tox] -envlist = - py27-{test} - py38-{test,cov,flake8} - docs +envlist = py27-test, py37-test, py27-flake8, docs # The exhaustive list of environments is: -# py{27,35,36,37,38}-{test,cov,flake8}, docs - -[gh-actions:env] -PLATFORM = - ubuntu-latest: linux - windows-latest: windows - -[testenv] -passenv = - LANG # avoids output errors - NOSE_SHOW_SKIPPED # Undocumented feature of nose-show-skipped. -deps = - {test,cov}: {[_test]deps} - flake8: {[_flake8]deps} - py27: pathlib -commands = - py27-cov: python -m nose --with-coverage {posargs} - py27-flake8: flake8 {posargs} {[_flake8]files} - py27-test: python -m nose {posargs} - py3{4,5,6,7,8}-cov: python -bb -m nose --with-coverage {posargs} - py3{4,5,6,7,8}-flake8: flake8 {posargs} {[_flake8]files} - py3{4,5,6,7,8}-test: python -bb -m nose {posargs} +# envlist = py{27,34,35}-{test,cov}, py{27,34,35}-flake8, docs [_test] deps = beautifulsoup4 - coverage flask - discogs-client mock nose nose-show-skipped pylast - python-mpd2 - pyxdg rarfile + responses>=0.3.0 + pyxdg + python-mpd2 + coverage + discogs-client requests_oauthlib - responses - sphinx [_flake8] deps = flake8 - flake8-blind-except flake8-coding flake8-future-import - pep8-naming -files = - beet - beets - beetsplug - docs - setup.py - test + flake8-blind-except + pep8-naming~=0.7.0 +files = beets beetsplug beet test setup.py docs + +[testenv] +passenv = + NOSE_SHOW_SKIPPED # Undocumented feature of nose-show-skipped. +deps = + {test,cov}: {[_test]deps} + py27: pathlib + py{27,34,35,36,37,38}-flake8: {[_flake8]deps} +commands = + py27-cov: python -m nose --with-coverage {posargs} + py27-test: python -m nose {posargs} + py3{4,5,6,7,8}-cov: python -bb -m nose --with-coverage {posargs} + py3{4,5,6,7,8}-test: python -bb -m nose {posargs} + py27-flake8: flake8 --min-version 2.7 {posargs} {[_flake8]files} + py34-flake8: flake8 --min-version 3.4 {posargs} {[_flake8]files} + py35-flake8: flake8 --min-version 3.5 {posargs} {[_flake8]files} + py36-flake8: flake8 --min-version 3.6 {posargs} {[_flake8]files} + py37-flake8: flake8 --min-version 3.7 {posargs} {[_flake8]files} + py38-flake8: flake8 --min-version 3.8 {posargs} {[_flake8]files} [testenv:docs] basepython = python2.7 deps = sphinx -commands = sphinx-build -W -q -b html docs {envtmpdir}/html {posargs} +commands = sphinx-build -W -q -b html docs {envtmpdir}/html {posargs} \ No newline at end of file From e66cfd58ad679f02a37480717b19de9c1077e7e4 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 01:09:35 -0400 Subject: [PATCH 09/16] feat: add windows into ci --- .github/workflows/ci.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5c736e1ba..50ab7462a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,10 +5,11 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ ubuntu-latest ] + platform: [ windows-latest, ubuntu-latest ] env: - PY_COLOR: 1 NOSE_SHOW_SKIPPED: 1 + PY_COLOR: 1 + PYTHONIOENCODING: utf-8 steps: - uses: actions/checkout@v2 - name: Set up Python 2.7 @@ -39,11 +40,12 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ ubuntu-latest ] + platform: [ windows-latest, ubuntu-latest ] python-version: [ 5, 6, 7, 8 ] env: - PY_COLOR: 1 NOSE_SHOW_SKIPPED: 1 + PY_COLOR: 1 + PYTHONIOENCODING: utf-8 steps: - uses: actions/checkout@v2 - name: Set up Python 3.${{ matrix.python-version }} From 26caef544f5e2f5996dedaed3e6e20e99f9a5d1f Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 01:21:46 -0400 Subject: [PATCH 10/16] fix: remove `--min-version` --- tox.ini | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tox.ini b/tox.ini index 19cb3069b..9c1bc4106 100644 --- a/tox.ini +++ b/tox.ini @@ -46,12 +46,12 @@ commands = py27-test: python -m nose {posargs} py3{4,5,6,7,8}-cov: python -bb -m nose --with-coverage {posargs} py3{4,5,6,7,8}-test: python -bb -m nose {posargs} - py27-flake8: flake8 --min-version 2.7 {posargs} {[_flake8]files} - py34-flake8: flake8 --min-version 3.4 {posargs} {[_flake8]files} - py35-flake8: flake8 --min-version 3.5 {posargs} {[_flake8]files} - py36-flake8: flake8 --min-version 3.6 {posargs} {[_flake8]files} - py37-flake8: flake8 --min-version 3.7 {posargs} {[_flake8]files} - py38-flake8: flake8 --min-version 3.8 {posargs} {[_flake8]files} + py27-flake8: flake8 {posargs} {[_flake8]files} + py34-flake8: flake8 {posargs} {[_flake8]files} + py35-flake8: flake8 {posargs} {[_flake8]files} + py36-flake8: flake8 {posargs} {[_flake8]files} + py37-flake8: flake8 {posargs} {[_flake8]files} + py38-flake8: flake8 {posargs} {[_flake8]files} [testenv:docs] basepython = python2.7 From f0534090c32ec386b8dfc21248b5426a70a271be Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 01:26:09 -0400 Subject: [PATCH 11/16] fix: revert add windows to ci --- .github/workflows/ci.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 50ab7462a..bec58f700 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,11 +5,10 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ windows-latest, ubuntu-latest ] + platform: [ ubuntu-latest ] env: NOSE_SHOW_SKIPPED: 1 PY_COLOR: 1 - PYTHONIOENCODING: utf-8 steps: - uses: actions/checkout@v2 - name: Set up Python 2.7 @@ -40,12 +39,11 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ windows-latest, ubuntu-latest ] + platform: [ ubuntu-latest ] python-version: [ 5, 6, 7, 8 ] env: NOSE_SHOW_SKIPPED: 1 PY_COLOR: 1 - PYTHONIOENCODING: utf-8 steps: - uses: actions/checkout@v2 - name: Set up Python 3.${{ matrix.python-version }} From b9068e3fbd22409509da61a5a693bfbe174b6b16 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 01:40:05 -0400 Subject: [PATCH 12/16] fix: flake8 problem --- beets/autotag/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 9bdf6b001..9841360ea 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -332,7 +332,7 @@ class Distance(object): self._penalties = {} @LazyClassProperty - def _weights(cls): # noqa + def _weights(self, cls): # noqa """A dictionary from keys to floating-point weights. """ weights_view = config['match']['distance_weights'] From 42e5844564740fd5fc5ba3393e03d96522352ff9 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 01:48:48 -0400 Subject: [PATCH 13/16] fix: revert flake8 change --- beets/autotag/hooks.py | 2 +- beetsplug/smartplaylist.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 9841360ea..9bdf6b001 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -332,7 +332,7 @@ class Distance(object): self._penalties = {} @LazyClassProperty - def _weights(self, cls): # noqa + def _weights(cls): # noqa """A dictionary from keys to floating-point weights. """ weights_view = config['match']['distance_weights'] diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py index f3157c96f..700b0c76a 100644 --- a/beetsplug/smartplaylist.py +++ b/beetsplug/smartplaylist.py @@ -105,17 +105,18 @@ class SmartPlaylistPlugin(BeetsPlugin): playlist_data = (playlist['name'],) try: - for key, model in (('query', Item), ('album_query', Album)): + for key, model_cls in (('query', Item), + ('album_query', Album)): qs = playlist.get(key) if qs is None: query_and_sort = None, None elif isinstance(qs, six.string_types): - query_and_sort = parse_query_string(qs, model) + query_and_sort = parse_query_string(qs, model_cls) elif len(qs) == 1: - query_and_sort = parse_query_string(qs[0], model) + query_and_sort = parse_query_string(qs[0], model_cls) else: # multiple queries and sorts - queries, sorts = zip(*(parse_query_string(q, model) + queries, sorts = zip(*(parse_query_string(q, model_cls) for q in qs)) query = OrQuery(queries) final_sorts = [] From 14dc285b4f6348729e6cb3c7173fa3f786ef75b8 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 21:55:47 -0400 Subject: [PATCH 14/16] chore(flake8): update comment and version --- beets/autotag/hooks.py | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 9bdf6b001..065d88170 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -332,7 +332,7 @@ class Distance(object): self._penalties = {} @LazyClassProperty - def _weights(cls): # noqa + def _weights(cls): # noqa: N805 """A dictionary from keys to floating-point weights. """ weights_view = config['match']['distance_weights'] diff --git a/tox.ini b/tox.ini index 9c1bc4106..047784f8b 100644 --- a/tox.ini +++ b/tox.ini @@ -31,7 +31,7 @@ deps = flake8-coding flake8-future-import flake8-blind-except - pep8-naming~=0.7.0 + pep8-naming files = beets beetsplug beet test setup.py docs [testenv] From c095429123c319fb355d22667a434dd1e64f42e5 Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 22:03:16 -0400 Subject: [PATCH 15/16] feat: remove Travis CI in favor of GitHub Actions --- .travis.yml | 87 ----------------------------------------------------- 1 file changed, 87 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b889f698d..000000000 --- a/.travis.yml +++ /dev/null @@ -1,87 +0,0 @@ -dist: trusty -sudo: required -language: python - -env: - global: - # Undocumented feature of nose-show-skipped. - NOSE_SHOW_SKIPPED: 1 - -matrix: - include: - - python: 2.7.13 - env: {TOX_ENV: py27-cov, COVERAGE: 1} - - python: 2.7.13 - env: {TOX_ENV: py27-test} - # - python: 3.4 - # env: {TOX_ENV: py34-test} - # - python: 3.4_with_system_site_packages - # env: {TOX_ENV: py34-test} - - python: 3.5 - env: {TOX_ENV: py35-test} - - python: 3.6 - env: {TOX_ENV: py36-test} - - python: 3.7 - env: {TOX_ENV: py37-test} - dist: xenial - - python: 3.8 - env: {TOX_ENV: py38-test} - dist: xenial - # - python: pypy - # - env: {TOX_ENV: pypy-test} - - python: 3.6 - env: {TOX_ENV: py36-flake8} - - python: 2.7.13 - env: {TOX_ENV: docs} -# Non-Python dependencies. -addons: - apt: - sources: - - sourceline: "deb https://archive.ubuntu.com/ubuntu/ trusty multiverse" - - sourceline: "deb https://archive.ubuntu.com/ubuntu/ trusty-updates multiverse" - packages: - - bash-completion - - gir1.2-gst-plugins-base-1.0 - - gir1.2-gstreamer-1.0 - - gstreamer1.0-plugins-good - - gstreamer1.0-plugins-bad - - imagemagick - - python-gi - - python-gst-1.0 - - python3-gi - - python3-gst-1.0 - - unrar - -# To install dependencies, tell tox to do everything but actually running the -# test. -install: - - travis_retry pip install tox sphinx - # upgrade requests to satisfy sphinx linkcheck (for building man pages) - - if [[ $TRAVIS_PYTHON_VERSION == *_site_packages ]]; then pip install -U requests; fi - - travis_retry tox -e $TOX_ENV --notest - -script: - # prevents "libdc1394 error: Failed to initialize libdc1394" errors - - sudo ln -s /dev/null /dev/raw1394 - - if [[ $TRAVIS_PYTHON_VERSION == *_site_packages ]]; then SITE_PACKAGES=--sitepackages; fi - # pip in trusty breaks on packages prefixed with "_". See https://github.com/pypa/pip/issues/3681 - - if [[ $TRAVIS_PYTHON_VERSION == 3.4_with_system_site_packages ]]; then sudo rm -rf /usr/lib/python3/dist-packages/_lxc-0.1.egg-info; fi - - tox -e $TOX_ENV $SITE_PACKAGES - -# Report coverage to codecov.io. -before_install: - - "[ ! -z $COVERAGE ] && travis_retry pip install codecov || true" -after_success: - - "[ ! -z $COVERAGE ] && codecov || true" - -cache: - pip: true - -notifications: - irc: - channels: - - "irc.freenode.org#beets" - use_notice: true - skip_join: true - on_success: change - on_failure: always From a96059634ca80a907d2a5f9d7d4302da0445ed9d Mon Sep 17 00:00:00 2001 From: Jef LeCompte Date: Thu, 4 Jun 2020 22:09:18 -0400 Subject: [PATCH 16/16] feat: add `codecov` to GitHub Actions --- .github/workflows/ci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bec58f700..0f2c625a3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -74,6 +74,8 @@ jobs: tox -e py3${{ matrix.python-version }}-test tox -e py3${{ matrix.python-version }}-cov tox -e py3${{ matrix.python-version }}-flake8 + pip install codecov || true + codecov || true - name: Test with tox if: matrix.python-version != '8' run: tox -e py3${{ matrix.python-version }}-test