Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
56f7cc8
Refactor and rely on Distribute.
joncotton Apr 12, 2013
8a4fa20
Remove custom string conversion in `setup.py`.
joncotton Apr 12, 2013
f1bf557
WIP - create a common test runner that sets up the Django environment…
joncotton Apr 12, 2013
dbc518b
Iterate the last commit. `dev_django.py` is now the hub for running a…
joncotton Apr 19, 2013
87adf34
Tidying and change of test location.
joncotton Apr 24, 2013
22707fe
WIP remove VirtualDjango in favor of new `run_django_cmd` and move Fa…
joncotton Apr 24, 2013
d5c42d7
Replace `reinstall` command with a more flexible `install`
joncotton Apr 24, 2013
e53d8af
Remove the `pip_install` decorator that automatically uninstalls/inst…
joncotton Apr 24, 2013
1c9f9da
Remove package requirements in favor of an "a la carte" model of inst…
joncotton Apr 24, 2013
f3505b8
Drop Lettuce (for now at least) and the no-longer-necessary `get_full…
joncotton Apr 24, 2013
aaca584
Refactor `coverage` and `test`.
joncotton Apr 24, 2013
e4a5d03
New feature to remove all Armstrong components (except for armstrong.…
joncotton Apr 24, 2013
f0cbf23
Remove VirtualDjango!
joncotton Apr 24, 2013
8df29a8
Fix - literal_eval() needs a string
joncotton May 24, 2013
923605a
Revert "Add `assertInContext` method."
joncotton Jun 26, 2013
5578846
Use the native `assertIsNone()`
joncotton Jun 26, 2013
16ecd66
Use the native `assertIsInstance()`
joncotton Jun 26, 2013
d7bb6ba
Drop this one liner test that can be confused with a native test. Its…
joncotton Jun 26, 2013
c69bdee
Add a note to remove this backport code when we drop Django 1.3 support.
joncotton Jun 26, 2013
2abf130
Remove `fudge` requirement but keep potentially handy fudge reset beh…
joncotton Jun 26, 2013
44d8b4f
Documentation
joncotton Jun 28, 2013
820dc9b
Remove the anemic Sphinx command
joncotton Jan 23, 2014
fa4d1e4
Default settings - use old test runner for Django 1.6. "mydatabase" i…
joncotton Jan 23, 2014
ad0efe6
slight improvement on `fudge` detection
joncotton Jan 23, 2014
d71e62c
Call `super()` on ArmstrongTestCase. A good idea, but not strictly ne…
joncotton Jan 25, 2014
8b900a8
Fix and simplify `generate_random_users()`. Randomization wasn't guar…
joncotton Jan 25, 2014
99d5316
Remove Django magic that makes concrete models. Only used in ArmConte…
joncotton Jan 26, 2014
6a328cb
Bump to 2.0 alpha version.
joncotton Jan 26, 2014
3914643
Merge branch 'release_2.0' into v2.0-prep. Resolves #13
joncotton Jan 26, 2014
2284c64
Merge branch 'tox_testing' into v2.0-prep. The complete overhaul reso…
joncotton Jan 26, 2014
23c923a
Isolate loading of Django settings because we don't always need them.…
joncotton Feb 6, 2014
ef357f1
Capitalize "Armstrong" and change command name to something easier an…
joncotton Feb 7, 2014
e9ad4b1
Make the CLI entry point a little more flexible.
joncotton Feb 9, 2014
04ad98b
WIP switching from Fabric to Invoke. Task arguments are currently bro…
joncotton Feb 7, 2014
ac18e67
Use Decorator to create our own decorators to allow the "real" functi…
joncotton Feb 7, 2014
c4f40f7
Handle Invoke task args. Fabric could handle arbitrary args/kwargs, b…
joncotton Feb 9, 2014
c9936b7
Fix `--extra` handling for kwargs. Now things like `--extra "test1 t…
joncotton Feb 9, 2014
c4d1cf2
help test for Invoke tasks
joncotton Feb 9, 2014
3ee5af2
Merge branch 'invoke' into v2.0-prep
joncotton Feb 10, 2014
64abcf2
Django 1.6 uses the native 1.6 test runner.
joncotton Feb 10, 2014
e8670e5
Override and use the Django 1.6 test runner and backport for older Dj…
joncotton Feb 10, 2014
2d53bb6
Relative package import.
joncotton Feb 11, 2014
a414835
Packages - make Invoke optional.
joncotton Feb 11, 2014
4df0c53
Using pkgutil is fine. Remove improper namespacing.
joncotton Feb 19, 2014
499d010
Put this back. Partial revert of 56f7cc8a768568e9baaa910558150abb6c13…
joncotton Feb 19, 2014
473ab0a
Simplify `namespace_packages` creation and use `pkg_resources`.
joncotton Feb 19, 2014
a43c5ef
It's probably okay to `zip_safe=True` for all of our packages but I'l…
joncotton Feb 19, 2014
bdf32d6
Use `find_packages()` and since we aren't building `package_data` any…
joncotton Feb 19, 2014
4fa0dbf
Remove unnecessary path modification.
joncotton Feb 19, 2014
d4b73c3
Merge branch 'distribute' into v2.0-prep
joncotton Feb 19, 2014
67bf687
Update README and add a CHANGES file.
joncotton Feb 19, 2014
e7ecdab
Setup.py metadata. Include the license in the manifest.
joncotton Mar 4, 2014
eb2e0b1
New feature - add a hook to exclude files during Coverage testing. By…
joncotton Mar 5, 2014
2696e21
Readme changes and removing some line-ending whitespace.
joncotton Mar 7, 2014
ff2bdc7
Logging setting - add a default setting to catch "armstrong" loggers …
joncotton Mar 11, 2014
2d9b2c3
Use a docstring for `default_settings.py` and set `DEBUG=True`, which…
joncotton Mar 11, 2014
e94c594
Adjust logger output and fix whitespace.
joncotton Mar 19, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
*.pyc
*~
*.swp
coverage/*
build/*
*.egg-info
coverage*/
build/
mydatabase
docs/_build/*
docs/_build/
MANIFEST
dist/
66 changes: 66 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
CHANGES
=======

2.0 (unreleased)
------------------

- **Backward incompatible:** ``env_settings.py`` is required and contains
the settings that ``fabfile.py`` used to have. It is written in the normal
Django settings.py style of variable assignments.

- **Backward incompatible:** ``tasks.py`` is required and replaces the
previously required ``fabfile.py``. It no longer defines Django settings
(now handled in ``env_settings.py``).

- **Backward incompatible:** switched from Fabric to Invoke, so the ``fab``
command is replaced with ``invoke``.

- **Backward incompatible:** Lettuce testing support is gone.

- **Backward incompatible:** the Sphinx documentation command ``docs`` is gone.

- **Backward incompatible:** remove ``assertInContext``, ``assertNone``,
``assertIsA`` and ``assertDoesNotHave``. Some of these duplicated native
Python methods and the potential confusion was greater than the benefit.

- **Backward incompatible:** individual components need to specify the
``fudge`` requirement if they need it.

- **Backward incompatible:** Fix ``generate_random_users()`` and turn it
into a generator.

- **Backward incompatible:** remove ``concrete`` decorators. The Armstrong
standard practice is to use "support" models when necessary in testing,
which are much easier to use and understand.

- Setuptools is explictly used. This is not a backwards incompatible change
because anything installed with Pip was automatically and transparently
using Setuptools/Distribute *anyway*. We rely on setup kwargs that Distutils
doesn't support and that only worked because of Pip's behind the scenes swap.
This allowed us to remove boilerplate and better prepares us for Python 3
and perhaps even more simplifying refactors. Functionally though, this
doesn't change anything.

- Drop the atypical VirtualDjango in favor of the ``settings.configure()``
Django bootstrapping method.

- Bare minimum package requirements for as-fast-as-possible virtualenv
creation. Even Invoke is optional when running tests. Individual tasks
can specify package requirements and will nicely message their needs if
the package is not installed.

- Run any Django ``manage.py`` command from import or the CLI with
component-specific settings bootstrapped in.

- Run tests with arguments. Use any args that ``manage.py test`` accepts
to run only specific test cases, change output verbosity, etc.

- Coverage testing is ready for multiple environments at once (like with Tox).

- Use (and backport) the Django 1.6 test runner. This standardizes testing
in favor of the newest method so we don't need to be cognizant of the current
Django version as we test across multiple versions. Bonus: because the new
runner is explicit about test discovery, drop the ``TESTED_APP`` code.

- New ``remove_armstrong`` task command to uninstall every Armstrong component
(except for ArmDev).
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include LICENSE
include README.rst
include CHANGES.rst
include package.json
include armstrong/cli/templates/standard/requirements/*.txt
prune build/*
198 changes: 152 additions & 46 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,184 @@ armstrong.dev
Tools and such for handling development of Armstrong applications

This package contains some of the various helpers needed to do development work
on the Armstrong packages. If you're not actively developing, or working with
on the Armstrong packages. If you're not actively developing, or working with
development versions of Armstrong, you probably don't need this package.


Installation & Configuration
----------------------------
If you are just running tests for a component, Tox will grab everything it
needs including ArmDev.

- ``pip install tox`` and run ``tox``

Otherwise:

- ``pip install armstrong.dev invoke``

`Invoke`_ is not strictly required. ArmDev is as lean as possible to support
fast virtualenv creation so multi-environment testing tools like TravisCI
and Tox will complete ASAP.

Many of the Invoke tasks have their own package requirements and they will
nicely notify you if something they require needs to be installed.

**Optional Settings:** (Used in ``env_settings.py``)

``COVERAGE_EXCLUDE_FILES = ['*/migrations/*']``
A list of filename patterns for files to exclude during coverage testing.
Individual components are free to extend or replace this setting.

.. _Invoke: http://docs.pyinvoke.org/en/latest/index.html


Usage
-----
Most Armstrong components already have the necessary configuration to use these
Dev tools. Specifically, components need ``tasks.py`` and ``env_settings.py``
files. Assuming these are present:

Create a `fabfile` (either `fabfile/__init__.py` or simply `fabfile.py`) in
your project and add the following::
``invoke --list``
to see a list of all available commands

from armstrong.dev.tasks import *
``invoke --help <cmd>``
for help on a specific command

Several of the tasks take an optional ``--extra`` argument that is used as a
catch-all way of passing arbitrary arguments to the underlying command. Invoke
cannot handle arbitrary args (like Fabric 1.x could) so this is our workaround.
Two general rules: 1) enclose multiple args in quotes 2) kwargs need to use
"=" with no spaces (our limitation, not Invoke's). Example:
``invoke test --extra "--verbosity=2 <path.to.app.test1> <path.to.app.test2>"``

settings = {
"DEBUG": True,
# And so on with the keys being the name of the setting and the values
# the appropriate value.
}
``invoke install [--editable]``
to "pip install" the component, by default as an `editable`_ install. For
a regular install, use ``--no-editable`` or ``--editable=False``.

main_app = "name.of.your.app"
tested_apps ("another_app", main_app, )
``invoke test [--extra ...]``
to run tests where --extra handles anything the normal Django
"manage.py test" command accepts.

``invoke coverage [--reportdir=<directory>] [--extra ...]``
for running test coverage. --extra works the same as in "invoke test" passing
arbitrary args to the underlying test command. --reportdir is where the HTML
report will be created; by default this directory is named "coverage".

Now your fabfile will expose the various commands for setting up and running
your reusable app inside a virtualenv for testing, interacting with via the
shell, and even running a simple server.
``invoke managepy <cmd> [--extra ...]``
to run any Django "manage.py" command where --extra handles any arbitrary
args. Example: ``invoke managepy shell`` or
``invoke managepy runserver --extra 9001``

Type ``fab -l`` to see a list of all of the commands.
``invoke create_migration [--initial]``
to create a South migration for the component. An "auto" migration is
default if the --initial flag is not used.

There are other commands as well, but these are the most useful. Remember
that individual components may provide additional Invoke tasks as well. So
run ``invoke --list`` to discover them all.

Installation
------------

::
.. _editable: http://pip.readthedocs.org/en/latest/reference/pip_install.html#editable-installs

name="armstrong.dev"
pip install -e git://github.com/armstrong/$name#egg=$name

**Note**: This currently relies on a development version of Fabric. This
requirement is set to be dropped once Fabric 1.1 is released. To ensure this
runs as expected, install the ``tswicegood/fabric`` fork of Fabric:
Component Setup
---------------
If you are creating a new Armstrong component or updating one that uses the
pre-2.0 ArmDev, you'll need to create (or port to) these two files:

::
1. Create a ``tasks.py`` and add the following::

pip install -e git://github.com/tswicegood/fabric.git#egg=fabric
from armstrong.dev.tasks import *

# any additional Invoke commands
# ...

Contributing
------------
2. Create an ``env_settings.py`` and add the following::

* Create something awesome -- make the code better, add some functionality,
whatever (this is the hardest part).
* `Fork it`_
* Create a topic branch to house your changes
* Get all of your commits in the new topic branch
* Submit a `pull request`_
from armstrong.dev.default_settings import *

# any additional settings
# it's likely you'll need to extend the list of INSTALLED_APPS
# ...

License
-------
Copyright 2011 Bay Citizen and Texas Tribune
Not required but as long as you are reviewing the general state of things,
take care of these too!

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- Review the ``requirements`` files
- Review the TravisCI configuration
- Drop Lettuce tests and requirements
- Add a ``tox.ini`` file
- Review the README text and setup.py metadata
- Use Setuptools and fix any improper namespacing
- Stop shipping tests by moving tests/ to the root directory
- If the component uses logging, consider namespacing it with
``logger = logging.getLogger(__name__)``.
- Add a ``CHANGES.rst`` file and include it in the MANIFEST
- Review ``.gitignore``. You might want to ignore these::

http://www.apache.org/licenses/LICENSE-2.0
.tox/
coverage*/
*.egg-info

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Notable changes in 2.0
----------------------
Setuptools is now explicitly used/required instead of Distutils.

Invoke replaces Fabric for a leaner install without the SSH and crypto
stuff. Invoke is still pre-1.0 release so we might have some adjustment
to do later.

This version offers an easier and more standard way to run a Django
environment with a component's specific settings, either from the
commandline or via import.

It provides an "a la carte" requirements approach. Meaning that if you run an
Invoke command that needs a package that isn't installed, it will prompt you
to install it instead of requiring everything up-front. This allows for much
faster virtualenv creation (which saves considerable time in testing) and
doesn't pollute your virtualenv with packages for features you don't use.

``test`` and ``coverage`` will work better with automated test tools like
TravisCI and Tox. These commands also now work like Django's native test
command so that you can pass arguments for running selective tests or
changing the output verbosity.

Settings are now defined in the normal Django style in an ``env_settings.py``
file instead of as a dict within the tasks file. It's not called "settings.py"
to make it clearer that these are settings for the development and testing
of this component, not necessarily values to copy/paste for incorporating
the component into other projects.

The full list of changes and backward incompatibilties is available
in **CHANGES.rst**.


Contributing
------------
Development occurs on Github. Participation is welcome!

* Found a bug? File it on `Github Issues`_. Include as much detail as you
can and make sure to list the specific component since we use a centralized,
project-wide issue tracker.
* Have code to submit? Fork the repo, consolidate your changes on a topic
branch and create a `pull request`_.
* Questions, need help, discussion? Use our `Google Group`_ mailing list.

.. _Github Issues: https://github.com/armstrong/armstrong/issues
.. _pull request: http://help.github.com/pull-requests/
.. _Fork it: http://help.github.com/forking/
.. _Google Group: http://groups.google.com/group/armstrongcms


State of Project
----------------
`Armstrong`_ is an open-source news platform that is freely available to any
organization. It is the result of a collaboration between the `Texas Tribune`_
and `The Center for Investigative Reporting`_ and a grant from the
`John S. and James L. Knight Foundation`_. Armstrong is available as a
complete bundle and as individual, stand-alone components.

.. _Armstrong: http://www.armstrongcms.org/
.. _Texas Tribune: http://www.texastribune.org/
.. _The Center for Investigative Reporting: http://cironline.org/
.. _John S. and James L. Knight Foundation: http://www.knightfoundation.org/
3 changes: 1 addition & 2 deletions armstrong/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
__import__('pkg_resources').declare_namespace(__name__)
2 changes: 0 additions & 2 deletions armstrong/dev/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
53 changes: 53 additions & 0 deletions armstrong/dev/default_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
Default settings for Armstrong components running in a dev/test environment

A component may (and might have to) override or supply additional settings
by creating an `env_settings.py` file in its root directory that imports
from this file.

from armstrong.dev.default_settings import *

"""
# Since we are using configure() we need to manually load the defaults
from django.conf.global_settings import *

# Grab our package information
import json
package = json.load(open("./package.json"))
app_name = package['name'].rsplit('.', 1)[1]

#
# Armstrong default settings
#
DEBUG = True
INSTALLED_APPS = [package['name']]
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": 'mydatabase'
}
}
TEST_RUNNER = "armstrong.dev.tests.runner.ArmstrongDiscoverRunner"

COVERAGE_EXCLUDE_FILES = ['*/migrations/*']

# Add a DEBUG console "armstrong" logger
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'basic': {'format': '%(levelname)s %(name)s--%(message)s'}
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'basic'
}
},
'loggers': {
'armstrong': {
'level': 'DEBUG',
'handlers': ['console']
}
}
}
Loading