Skip to content

Commit

Permalink
release automation
Browse files Browse the repository at this point in the history
  • Loading branch information
obestwalter committed Jun 7, 2017
1 parent 89da1fe commit 59b7bc1
Show file tree
Hide file tree
Showing 9 changed files with 311 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

### Fixed

- #2 - fails if not using i3status. Fixed by making the refresh call ignore any errors - not nice, just a quick fix.
-[#2](https://github.com/obestwalter/i3configger/issues/2) - fails if not using i3status. Fixed by making the refresh call ignore any errors - not nice, just a quick fix.

# 0.0 - 0.4.3

Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include LICENSE
include README.md
include setup.py
include tox.ini
graft docs
graft i3configger
graft tests

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@

* build main config and one or several i3status configs from the same sources
* variables are handled slightly more intelligently than i3 does it (variables assigned to other variables are resolved)
* end of line comments are possible (removed at build time)
* (**THIS WILL GO - to much bug potential - would need some form of parsing already)end of line comments are possible (removed at build time)

* variables in i3status configs are also resolved (set anywhere in the sources)
* reload or restart i3 when a change has been done (using `i3-msg`)
* notify when new config has been created and activated (using `notify-send`)
Expand Down
63 changes: 63 additions & 0 deletions docs/_pypi/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
CHANGELOG
=========

[Unreleased]
------------

Removed
~~~~~~~

- end of line comments are not allowed anymore (too much bug potential
- would need some form of parsing already to make it work -> not
worth the fuzz)

Changes
~~~~~~~

- Notification is off by default: cli arg changed from ``--no-notify-``
to ``--notify``

Fixed
~~~~~

- checking the config with ``i3 -C`` did not work because ``-c`` (small
c) was not passed and the passed path to the new config was silently
ignored and the active config was checked instead

0.4.4
-----

Fixed
~~~~~

-[#2](https://github.com/obestwalter/i3configger/issues/2) <https://github.com/obestwalter/i3configger/issues/2>`__ - fails if
not using i3status. Fixed by making the refresh call ignore any errors -
not nice, just a quick fix.

0.0 - 0.4.3
===========

**Basic implementation**

- build main config and one or several i3status configs from the same
sources
- variables are handled slightly more intelligently than i3 does it
(variables assigned to other variables are resolved)
- end of line comments are possible (removed at build time)
- variables in i3status configs are also resolved (set anywhere in the
sources)
- reload or restart i3 when a change has been done (using ``i3-msg``)
- notify when new config has been created and activated (using
``notify-send``)
- simple way to render partials based on key value pairs in file name
- simple way to change the configuration by sending messages
- build config as one shot script or watch for changes
- send messages to watching i3configger process
- if ``i3 -C fails`` with the newly rendered config, the old config
will be kept, no harm done

--------------

**Note:** The format is based on `Keep a
Changelog <http://keepachangelog.com/>`__ and this project adheres to
`Semantic Versioning <http://semver.org/>`__.
192 changes: 192 additions & 0 deletions docs/_pypi/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
|Project Status: Active – The project has reached a stable, usable state
and is being actively developed.| |Build Status| |PyPI version|

i3configger
===========

Overview
--------

- generate an `i3 <https://i3wm.org>`__ config from a set of ``.conf``
files in ``<i3 config folder>/config.d``.

- automatically restart or reload i3 when changes were made (optional -
on by default). This makes it possible to dynamically change settings
that need changes in the configuration files (e.g. switch bar mode
between hide and docked or cycle through different color schemes).

- keep it DRY (optional):

- assign variables to variables
- use variables in i3status configuration files
- generate ``bar {...}`` settings from a simple template with some
extra config.

Detailed Features
-----------------

- build main config and one or several i3status configs from the same
sources
- variables are handled slightly more intelligently than i3 does it
(variables assigned to other variables are resolved)
- (\*\*THIS WILL GO - to much bug potential - would need some form of
parsing already)end of line comments are possible (removed at build
time)

- variables in i3status configs are also resolved (set anywhere in the
sources)
- reload or restart i3 when a change has been done (using ``i3-msg``)
- notify when new config has been created and activated (using
``notify-send``)
- simple way to render partials based on key value pairs in file name
- simple way to change the configuration by sending messages
- build config as one shot script or watch for changes
- send messages to watching i3configger process
- (**WARNING** - this does not work reliably yet) if ``i3 -C`` fails
with the newly rendered config, the old config will be kept, no harm
done

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

**Note** the code is Python 3.6 only. I want to play with the new toys
:)

``i3configger`` is released on `the Python Package
Index <https://pypi.org/project/i3configger/>`__. The standard
installation method is:

::

$ pip install i3configger

`i3configger release announcements and
discussion <https://www.reddit.com/r/i3wm/comments/6exzgs/meet_i3configger/>`__

Getting started
---------------

Simple
~~~~~~

1. Cut your config file into chewable chunks with the extension
``.conf`` and put them in the directory
``<i3 config folder>/config.d``.
2. Run ``i3configger``.
3. ``i3configger.json`` and ``.state.json`` are created in ``config.d``
4. A new config file is generated instead of your old config.
5. A backup of the last config is kept with suffix ``.bak``

- ``i3configger.json`` can be used to do configuration of the status
bars.
- ``.state.json`` remembers the state of your current settings

Watch files in the background
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are experimenting with the config and want it automatically
updated on change:

run it in the foreground:

::

$ i3configger --watch

run it as a daemon:

::

$ i3configger --daemon

stop the daemon:

::

$ i3configger --kill

Diving a bit deeper
-------------------

I use this to generate `my own i3
config <https://github.com/obestwalter/i3config>`__. Here are the config
partials and settings:
`.i3/config.d <https://github.com/obestwalter/i3config/tree/master/config.d>`__,
from which
`config <https://github.com/obestwalter/i3config/tree/master/config>`__
and all ``i3status.*conf`` files are built.

With my config, the call:

::

$ i3configger select scheme solarized-dark

will integrate ``scheme.solarized-dark.conf`` in the build and exclude
all other ``scheme.*.conf`` files.

::

$ i3configger select-next scheme

will switch to the next scheme (and wrap around to the first scheme)

This is persisted in ``.state.json``

If I want to get my bar out of the way:

::

$ i3configger set mode hide

**``select``** integrates different partial files. Config partials that
follow the naming scheme ``<key>.<value>.conf`` are only rendered into
the config if explicitly set via configuration or a message from the
command line.

**``set``** assigns values to arbitrary variables that are set anywhere
in the configuration.

All changes done this way are persisted in ``.state.json``.

Build process
-------------

1. merge all files that fit the conditions and configuration
2. read in all lines that fit the pattern ``set $.*``
3. parse them into a map key -> value
4. Resolve all indirect assignments (e.g. ``set $bla $blub``)
5. Replace all variables in configs with their values (bar configs get
local context merged before substitution)
6. Write results
7. Check if config is valid - if not switch back to saved backup

Resources
---------

I3 official
~~~~~~~~~~~

- `i3wm <https://i3wm.org/>`__
- `i3wm reddit group (FAQs) <https://www.reddit.com/r/i3wm/>`__
- `Archlinux Wiki <https://wiki.archlinux.org/index.php/I3>`__

Other Tools
~~~~~~~~~~~

... from the i3wm ecosystem

- `online color
configurator <https://thomashunter.name/i3-configurator/>`__
- `j4-make-config
(i3-theme) <https://github.com/okraits/j4-make-config>`__
- `i3-style <https://github.com/acrisci/i3-style>`__
- `i3ColourChanger <https://github.com/PMunch/i3ColourChanger>`__
- `i3-manager <https://github.com/erayaydin/i3-manager>`__

.. |Project Status: Active – The project has reached a stable, usable state and is being actively developed.| image:: http://www.repostatus.org/badges/latest/active.svg
:target: http://www.repostatus.org/#active
.. |Build Status| image:: https://travis-ci.org/obestwalter/i3configger.svg?branch=master
:target: https://travis-ci.org/obestwalter/i3configger
.. |PyPI version| image:: https://badge.fury.io/py/i3configger.svg
:target: https://badge.fury.io/py/i3configger
33 changes: 33 additions & 0 deletions i3configger/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Utilities that help managing and releasing i3configger"""
import re
from pathlib import Path

import pypandoc

REPO_URL = 'https://github.com/obestwalter/i3configger'
PROJECT_ROOT = Path(__file__).parents[1]
PYPI_PATH = PROJECT_ROOT / 'docs' / '_pypi'
CHANGELOG_PATH = PROJECT_ROOT / 'CHANGELOG.md'
README_PATH = PROJECT_ROOT / 'README.md'


def linkify(changelog):
issue_replacement = r'[#\1](%s/issues/\1)' % REPO_URL
changelog = re.sub(r'[^\[]#(\d+?)', issue_replacement, changelog)
pull_replacement = r'[#p\1](%s/pull/\1)' % REPO_URL
changelog = re.sub(r'[^\[]#p(\d+?)', pull_replacement, changelog)
return changelog


def update_pypi_files():
"""Pypi doesn't like .md - I don't like .rst - let's compromise."""
rstReadme = pypandoc.convert(str(PROJECT_ROOT / 'README.md'), 'rst')
(PYPI_PATH / "README.rst").write_text(rstReadme)
changelogMd = linkify(CHANGELOG_PATH.read_text())
CHANGELOG_PATH.write_text(changelogMd)
changelogRst = pypandoc.convert_text(changelogMd, to='rst', format='md')
(PYPI_PATH / 'CHANGELOG.rst').write_text(linkify(changelogRst))


if __name__ == '__main__':
update_pypi_files()
14 changes: 11 additions & 3 deletions notes.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
## Some inspiration from i3 project
# Changelog

http://keepachangelog.com/en/0.3.0/

# Some inspiration from i3 project

> * Never break configuration files or existing workflows. Breaking changes require a major version bump (v4 → v5).
* Keep mental complexity low: once you know i3’s key features, other features should be easy to understand.
* Only add features which benefit many people, instead of going to great lengths to support rarely used workflows.
* Only documented behavior is supported. Clear documentation is a requirement for contributions.

### Display specific bars on specific displays
# Display specific bars on specific displays

Those bars should only be integrated if the display is present

Use http://python-xlib.sourceforge.net/doc/html/python-xlib_16.html to read display infos?

## Build on startup
# Build on startup

It i3configger is started/run once before i3 is started the config can be build depending on settings and environments. e.g in xinitrc before i3wm is started.

tox -e i3configger

tox -e i3configger -- --daemon

e.g. which displays are connected and how should the workspaces and bars be configured according to that.
14 changes: 5 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import sys
from setuptools import find_packages, setup

try:
import pypandoc
longDescription = pypandoc.convert('README.md', 'rst')
except(OSError, IOError, ImportError):
if 'upload' in sys.argv:
raise
longDescription = open('README.md').read()

def get_long_description():
readme = open('docs/_pypi/README.md').read()
changelog = open('docs/_pypi/CHANGELOG.md').read()
return "%s\n\n%s" % (readme, changelog)

kwargs = dict(
name='i3configger',
author='Oliver Bestwalter',
url='https://github.com/obestwalter/i3configger',
description="i3 config generation tool",
long_description=longDescription,
long_description=get_long_description(),
use_scm_version=True,
setup_requires=['setuptools_scm'],
entry_points={'console_scripts': ['i3configger = i3configger.main:main']},
Expand Down
4 changes: 3 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ commands =
[testenv:release]
description = create, push new tag sdist upload
deps = pypandoc
commands = ./release.sh {posargs}
commands =

./release.sh {posargs}

[testenv:clean]
description = clean up cruft
Expand Down

0 comments on commit 59b7bc1

Please sign in to comment.