Merge pull request #1653 from sebweb3r/daemon

add corrections for daemon and demon
diff --git a/.github/workflows/codespell-private.yml b/.github/workflows/codespell-private.yml
index 9978f04..f79aba6 100644
--- a/.github/workflows/codespell-private.yml
+++ b/.github/workflows/codespell-private.yml
@@ -7,7 +7,13 @@
   make-check-dictionaries:
     runs-on: ubuntu-latest
     steps:
+      - name: Set up Python
+        uses: actions/setup-python@v2
       - uses: actions/checkout@v2
+      - name: Install general dependencies
+        run: pip install -U pip wheel # upgrade to latest pip find 3.5 wheels; wheel to avoid errors
+      - name: Install codespell dependencies
+        run: pip install -e ".[dev]"
       - uses: codespell-project/sort-problem-matcher@v1
       - run: make check-dictionaries
 
diff --git a/.travis.yml b/.travis.yml
index a79a631..94c129b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,23 +29,20 @@
     - source venv/bin/activate
     - python --version  # just to check
     - pip install -U pip wheel # upgrade to latest pip find 3.5 wheels; wheel to avoid errors
-    - retry pip install pytest pytest-cov pytest-dependency flake8 coverage codecov chardet "setuptools!=47.2.0" docutils check-manifest
+    - retry pip install codecov chardet "setuptools!=47.2.0" docutils
     - retry pip install aspell-python-py3
     - cd $SRC_DIR
+    - pip install -e ".[dev]" # install the codespell dev packages
 
 install:
     - python setup.py install
 
 script:
     - codespell --help
-    - make check-dictionary
+    - make check
     - codespell --check-filenames --skip="./.git/*,*.pyc,./codespell_lib/tests/test_basic.py,./codespell_lib/data/*,./example/code.c,./build/lib/codespell_lib/tests/test_basic.py,./build/lib/codespell_lib/data/*"
     # this file has an error
     - "! codespell codespell_lib/tests/test_basic.py"
-    - flake8
-    - python setup.py check --restructuredtext --strict
-    - pytest codespell_lib
-    - make check-manifest
 
 after_success:
     - codecov
diff --git a/Makefile b/Makefile
index 2313231..9e4b773 100644
--- a/Makefile
+++ b/Makefile
@@ -2,15 +2,17 @@
 
 DICTIONARIES := codespell_lib/data/dictionary*.txt
 
-PHONY := all check check-dictionaries sort-dictionaries trim-dictionaries check-dictionary sort-dictionary trim-dictionary clean
+PHONY := all check check-dictionaries sort-dictionaries trim-dictionaries check-dictionary sort-dictionary trim-dictionary check-manifest check-distutils flake8 pytest pypi clean
 
 all: check-dictionaries codespell.1
 
+check: check-dictionaries check-manifest check-distutils flake8 pytest
+
 check-dictionary: check-dictionaries
 sort-dictionary: sort-dictionaries
 trim-dictionary: trim-dictionaries
 
-codespell.1: codespell.1.include bin/codespell
+codespell.1: codespell.1.include bin/codespell Makefile
 	PYTHONPATH=. help2man ./bin/codespell --include codespell.1.include --no-info --output codespell.1
 	sed -i '/\.SS \"Usage/,+2d' codespell.1
 
@@ -27,6 +29,9 @@
 	done
 	@if command -v pytest > /dev/null; then \
 		pytest codespell_lib/tests/test_dictionary.py; \
+	else \
+		echo "Test dependencies not present, install using 'pip install -e \".[dev]\"'"; \
+		exit 1; \
 	fi
 
 sort-dictionaries:
@@ -42,6 +47,15 @@
 check-manifest:
 	check-manifest
 
+check-distutils:
+	python setup.py check --restructuredtext --strict
+
+flake8:
+	flake8
+
+pytest:
+	pytest codespell_lib
+
 pypi:
 	python setup.py sdist register upload
 
diff --git a/README.rst b/README.rst
index 1052789..9058118 100644
--- a/README.rst
+++ b/README.rst
@@ -78,6 +78,28 @@
     echo "word" | codespell -
     echo "1stword,2ndword" | codespell -
 
+Using a config file
+-------------------
+
+Command line options can also be specified in a config file.
+
+When running ``codespell``, it will check in the current directory for a file
+named ``setup.cfg`` or ``.codespellrc`` (or a file specified via ``--config``),
+containing an entry named ``[codespell]``. Each command line argument can
+be specified in this file (without the preceding dashes), for example::
+
+    [codespell]
+    skip = *.po,*.ts,./src/3rdParty,./src/Test
+    count =
+    quiet-level = 3
+
+This is equivalent to running::
+
+    codespell --quiet-level 3 --count --skip "*.po,*.ts,./src/3rdParty,./src/Test"
+
+Any options specified in the command line will *override* options from the
+config file.
+
 Dictionary format
 -----------------
 
@@ -107,6 +129,17 @@
    Note that there isn't a comma in the end of the line. The last argument is
    treated as the reason why a suggestion cannot be automatically applied.
 
+Development Setup
+-----------------
+
+You can install required dependencies for development by running the following within a checkout of the codespell source::
+
+       pip install -e ".[dev]"
+
+To run tests against the codebase run::
+
+       make check
+
 Sending Pull Requests
 ---------------------
 
@@ -181,6 +214,7 @@
 
 .. _GPL v2: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 
-dictionary.txt is a derived work of English Wikipedia and is released under the
-Creative Commons Attribution-Share-Alike License 3.0
+``dictionary.txt`` and the other ``dictionary_*.txt`` files are a derived work of
+English Wikipedia and are released under the Creative Commons
+Attribution-Share-Alike License 3.0
 http://creativecommons.org/licenses/by-sa/3.0/
diff --git a/appveyor.yml b/appveyor.yml
index d234a08..79740ca 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -13,7 +13,8 @@
 
 install:
   - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
-  - "pip install pytest pytest-cov pytest-dependency setuptools flake8 coverage chardet codecov"
+  - "pip install codecov chardet setuptools"
+  - "pip install -e \".[dev]\"" # install the codespell dev packages
   - "python setup.py develop"
 
 build: false  # Not a C# project, build stuff at the test step instead.
diff --git a/codespell_lib/_codespell.py b/codespell_lib/_codespell.py
index 83ebaa4..7ccff56 100755
--- a/codespell_lib/_codespell.py
+++ b/codespell_lib/_codespell.py
@@ -21,6 +21,7 @@
 
 import argparse
 import codecs
+import configparser
 import fnmatch
 import os
 import re
@@ -361,12 +362,39 @@
                         help='print LINES of leading context')
     parser.add_argument('-C', '--context', type=int, metavar='LINES',
                         help='print LINES of surrounding context')
+    parser.add_argument('--config', type=str,
+                        help='path to config file.')
 
     parser.add_argument('files', nargs='*',
                         help='files or directories to check')
 
+    # Parse command line options.
     options = parser.parse_args(list(args))
 
+    # Load config files and look for ``codespell`` options.
+    cfg_files = ['setup.cfg', '.codespellrc']
+    if options.config:
+        cfg_files.append(options.config)
+    config = configparser.ConfigParser()
+    config.read(cfg_files)
+
+    if config.has_section('codespell'):
+        # Build a "fake" argv list using option name and value.
+        cfg_args = []
+        for key in config['codespell']:
+            # Add option as arg.
+            cfg_args.append("--%s" % key)
+            # If value is blank, skip.
+            val = config['codespell'][key]
+            if val != "":
+                cfg_args.append(val)
+
+        # Parse config file options.
+        options = parser.parse_args(cfg_args)
+
+        # Re-parse command line options to override config.
+        options = parser.parse_args(list(args), namespace=options)
+
     if not options.files:
         options.files.append('.')
 
diff --git a/codespell_lib/data/dictionary.txt b/codespell_lib/data/dictionary.txt
index a66de87..1b9cf77 100644
--- a/codespell_lib/data/dictionary.txt
+++ b/codespell_lib/data/dictionary.txt
@@ -1424,7 +1424,7 @@
 alrogithm->algorithm
 alrteady->already
 als->also
-alse->also, else,
+alse->also, else, false,
 alsmost->almost
 alsot->also
 alsready->already
@@ -5044,7 +5044,6 @@
 cloesd->closed
 cloesed->closed
 cloesing->closing
-cloneable->clonable
 clonez->clones, cloner,
 clonning->cloning
 clory->glory
@@ -5704,6 +5703,7 @@
 compatiability->compatibility
 compatiable->compatible
 compatiablity->compatibility
+compatibel->compatible
 compatibile->compatible
 compatibiliy->compatibility
 compatibilty->compatibility
@@ -7884,7 +7884,6 @@
 dedly->deadly
 deductable->deductible
 deductables->deductibles
-dedup->dedupe
 deduplacate->deduplicate
 deduplacated->deduplicated
 deduplacates->deduplicates
@@ -12323,8 +12322,9 @@
 fatser->faster
 fature->feature
 faught->fought
+fauilure->failure
 fauilures->failures
-faund->found
+faund->found, fund,
 favoutrable->favourable
 faymus->famous
 fcound->found
@@ -12515,15 +12515,25 @@
 fisisist->physicist
 fisist->physicist
 fisrt->first
-fiter->filter, fighter,
+fiter->filter, fighter, fitter, fiver,
 fitering->filtering
-fiters->filters, fighters,
+fiters->filters, fighters, fitters, fivers,
 fitler->filter
 fitlers->filters
 fivety->fifty
 fixe->fixed, fixes, fix, fixme, fixer,
 fixeme->fixme
 fizeek->physique
+flacor->flavor
+flacored->flavored
+flacoring->flavoring
+flacorings->flavorings
+flacors->flavors
+flacour->flavour
+flacoured->flavoured
+flacouring->flavouring
+flacourings->flavourings
+flacours->flavours
 flage->flags
 flaged->flagged
 flages->flags
@@ -12533,7 +12543,7 @@
 flaot->float
 flaoting->floating
 flashflame->flashframe
-flass->class, flask,
+flass->class, glass, flask, flash,
 flate->flat
 flatened->flattened
 flattend->flattened
@@ -13127,7 +13137,6 @@
 fysisit->physicist
 gabage->garbage
 gadged->gadget, gauged,
-gae->game, Gael, gale,
 galatic->galactic
 Galations->Galatians
 gallaries->galleries
@@ -16065,7 +16074,6 @@
 keyowrd->keyword
 keypair->key pair
 keypairs->key pairs
-keyserver->key server
 keyservers->key servers
 keystokes->keystrokes
 keyward->keyword
@@ -17018,7 +17026,7 @@
 messure->measure
 messured->measurd
 messurement->measurement
-messures->measure
+messures->measures
 messuring->measuring
 messurment->measurement
 mesure->measure
@@ -17203,7 +17211,7 @@
 mininum->minimum
 miniscule->minuscule
 miniscully->minusculy
-ministery->ministry
+ministery->ministry, minister,
 miniture->miniature
 minium->minimum
 miniums->minimums
@@ -18502,7 +18510,6 @@
 objetc->object
 objetcs->objects
 objets->objects
-objext->object
 objtain->obtain
 objtained->obtained
 objtains->obtains
@@ -18612,7 +18619,6 @@
 ocurred->occurred
 ocurrence->occurrence
 ocurrences->occurrences
-od->of
 oder->order, odor,
 odly->oddly
 oen->one
@@ -23127,6 +23133,9 @@
 restoiring->restoring
 restor->restore
 restorated->restored
+restoreable->restorable
+restoreble->restorable
+restoreing->restoring
 restors->restores
 restouration->restoration
 restraunt->restraint, restaurant,
@@ -25305,9 +25314,12 @@
 stopps->stops
 stopry->story
 storag->storage
+storeable->storable
 storeage->storage
 stoream->stream
-storeis->stories
+storeble->storable
+storeing->storing
+storeis->stories, stores, store is, storeys,
 storise->stories
 stornegst->strongest
 stoyr->story
@@ -26330,7 +26342,7 @@
 tcahce->cache
 tcahces->caches
 tcheckout->checkout
-te->the, be,
+te->the, be, we,
 teached->taught
 teachnig->teaching
 teamplate->template
diff --git a/codespell_lib/data/dictionary_code.txt b/codespell_lib/data/dictionary_code.txt
index fbaa9e2..3eacc39 100644
--- a/codespell_lib/data/dictionary_code.txt
+++ b/codespell_lib/data/dictionary_code.txt
@@ -1,18 +1,24 @@
 amin->main
 cas->case, cast,
 clas->class
+cloneable->clonable
 cmo->com
+copyable->copiable
 define'd->defined
 dof->of, doff,
 dont->don't
 endcode->encode
 errorstring->error string
+gae->game, Gael, gale,
 iam->I am, aim,
 iff->if
 ith->with
+keyserver->key server
 movei->movie
 mut->must, mutt, moot,
 nto->not
+objext->object
+od->of
 referer->referrer
 rela->real
 secant->second
@@ -21,6 +27,8 @@
 sinc->sync, sink, since,
 sincs->syncs, sinks, since,
 stoll->still
+storaged->storage, stored,
+storaget->storage
 thead->thread
 todays->today's
 uint->unit
diff --git a/codespell_lib/data/dictionary_rare.txt b/codespell_lib/data/dictionary_rare.txt
index 973931e..460ec98 100644
--- a/codespell_lib/data/dictionary_rare.txt
+++ b/codespell_lib/data/dictionary_rare.txt
@@ -24,7 +24,6 @@
 consequentially->consequently
 coo->coup
 copping->coping, copying, cropping,
-copyable->copiable
 crasher->crash
 crashers->crashes
 crate->create
diff --git a/codespell_lib/tests/test_basic.py b/codespell_lib/tests/test_basic.py
index 876e24c..2e8fd73 100644
--- a/codespell_lib/tests/test_basic.py
+++ b/codespell_lib/tests/test_basic.py
@@ -488,6 +488,39 @@
     assert cs.main(f.name, r'--ignore-regex=\Wdonn\W') == 1
 
 
+def test_config(tmpdir, capsys):
+    """
+    Tests loading options from a config file.
+    """
+    d = str(tmpdir)
+
+    # Create sample files.
+    with open(op.join(d, 'bad.txt'), 'w') as f:
+        f.write('abandonned donn\n')
+    with open(op.join(d, 'good.txt'), 'w') as f:
+        f.write("good")
+
+    # Create a config file.
+    conffile = op.join(d, 'config.cfg')
+    with open(conffile, 'w') as f:
+        f.write(
+            '[codespell]\n'
+            'skip = bad.txt\n'
+            'count = \n'
+        )
+
+    # Should fail when checking both.
+    code, stdout, _ = cs.main(d, count=True, std=True)
+    # Code in this case is not exit code, but count of misspellings.
+    assert code == 2
+    assert 'bad.txt' in stdout
+
+    # Should pass when skipping bad.txt
+    code, stdout, _ = cs.main('--config', conffile, d, count=True, std=True)
+    assert code == 0
+    assert 'bad.txt' not in stdout
+
+
 @contextlib.contextmanager
 def FakeStdin(text):
     if sys.version[0] == '2':
diff --git a/codespell_lib/tests/test_dictionary.py b/codespell_lib/tests/test_dictionary.py
index 5b67d5d..c3a26bd 100644
--- a/codespell_lib/tests/test_dictionary.py
+++ b/codespell_lib/tests/test_dictionary.py
@@ -146,7 +146,7 @@
         _check_err_rep(err, rep, (None, None), 'dummy')
 
 
-@pytest.mark.skipif(speller is None, reason='requires aspell')
+@pytest.mark.skipif(speller is None, reason='requires aspell-en')
 @pytest.mark.parametrize('err, rep, err_aspell, rep_aspell, match', [
     # This doesn't raise any exceptions, so skip for now:
     # pytest.param('a', 'uvw, bar,', None, None, 'should be in aspell'),
diff --git a/setup.py b/setup.py
index a475ef1..b809636 100755
--- a/setup.py
+++ b/setup.py
@@ -56,5 +56,10 @@
               'console_scripts': [
                   'codespell = codespell_lib:_script_main'
               ],
+          },
+          extras_require={
+              "dev": ["check-manifest", "flake8", "pytest", "pytest-cov",
+                      "pytest-dependency"],
+              "hard-encoding-detection": ["chardet"],
           }
           )