diff --git a/.gitignore b/.gitignore
index 894a44c..1993236 100644
--- a/.gitignore
+++ b/.gitignore
@@ -47,58 +47,17 @@ coverage.xml
.hypothesis/
.pytest_cache/
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-db.sqlite3
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
# Sphinx documentation
docs/_build/
# PyBuilder
target/
-# Jupyter Notebook
-.ipynb_checkpoints
-
# pyenv
.python-version
-# celery beat schedule file
-celerybeat-schedule
+node_modules
-# SageMath parsed files
-*.sage.py
-
-# Environments
-.env
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
+# Generated
+ChangeLog
+AUTHORS
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..49d7703
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,28 @@
+---
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v1.3.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: mixed-line-ending
+ - id: check-byte-order-marker
+ - id: check-executables-have-shebangs
+ - id: check-merge-conflict
+ - id: check-symlinks
+ - id: check-vcs-permalinks
+ - id: flake8
+ - id: debug-statements
+ - id: requirements-txt-fixer
+ - id: check-yaml
+ files: .*\.(yaml|yml)$
+ - repo: https://github.com/adrienverge/yamllint.git
+ rev: v1.11.1
+ hooks:
+ - id: yamllint
+ files: \.(yaml|yml)$
+
+ - repo: https://github.com/openstack-dev/bashate.git
+ rev: 0.6.0
+ hooks:
+ - id: bashate
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..e063e28
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,38 @@
+---
+language: python
+cache:
+ - pip
+ - directories:
+ - "node_modules"
+ - $HOME/.cache
+os:
+ - linux
+stages:
+ - phase1
+before_install:
+ - nvm install $TRAVIS_NODE_VERSION
+ - >
+ which tox >/dev/null ||
+ if [ -z ${VIRTUAL_ENV+x} ];
+ then python -m pip install --user tox tox-pyenv;
+ else python -m pip install tox tox-pyenv twine;
+ fi
+notifications:
+ email:
+ - sorin.sbarnea@gmail.com
+jobs:
+ include:
+ - stage: phase1
+ script:
+ # package building added here purely to fail-fast if is broken
+ - python setup.py sdist bdist_wheel
+ - python -m tox
+ env: TOXENV=linters
+ python: "2.7"
+ language: nodejs
+ node_js:
+ - "8"
+env:
+ global:
+ - PIP_DISABLE_PIP_VERSION_CHECK=1
+ - TRAVIS_NODE_VERSION="v8.11.3"
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..8f277fb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,51 @@
+all: info clean test dist upload release
+.PHONY: all docs upload info req dist
+
+PACKAGE_NAME := $(shell python setup.py --name)
+PACKAGE_VERSION := $(shell python setup.py --version)
+PYTHON_PATH := $(shell which python)
+PLATFORM := $(shell uname -s | awk '{print tolower($$0)}')
+ifeq ($(PLATFORM), darwin)
+ DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+else
+ DIR := $(shell dirname $(realpath $(MAKEFILE_LIST)))
+endif
+PYTHON_VERSION := $(shell python3 -c "import sys; print('py%s%s' % sys.version_info[0:2] + ('-conda' if 'conda' in sys.version or 'Continuum' in sys.version else ''))")
+ifneq (,$(findstring conda, $(PYTHON_VERSION)))
+ #CONDA := $(shell conda info --envs | grep '*' | awk '{print $$1}')
+ CONDA := $(CONDA_DEFAULT_ENV)
+endif
+
+PREFIX :=
+ifndef GIT_BRANCH
+GIT_BRANCH=$(shell git branch | sed -n '/\* /s///p')
+endif
+
+info:
+ @echo "INFO: Building $(PACKAGE_NAME):$(PACKAGE_VERSION) on $(GIT_BRANCH) branch"
+ @echo "INFO: Python $(PYTHON_VERSION) from '$(PREFIX)' [$(CONDA)]"
+
+clean:
+ @find . -name "*.pyc" -delete
+ @rm -rf .tox dist/* docs/build/*
+
+package:
+ python setup.py sdist bdist_wheel build_sphinx
+
+install: prepare
+ $(PREFIX)pip install .
+
+uninstall:
+ $(PREFIX)pip uninstall -y $(PACKAGE_NAME)
+
+test:
+ $(PREFIX)tox
+
+dist:
+ rm -f dist/*
+ $(PREFIX)python setup.py sdist bdist_wheel
+
+upload: dist
+ @echo "INFO: Upload package to pypi.python.org"
+ $(PREFIX)python setup.py check --restructuredtext --strict
+ $(PREFIX)twine upload dist/*
diff --git a/README.md b/README.md
index c3d8ccd..8015b47 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,17 @@
# coats
+
+[![Build Status](https://travis-ci.org/ssbarnea/coats.svg?branch=master)](https://travis-ci.org/ssbarnea/coats)
+
Collection of scripts (coats) that improve open-stack developer browsing experience
+
+FoxReplace.json is text replacements configuration for
+ which would add
+some extra coloring on build logs, making them easier to read. We plan to
+convert this into a greasemonkey helper in the future to allow use from
+multiple browsers.
+
+![foxreplace-os-logs](https://s3.sbarnea.com/ss/181001-Mozilla_Firefox_.png)
+
+After you install Firefox extension you can either do an one-time import
+of the configuration from
+or configure it to re-download it when it changes.
diff --git a/coats/FoxReplace.json b/coats/FoxReplace.json
new file mode 100644
index 0000000..ef430e3
--- /dev/null
+++ b/coats/FoxReplace.json
@@ -0,0 +1,101 @@
+{
+ "version": "2.1",
+ "groups": [
+ {
+ "name": "failed2",
+ "urls": [
+ "http://logs.openstack.org",
+ "http://logs.rdoproject.org",
+ "https://ci.centos.org",
+ "https://logs.rdoproject.org",
+ "https://zuul.openstack.org"
+ ],
+ "substitutions": [
+ {
+ "input": "(failed[=:]\\s?[1-9]\\d*.*)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": true
+ },
+ {
+ "input": "(\\*\\*\\* FAILED with status: .*)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": true
+ },
+ {
+ "input": "(.* failed with error code .*)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": true
+ },
+ {
+ "input": "((ERROR|error|fatal|RUN END RESULT_TIMED_OUT)[:\\!] .*)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": false
+ },
+ {
+ "input": "(Failed \\d+ tests - output below:)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": true
+ },
+ {
+ "input": "(\\[(DEPRECATION )?WARNING\\].*)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": true
+ },
+ {
+ "input": "(.*CREATE_FAILED.*)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": true
+ },
+ {
+ "input": "(Exception registering nodes|failed: [^0]|Could not find or access ).*",
+ "inputType": "regexp",
+ "output": "$&",
+ "caseSensitive": true
+ },
+ {
+ "input": "(error:.*)",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": false
+ },
+ {
+ "input": "(.* (marked build as failure|No such file or directory))",
+ "inputType": "regexp",
+ "output": "$1",
+ "caseSensitive": true
+ }
+ ],
+ "html": "output",
+ "enabled": true,
+ "mode": "auto&manual"
+ },
+ {
+ "name": "hyperlinking-logs",
+ "urls": [
+ "http://logs.openstack.org",
+ "http://logs.rdoproject.org",
+ "https://ci.centos.org",
+ "https://logs.rdoproject.org",
+ "https://zuul.openstack.org"
+ ],
+ "substitutions": [
+ {
+ "input": "/home/zuul/workspace/logs/(\\w+)\\.log",
+ "inputType": "regexp",
+ "output": "$&",
+ "caseSensitive": false
+ }
+ ],
+ "html": "output",
+ "enabled": true,
+ "mode": "auto&manual"
+ }
+ ]
+}
diff --git a/cspell.json b/cspell.json
new file mode 100644
index 0000000..181c1fb
--- /dev/null
+++ b/cspell.json
@@ -0,0 +1,60 @@
+{
+ "version": "0.1",
+ "language": "en",
+ "words": [
+ "Sbarnea",
+ "Sorin",
+ "TOXENV",
+ "atexit",
+ "bdist",
+ "conda",
+ "deps",
+ "envars",
+ "envlist",
+ "envs",
+ "htmlcov",
+ "ifeq",
+ "ifndef",
+ "ifneq",
+ "noqa",
+ "passenv",
+ "pycache",
+ "pycodestyle",
+ "pyenv",
+ "pytest",
+ "repo",
+ "repos",
+ "sdist",
+ "setenv",
+ "symlink",
+ "symlinks",
+ "testenv",
+ "tolower",
+ "uname",
+ "xargs",
+ "zuul"
+ ],
+ "flagWords": [],
+ "allowCompoundWords": true,
+ "dictionaries": [
+ "python",
+ "html",
+ "css"
+ ],
+ "ignoreRegExpList": [
+ "/'s\\b/",
+ "/\\br'/",
+ "/\\bu'/",
+ "/\\b-rrequirements/",
+ "[^\\s]{20,}",
+ "/I18NSPHINXOPTS/"
+ ],
+ "ignorePaths": [
+ "docs/build",
+ ".tox",
+ ".eggs"
+ ],
+ "ignoreWords": [
+ "I18NSPHINXOPTS"
+ ]
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6b56500
--- /dev/null
+++ b/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "coats",
+ "version": "1.0.0",
+ "description": "Collection of scripts (coats) that improve open-stack developer browsing experience.",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "spell": "npm -s run spell-files && npm -s run spell-commit",
+ "spell-commit": "git log -1 --pretty=%B > .git/commit.msg && cspell .git/commit.msg",
+ "spell-files": "git ls-files | xargs cspell --unique"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ssbarnea/coats.git"
+ },
+ "keywords": [
+ "openstack",
+ "ux",
+ "web",
+ "greasemonkey",
+ "tampermonkey",
+ "zuul",
+ "logs"
+ ],
+ "author": "Sorin Sbarnea",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/ssbarnea/coats/issues"
+ },
+ "homepage": "https://github.com/ssbarnea/coats#readme",
+ "dependencies": {
+ "cspell": "^2.1.12",
+ "npm": "^6.1.0"
+ }
+}
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..e69de29
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..dbdf7ad
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,58 @@
+[metadata]
+name = coats
+author = Sorin Sbarnea
+author-email = sorin.sbarnea@gmail.com
+maintainer = Sorin Sbarnea
+maintainer-email = sorin.sbarnea@gmail.com
+summary = Collection of scripts (coats) that improve open-stack developer browsing experience
+description-file =
+ README.md
+home-page = https://github.com/ssbarnea/coats
+requires-python = >=2.7
+
+license = BSD
+classifier =
+ Development Status :: 5 - Production/Stable
+ Environment :: Other Environment
+ Intended Audience :: Developers
+ Intended Audience :: Information Technology
+ License :: OSI Approved :: Apache Software License
+ Operating System :: OS Independent
+ Programming Language :: Python
+ Programming Language :: Python :: 2.7
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3.4
+ Programming Language :: Python :: 3.5
+ Programming Language :: Python :: 3.6
+ Programming Language :: Python :: 3.7
+ Topic :: Software Development :: Libraries :: Python Modules
+ Topic :: Internet :: WWW/HTTP
+keywords = openstack, greasemonkey, foxreplace, web
+
+[files]
+packages =
+ coats
+
+[egg_info]
+egg_base = .
+
+[aliases]
+test=pytest
+
+[bdist_wheel]
+universal = 1
+
+[build_sphinx]
+source-dir = docs
+build-dir = docs/build
+all_files = 1
+
+[upload_sphinx]
+upload-dir = docs/build/html
+
+[pbr]
+warnerrors = true
+
+[pycodestyle]
+max-line-length=160
+exclude = .eggs,.tox,build
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..405bf85
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import setuptools
+
+# In python < 2.7.4, a lazy loading of package `pbr` will break
+# setuptools if some other modules registered functions in `atexit`.
+# solution from: http://bugs.python.org/issue15881#msg170215
+try:
+ import multiprocessing # noqa
+except ImportError:
+ pass
+
+
+setuptools.setup(
+ setup_requires=['pbr>=3.0.0', 'setuptools>=17.1'],
+ pbr=True)
diff --git a/test-requirements.txt b/test-requirements.txt
new file mode 100644
index 0000000..457888e
--- /dev/null
+++ b/test-requirements.txt
@@ -0,0 +1,2 @@
+# this file is needed by readthedocs.org so don't move them in another place
+pre-commit
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..0831006
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,36 @@
+[tox]
+minversion = 2.3.1
+envlist = linters
+skip_missing_interpreters = true
+
+[testenv]
+usedevelop = True
+# avoid using deps= due to https://github.com/tox-dev/tox/issues/149
+# hide deps from stdout https://github.com/tox-dev/tox/issues/601
+list_dependencies_command=echo
+
+sitepackages=False
+setenv =
+ PIP_LOG={envdir}/pip.log
+passenv =
+ CI
+ PIP_*
+ TRAVIS
+ TRAVIS_*
+ XDG_CACHE_HOME
+envars =
+ PIP_DISABLE_PIP_VERSION_CHECK=1
+ PIP_USER=no
+whitelist_externals =
+ bash
+ echo
+ find
+ grep
+ rm
+ xargs
+
+[testenv:linters]
+commands=
+ pip install -q -r requirements.txt -r test-requirements.txt
+ bash -c "npm install && npm run spell"
+ python -m pre_commit run --all