Mercurial > louis > mq > lightsd
view add_make_release.patch @ 443:cf7f56964196
wip, reworked the client-side release commands
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Thu, 28 Apr 2016 23:50:40 -0700 |
parents | 6615c130dab6 |
children | 918645c7e15e |
line wrap: on
line source
# HG changeset patch # Parent d16f6ed548379278b946b5ed7caf291ba0ac4e6e Add a release command that can be used from buildbot diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,10 +3,10 @@ PROJECT(LIGHTSD C) -SET(CPACK_PACKAGE_VERSION_MAJOR "1") -SET(CPACK_PACKAGE_VERSION_MINOR "2") -SET(CPACK_PACKAGE_VERSION_PATCH "0") -SET(LIGHTSD_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") +SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${LIGHTSD_SOURCE_DIR}/CMakeScripts") + +STRING(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE) +INCLUDE(LightsdVersion) MESSAGE(STATUS "lightsd version: ${LIGHTSD_VERSION}") MESSAGE(STATUS "CMake version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}") @@ -15,8 +15,6 @@ MESSAGE(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") MESSAGE(STATUS "Source directory: ${LIGHTSD_SOURCE_DIR}") -SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${LIGHTSD_SOURCE_DIR}/CMakeScripts") - ENABLE_TESTING() ### Platform checks ############################################################ @@ -26,6 +24,16 @@ FIND_PACKAGE(Endian REQUIRED) FIND_PACKAGE(Sphinx) +IF (CMAKE_BUILD_TYPE MATCHES RELEASE) + FIND_PACKAGE(Gzip) + FIND_PACKAGE(Hg) + SET(Python_ADDITIONAL_VERSIONS 3) # actually >= 3.3 (os.replace) + FIND_PACKAGE(PythonInterp) + FIND_PACKAGE(BsdTar) + FIND_PACKAGE(Virtualenv) + FIND_PACKAGE(Xz) +ENDIF () + INCLUDE(CheckFunctionExists) INCLUDE(CheckVariableExists) INCLUDE(TestBigEndian) @@ -92,9 +100,7 @@ # 2.8.11 is the first version with TARGET_INCLUDE_DIRECTORIES: IF (CMAKE_VERSION VERSION_GREATER 2.8.10) - CONFIGURE_FILE( - CTestCustom.cmake.in "${LIGHTSD_BINARY_DIR}/CTestCustom.cmake" @ONLY - ) + CONFIGURE_FILE(CTestCustom.cmake.in "${LIGHTSD_BINARY_DIR}/CTestCustom.cmake" @ONLY) ADD_SUBDIRECTORY(tests) ELSE () MESSAGE( @@ -105,7 +111,14 @@ ENDIF () IF (SPHINX_FOUND) + MESSAGE(STATUS "Sphinx found, docs generation enabled") ADD_SUBDIRECTORY(docs) +ELSE () + MESSAGE(STATUS "Shpinx wasn't found, docs generation disabled") +ENDIF () + +IF (CMAKE_BUILD_TYPE MATCHES RELEASE) + ADD_SUBDIRECTORY(dist) ENDIF () INSTALL( diff --git a/CMakeScripts/FindBsdTar.cmake b/CMakeScripts/FindBsdTar.cmake new file mode 100644 --- /dev/null +++ b/CMakeScripts/FindBsdTar.cmake @@ -0,0 +1,6 @@ +FIND_PROGRAM( + BSDTAR_EXECUTABLE NAMES bsdtar + DOC "Path to the bsdtar executable" +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(BsdTar DEFAULT_MSG BSDTAR_EXECUTABLE) diff --git a/CMakeScripts/FindGzip.cmake b/CMakeScripts/FindGzip.cmake new file mode 100644 --- /dev/null +++ b/CMakeScripts/FindGzip.cmake @@ -0,0 +1,6 @@ +FIND_PROGRAM( + GZIP_EXECUTABLE NAMES gzip + DOC "Path to the gzip executable" +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gzip DEFAULT_MSG GZIP_EXECUTABLE) diff --git a/CMakeScripts/FindSphinx.cmake b/CMakeScripts/FindSphinx.cmake --- a/CMakeScripts/FindSphinx.cmake +++ b/CMakeScripts/FindSphinx.cmake @@ -1,7 +1,7 @@ FIND_PROGRAM( SPHINX_EXECUTABLE NAMES sphinx-build sphinx-build2 - DOC "Path to sphinx-build executable" + DOC "Path to the sphinx-build executable" ) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sphinx DEFAULT_MSG SPHINX_EXECUTABLE) diff --git a/CMakeScripts/FindVirtualenv.cmake b/CMakeScripts/FindVirtualenv.cmake new file mode 100644 --- /dev/null +++ b/CMakeScripts/FindVirtualenv.cmake @@ -0,0 +1,7 @@ +FIND_PROGRAM( + VIRTUALENV_EXECUTABLE + NAMES virtualenv virtualenv2 + DOC "Path to the virtualenv executable" +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Virtualenv DEFAULT_MSG VIRTUALENV_EXECUTABLE) diff --git a/CMakeScripts/FindXz.cmake b/CMakeScripts/FindXz.cmake new file mode 100644 --- /dev/null +++ b/CMakeScripts/FindXz.cmake @@ -0,0 +1,6 @@ +FIND_PROGRAM( + XZ_EXECUTABLE NAMES xz + DOC "Path to the xz executable" +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xz DEFAULT_MSG XZ_EXECUTABLE) diff --git a/CMakeScripts/LightsdVersion.cmake b/CMakeScripts/LightsdVersion.cmake new file mode 100644 --- /dev/null +++ b/CMakeScripts/LightsdVersion.cmake @@ -0,0 +1,7 @@ +# NOTE: auto-generated by the release target +SET(CPACK_PACKAGE_VERSION_MAJOR "1") +SET(CPACK_PACKAGE_VERSION_MINOR "2") +SET(CPACK_PACKAGE_VERSION_PATCH "0") +SET(LIGHTSD_PRERELEASE "rc.1") +SET(LIGHTSD_BUILD "") +SET(LIGHTSD_VERSION "1.2.0-rc.1") diff --git a/dist/CMakeLists.txt b/dist/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/dist/CMakeLists.txt @@ -0,0 +1,74 @@ +IF ( + PYTHONINTERP_FOUND + AND PYTHON_VERSION_MAJOR EQUAL 3 + AND PYTHON_VERSION_MINOR GREATER 2 # os.replace + AND VIRTUALENV_FOUND + AND HG_FOUND + AND BSDTAR_FOUND + AND GZIP_FOUND + AND XZ_FOUND +) + MESSAGE( + STATUS + "Python >= 3.3, virtualenv, bsdtar, gzip, xz, and mercurial (hg) " + "found, release commands enabled" + ) + + SET(VENV_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/py-env") + SET(VENV_PYTHON "${VENV_DIRECTORY}/bin/python") + SET(VENV_STAMP "${VENV_DIRECTORY}/stamp") + SET(PIP_REQUIREMENTS "${CMAKE_CURRENT_SOURCE_DIR}/requirements-release.txt") + + CONFIGURE_FILE(release.py.in "${CMAKE_CURRENT_BINARY_DIR}/release.py" @ONLY) + + ADD_CUSTOM_COMMAND( + OUTPUT "${VENV_STAMP}" + COMMAND "${VIRTUALENV_EXECUTABLE}" -q -p "${PYTHON_EXECUTABLE}" "${VENV_DIRECTORY}" + COMMAND "${VENV_DIRECTORY}/bin/pip" -q install -r "${PIP_REQUIREMENTS}" + COMMAND "${CMAKE_COMMAND}" -E touch "${VENV_STAMP}" + DEPENDS "${PIP_REQUIREMENTS}" + COMMENT "Setting up a Python virtualenv at ${VENV_DIRECTORY} for the release script" + VERBATIM + ) + + ADD_CUSTOM_TARGET( + release + COMMAND "${VENV_PYTHON}" "${CMAKE_CURRENT_BINARY_DIR}/release.py" "release" + DEPENDS "${VENV_STAMP}" + VERBATIM + ) + + ADD_CUSTOM_TARGET( + pre_release + COMMAND "${VENV_PYTHON}" "${CMAKE_CURRENT_BINARY_DIR}/release.py" "pre_release" + DEPENDS "${VENV_STAMP}" + VERBATIM + ) + + ADD_CUSTOM_TARGET( + package_release + COMMAND "${VENV_PYTHON}" "${CMAKE_CURRENT_BINARY_DIR}/release.py" "package_release" + DEPENDS "${VENV_STAMP}" + VERBATIM + ) + + ADD_CUSTOM_TARGET( + release_new_tag + COMMAND "${VENV_PYTHON}" "${CMAKE_CURRENT_BINARY_DIR}/release.py" "new_tag" + DEPENDS "${VENV_STAMP}" + VERBATIM + ) + + ADD_CUSTOM_TARGET( + release_docs + COMMAND "${VENV_PYTHON}" "${CMAKE_CURRENT_BINARY_DIR}/release.py" "docs" + DEPENDS "${VENV_STAMP}" docs + VERBATIM + ) +ELSE () + MESSAGE( + STATUS + "Python >= 3.3 and/or virtualenv, bsdtar, gzip, xz, mercurial (hg) " + "weren't found, release commands disabled" + ) +ENDIF () diff --git a/dist/dpkg/.hgtags b/dist/dpkg/.hgtags new file mode 100644 --- /dev/null +++ b/dist/dpkg/.hgtags @@ -0,0 +1,3 @@ +11534a873dbc92fd9c7225cf37d67942f852a67c 1.1.0 +60c3d81a6ff2305eca554c12c42d272d5f2187db 1.1.1 +bf09addc0ea974fc378f1acf48a8255e485f87d1 1.1.2 diff --git a/dist/dpkg/debian/changelog b/dist/dpkg/debian/changelog new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/changelog @@ -0,0 +1,29 @@ +lightsd (1.1.2-1) unstable; urgency=low + + * New upstream release: fix LIFX LAN protocol v2 handling. + + -- Louis Opter <kalessin@kalessin.fr> Mon, 30 Nov 2015 10:38:18 +0000 + +lightsd (1.1.1-1) unstable; urgency=low + + * New upstream release: responsiveness improvements. + + -- Louis Opter <kalessin@kalessin.fr> Tue, 17 Nov 2015 10:19:02 +0000 + +lightsd (1.1.0-2) unstable; urgency=low + + * Fix parallel builds + + -- Louis Opter <kalessin@kalessin.fr> Sat, 14 Nov 2015 06:35:43 +0000 + +lightsd (1.1.0-1) unstable; urgency=low + + * First published release + + -- Louis Opter <kalessin@kalessin.fr> Sun, 08 Nov 2015 08:06:51 +0000 + +lightsd (1.0.1-1) unstable; urgency=low + + * Initial release + + -- Louis Opter <kalessin@kalessin.fr> Tue, 03 Nov 2015 07:43:24 +0000 diff --git a/dist/dpkg/debian/compat b/dist/dpkg/debian/compat new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/compat @@ -0,0 +1,1 @@ +9 diff --git a/dist/dpkg/debian/control b/dist/dpkg/debian/control new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/control @@ -0,0 +1,23 @@ +Source: lightsd +Section: contrib/utils +Priority: optional +Maintainer: Louis Opter <kalessin@kalessin.fr> +Build-Depends: debhelper (>= 9), cmake (>= 2.8.9), libevent-dev (>= 2.0.19) +Suggests: python3, ipython3 +Standards-Version: 3.9.6 +Homepage: https://github.com/lopter/lightsd/ +Vcs-Git: https://github.com/lopter/dpkg-lightsd.git +Vcs-Browser: https://github.com/lopter/dpkg-lightsd/ + +Package: lightsd +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Centralized daemon to control your LIFX bulbs + lightsd discovers LIFX bulbs on the local network and acts as a central + point of control for them via a JSON-RPC interface. + . + The JSON-RPC interface can run over TCP, named pipes as well as Unix + sockets and allows you to retrieve the state of the bulbs or set their + colors. Effects, grouping and de-grouping operations are also supported. + . + Visit http://lightsd.readthedocs.org/ for more informations. diff --git a/dist/dpkg/debian/copyright b/dist/dpkg/debian/copyright new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/copyright @@ -0,0 +1,62 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: lightsd +Source: https://github.com/lopter/lightsd + +Files: * +Copyright: 2014-2015 Louis Opter <kalessin@kalessin.fr> +License: GPL-3.0+ + +Files: debian/* +Copyright: 2015 Louis Opter <kalessin@kalessin.fr> +License: BSD-3-clause + +Files: examples/* +Copyright: 2015 Louis Opter <kalessin@kalessin.fr> +License: BSD-3-clause + +Files: share/lightsc.sh +Copyright: 2015 Louis Opter <kalessin@kalessin.fr> +License: BSD-3-clause + +License: GPL-3.0+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/dpkg/debian/docs b/dist/dpkg/debian/docs new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/docs @@ -0,0 +1,1 @@ +README.rst diff --git a/dist/dpkg/debian/init.d b/dist/dpkg/debian/init.d new file mode 100755 --- /dev/null +++ b/dist/dpkg/debian/init.d @@ -0,0 +1,129 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: lightsd +# Required-Start: $local_fs $network $syslog $remote_fs +# Required-Stop: $local_fs $network $syslog $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start lightsd at boot time +# Description: Centralized daemon to discover and control LIFX bulbs. +### END INIT INFO + +# Author: Louis Opter <kalessin@kalessin.fr> + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="lightsd" +NAME=lightsd +DAEMON=/usr/bin/lightsd +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +DAEMON_ARGS=" + --daemonize + --verbosity warning + --user lightsd + --pidfile $PIDFILE + --socket /var/run/lightsd/socket + --command-pipe /var/run/lightsd/pipe + $DAEMON_OPTS +" + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.2-14) to ensure that this file is present +# and status_of_proc is working. +. /lib/lsb/init-functions + +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS \ + || return 2 +} + +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + restart|force-reload) + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: + +# vim: set ft=sh: diff --git a/dist/dpkg/debian/lightsd.default b/dist/dpkg/debian/lightsd.default new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/lightsd.default @@ -0,0 +1,10 @@ +# Defaults for lightsd initscript +# sourced by /etc/init.d/lightsd +# installed at /etc/default/lightsd by the maintainer scripts + +# +# This is a POSIX shell fragment +# + +# Additional options that are passed to the Daemon. +DAEMON_OPTS="" diff --git a/dist/dpkg/debian/postinst b/dist/dpkg/debian/postinst new file mode 100755 --- /dev/null +++ b/dist/dpkg/debian/postinst @@ -0,0 +1,55 @@ +#!/bin/sh +# postinst script for lightsd +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <postinst> `configure' <most-recently-configured-version> +# * <old-postinst> `abort-upgrade' <new version> +# * <conflictor's-postinst> `abort-remove' `in-favour' <package> +# <new-version> +# * <postinst> `abort-remove' +# * <deconfigured's-postinst> `abort-deconfigure' `in-favour' +# <failed-install-package> <version> `removing' +# <conflicting-package> <version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + getent group lightsd >/dev/null || groupadd -r lightsd + getent passwd lightsd >/dev/null || useradd -r -d / -g lightsd lightsd + + cat << 'EOF' + +lightsd runs under the `lightsd' user and group by default; add yourself to +this group to be able to open lightsd's socket and pipe under /var/run/lightsd: + + gpasswd -a $USER lightsd + +Re-open your current desktop or ssh session for the change to take effect. +Then use systemctl to start lightsd; you can start playing with lightsd with: + + `lightsd --prefix`/share/doc/lightsd/examples/lightsc.py + +EOF + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/dist/dpkg/debian/postrm b/dist/dpkg/debian/postrm new file mode 100755 --- /dev/null +++ b/dist/dpkg/debian/postrm @@ -0,0 +1,41 @@ +#!/bin/sh +# postrm script for lightsd +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <postrm> `remove' +# * <postrm> `purge' +# * <old-postrm> `upgrade' <new-version> +# * <new-postrm> `failed-upgrade' <old-version> +# * <new-postrm> `abort-install' +# * <new-postrm> `abort-install' <old-version> +# * <new-postrm> `abort-upgrade' <old-version> +# * <disappearer's-postrm> `disappear' <overwriter> +# <overwriter-version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + purge|remove|abort-install) + getent passwd lightsd >/dev/null && userdel lightsd + ;; + + upgrade|failed-upgrade|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/dist/dpkg/debian/rules b/dist/dpkg/debian/rules new file mode 100755 --- /dev/null +++ b/dist/dpkg/debian/rules @@ -0,0 +1,48 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +DH_VERBOSE = 1 + +# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/default.mk + +# see FEATURE AREAS in dpkg-buildflags(1) +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + +ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) + NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) + MAKEFLAGS += -j$(NUMJOBS) +endif + +ifeq (,$(wildcard /run)) + RUNTIME_DIRECTORY=/run +else + RUNTIME_DIRECTORY=/var/run +endif + +# main packaging script based on dh7 syntax +%: + dh $@ + +# debmake generated override targets +# This is example for Cmake (See http://bugs.debian.org/641051 ) +override_dh_auto_configure: + dh_auto_configure -- \ + -DCMAKE_BUILD_TYPE=RELEASE \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \ + -DLGTD_RUNTIME_DIRECTORY=$(RUNTIME_DIRECTORY)/lightsd + +override_dh_auto_build: + dh_auto_build --parallel + +override_dh_auto_install: + dh_auto_install + rm -f debian/lightsd/usr/share/doc/lightsd/COPYING diff --git a/dist/dpkg/debian/source/format b/dist/dpkg/debian/source/format new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/source/format @@ -0,0 +1,1 @@ +3.0 (quilt) diff --git a/dist/dpkg/debian/watch b/dist/dpkg/debian/watch new file mode 100644 --- /dev/null +++ b/dist/dpkg/debian/watch @@ -0,0 +1,7 @@ +# See uscan(1) for format + +# Compulsory line, this is a version 3 file +version=3 + +opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/lightsd-$1\.tar\.gz/ \ + https://github.com/lopter/lightsd/tags .*/?(\d+\.\d+.\d+)\.tar\.gz diff --git a/dist/homebrew/LICENSE b/dist/homebrew/LICENSE new file mode 100644 --- /dev/null +++ b/dist/homebrew/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015, Louis Opter <kalessin@kalessin.fr> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of homebrew-lightsd nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/dist/homebrew/README.rst b/dist/homebrew/README.rst new file mode 100644 --- /dev/null +++ b/dist/homebrew/README.rst @@ -0,0 +1,31 @@ +Homebrew lightsd +================ + +This `brew`_ tap let you install `lightsd`_, a daemon written C to control your +LIFX wifi smart bulbs, on Mac OS X. + +.. _brew: http://brew.sh +.. _lightsd: https://github.com/lopter/lightsd/ + +Instructions +------------ + +Make sure you have brew installed: http://brew.sh. + +:: + + brew install lopter/lightsd/lightsd + +Or: + +:: + + brew tap lopter/lightsd + brew install lightsd + +Documentation +------------- + +Please checkout lightsd's repository: https://github.com/lopter/lightsd/. + +.. vim: set tw=80 spelllang=en spell: diff --git a/dist/homebrew/lightsd.rb b/dist/homebrew/lightsd.rb new file mode 100644 --- /dev/null +++ b/dist/homebrew/lightsd.rb @@ -0,0 +1,99 @@ +require "formula" + +class Lightsd < Formula + desc "Daemon to control your LIFX wifi smart bulbs" + homepage "https://github.com/lopter/lightsd/" + url "{{ archive_url }}" + sha256 "{{ archive_sha256 }}" + revision 1 + + depends_on "cmake" => :build + depends_on "libevent" => :build + depends_on "python3" => :optional + + def install + # XXX, wtf? https://github.com/Homebrew/homebrew/issues/46061 + ENV["PATH"] = "/usr/bin:#{ENV["PATH"]}" + + args = std_cmake_args + args << "-DLGTD_RUNTIME_DIRECTORY=#{var}/run/lightsd" + + # idk what std_cmake_args is supposed to do but it appears to be missing + # proper release flags: + cflags = %W[ + -fstack-protector-strong + --param=ssp-buffer-size=4 + -O3 + -DNDEBUG + ] + args << "-DCMAKE_BUILD_TYPE=RELEASE" + args << "-DCMAKE_C_FLAGS_RELEASE='#{cflags * " "}'" + + system "cmake", *args + system "make", "install" + end + + def plist; <<-EOS.undent + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> + <plist version="1.0"> + <dict> + <key>KeepAlive</key> + <dict> + <key>SuccessfulExit</key> + <false/> + </dict> + <key>Label</key> + <string>#{plist_name}</string> + <key>ProgramArguments</key> + <array> + <string>#{opt_bin}/lightsd</string> + <string>-v</string> + <string>warning</string> + <string>-s</string> + <string>#{var}/run/lightsd/socket</string> + <string>-c</string> + <string>#{var}/run/lightsd/pipe</string> + </array> + <key>RunAtLoad</key> + <true/> + <key>WorkingDirectory</key> + <string>#{var}</string> + <key>StandardErrorPath</key> + <string>#{var}/log/lightsd.log</string> + <key>StandardOutPath</key> + <string>#{var}/log/lightsd.log</string> + </dict> + </plist> + EOS + end + + def caveats; <<-EOS.undent + Once you've started lightsd with launchctl load (see below), you can start + poking around with lightsc.py: + + `lightsd --prefix`/share/lightsd/examples/lightsc.py + EOS + end + + head do + url "https://github.com/lopter/lightsd.git" + end + + devel do + url "file:///Users/louis/projs/lightsd", :using => :hg + version "{{ dev_version }}" + end + + test do + Dir.mktmpdir("lightsd-test") do |dir| + args = %W[ + -l ::1:0 + -l 127.0.0.1:0 + -c #{dir}/lightsd.cmd + -h + ] + system "#{bin}/lightsd", *args + end + end +end diff --git a/dist/openwrt/utils/lightsd/Makefile b/dist/openwrt/utils/lightsd/Makefile new file mode 100644 --- /dev/null +++ b/dist/openwrt/utils/lightsd/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2015 Louis Opter <kalessin@kalessin.fr> +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=lightsd +PKG_VERSION:={{ version }} +PKG_RELEASE:=1 +PKG_MAINTAINER:=Louis Opter <kalessin@kalessin.fr> +PKG_LICENSE:=GPL-3.0+ +PKG_SOURCE_URL:=https://downloads.lightsd.io/releases/ +#PKG_SOURCE_URL:=http://localhost:8000/ +PKG_SOURCE:={{ archive_name }} +PKG_MD5SUM:={{ archive_md5 }} +PKG_BUILD_DIR:=$(BUILD_DIR)/lightsd-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +CMAKE_OPTIONS += \ + -DCMAKE_BUILD_TYPE=RELEASE \ + -DLGTD_RUNTIME_DIRECTORY=/var/run/lightsd + +define Package/lightsd + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=+libevent2-core + TITLE:=Daemon to control your LIFX Wi-Fi smart bulbs + MAINTAINER:=Louis Opter <kalessin@kalessin.fr> + URL:=https://github.com/lopter/lightsd + USERID:=lightsd:lightsd +endef + +define Package/lightsd/install + $(INSTALL_DIR) \ + $(1)/etc/init.d/ \ + $(1)/usr/bin \ + $(1)/usr/share/lightsd \ + $(1)/usr/share/doc/lightsd + + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/bin/lightsd \ + $(1)/usr/bin/lightsd + + $(INSTALL_BIN) \ + ./files/lightsd.init \ + $(1)/etc/init.d/lightsd + + $(CP) \ + $(PKG_INSTALL_DIR)/usr/share/lightsd \ + $(1)/usr/share/lightsd + + $(CP) \ + $(PKG_INSTALL_DIR)/usr/share/doc/lightsd \ + $(1)/usr/share/doc/lightsd +endef + +$(eval $(call BuildPackage,lightsd)) diff --git a/dist/openwrt/utils/lightsd/files/lightsd.init b/dist/openwrt/utils/lightsd/files/lightsd.init new file mode 100644 --- /dev/null +++ b/dist/openwrt/utils/lightsd/files/lightsd.init @@ -0,0 +1,19 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2015 Louis Opter <kalessin@kalessin.fr> +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. + +START=60 + +USE_PROCD=1 + +lightsd=/usr/bin/lightsd +rundir=`$lightsd --rundir` + +start_service() { + procd_open_instance + procd_set_param command $lightsd -S -v warning -t -u lightsd -s "$rundir/socket" -c "$rundir/pipe" + procd_set_param respawn + procd_close_instance +} diff --git a/dist/pkgbuild/.SRCINFO b/dist/pkgbuild/.SRCINFO new file mode 100644 --- /dev/null +++ b/dist/pkgbuild/.SRCINFO @@ -0,0 +1,19 @@ +pkgbase = lightsd + pkgdesc = Daemon to control your LIFX smart bulbs via a JSON-RPC API + pkgver = {{ version }} + pkgrel = 1 + epoch = 1 + url = https://www.github.com/lopter/lightsd/ + install = lightsd.install + arch = i686 + arch = x86_64 + license = GPL3 + makedepends = cmake>=2.8.11 + depends = libevent>=2.0.19 + optdepends = python: to run the interactive lightsc.py example client + optdepends = ipython: makes lightsc.py more user-friendly + source = {{ archive_url }} + sha256sums = {{ archive_sha256 }} + +pkgname = lightsd + diff --git a/dist/pkgbuild/PKGBUILD b/dist/pkgbuild/PKGBUILD new file mode 100644 --- /dev/null +++ b/dist/pkgbuild/PKGBUILD @@ -0,0 +1,44 @@ +# Maintainer: Louis Opter <kalessin@kalessin.fr> + +pkgname=lightsd +pkgver={{ version }} +pkgrel=1 +epoch=1 +pkgdesc="Daemon to control your LIFX smart bulbs via a JSON-RPC API" +arch=("i686" "x86_64") +url="https://www.github.com/lopter/lightsd/" +license=("GPL3") +depends=("libevent>=2.0.19") +optdepends=( + "python: to run the interactive lightsc.py example client" + "ipython: makes lightsc.py more user-friendly" +) +makedepends=("cmake>=2.8.11") +source=("{{ archive_url }}") +sha256sums=("{{ archive_sha256 }}") +#source=("src/${pkgname}-${pkgver}::hg+file:///home/kal/projs/lightsd") +#sha256sums="SKIP" +install=lightsd.install + +build() { + cd "$srcdir/$pkgname-$pkgver" + + cmake . \ + -DCMAKE_BUILD_TYPE=RELEASE \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLGTD_RUNTIME_DIRECTORY=/run/lightsd + + make +} + +check() { + cd "$srcdir/$pkgname-$pkgver" + + make test +} + +package() { + cd "$srcdir/$pkgname-$pkgver" + + make DESTDIR="$pkgdir/" install +} diff --git a/dist/pkgbuild/lightsd.install b/dist/pkgbuild/lightsd.install new file mode 100644 --- /dev/null +++ b/dist/pkgbuild/lightsd.install @@ -0,0 +1,22 @@ +post_install() { + getent group lightsd >/dev/null || groupadd -r lightsd + getent passwd lightsd >/dev/null || useradd -r -d / -g lightsd lightsd + + cat << 'EOF' + +lightsd runs under the `lightsd' user and group by default; add yourself to +this group to be able to open lightsd's socket and pipe under /run/lightsd: + + gpasswd -a $USER lightsd + +Re-open your current desktop or ssh session for the change to take effect. +Then use systemctl to start lightsd; you can start playing with lightsd with: + + `lightsd --prefix`/share/doc/lightsd/examples/lightsc.py + +EOF +} + +post_remove() { + getent passwd lightsd >/dev/null && userdel lightsd +} diff --git a/dist/release.py.in b/dist/release.py.in new file mode 100644 --- /dev/null +++ b/dist/release.py.in @@ -0,0 +1,438 @@ +#!/usr/bin/env python3 + +import click +import datetime +import functools +import hashlib +import os +import itertools +import jinja2 +import locale +import pytz +import requests +import semver +import subprocess +import sys + +LIGHTSD_VERSION = "@LIGHTSD_VERSION@" +# where the lightsd sources are: +LIGHTSD_SOURCE_DIR = "@LIGHTSD_SOURCE_DIR@" +# where the build is: +LIGHTSD_BINARY_DIR = "@LIGHTSD_BINARY_DIR@" +# where all the downstream repositories are, they will be pushed by by buildbot +# (which manage the credentials to those repositories) +LIGHTSD_PKGS_DIR = "@LIGHTSD_RELEASE_PACKAGES_DIR@" +# where to put the generated archives served at +# https://downloads.lightsd.io/releases/: +LIGHTSD_ARCHIVES_DIR = "@LIGHTSD_RELEASE_ARCHIVES_DIR@" +# where to manage the documentation served at https://docs.lighsd.io/: +LIGHTSD_DOCS_DIR = "@LIGHTSD_RELEASE_DOCS_DIR@" + +# paths to utilities: +HG_EXECUTABLE = "@HG_EXECUTABLE@" +BSDTAR_EXECUTABLE = "@BSDTAR_EXECUTABLE@" +GZIP_EXECUTABLE = "@GZIP_EXECUTABLE@" +XZ_EXECUTABLE = "@XZ_EXECUTABLE@" + +COMMIT_AUTHOR = "Buildbot <builbot@kalessin.fr>" + +FILE_READ_SIZE = 32768 + +TARBALL_COMPRESSORS = [ + # suffix, path, extra_flags + ("gz", GZIP_EXECUTABLE, ["--best"]), + ("xz", XZ_EXECUTABLE, []), +] + +prereq_echo = functools.partial(click.secho, fg="magenta", bold=True) +action_echo = functools.partial(click.secho, fg="blue", bold=True) +result_echo = functools.partial(click.secho, fg="green", bold=True) +error_echo = functools.partial(click.secho, bold=True) + + +def repopath(repo): + return os.path.join(LIGHTSD_PKGS_DIR, repo) + + +def next_dev_version(version): + parts, version = version, semver.format_version(**version) + if parts["prerelease"] is not None: + return semver.bump_prerelease(version) + return semver.parse(semver.bump_prerelease(semver.bump_patch(version))) + + +def next_pre_release(version): + version = semver.format_version(**version) + return semver.parse(semver.bump_prerelease(version)) + + +def next_build_release(version): + version = semver.format_version(**version) + return semver.parse(semver.bump_build(version)) + + +def readfile(fp, read_size=FILE_READ_SIZE): + chunk = fp.read(read_size) + while chunk: + yield chunk + chunk = fp.read(read_size) + + +class PackageContext: + + __slots__ = ( + "version", + "dev_version", + "archive_name", + "archive_md5", + "archive_sha256", + "archive_url", + ) + + def __init__(self, **kwargs): + for name, value in kwargs.items(): + if name not in self.__slots__: + raise TypeError("{}: invalid argument {}".format( + self.__class__.__name__, name + )) + setattr(self, name, value) + + def as_dict(self): + return {name: getattr(self, name) for name in self.__slots__} + + +class DownstreamPackage: + + TYPE = None + TEMPLATES = None + + def __init__(self, repo): + self._repo = repo + self._render_ctx = jinja2.Environment(loader=jinja2.FileSystemLoader( + os.path.join(LIGHTSD_SOURCE_DIR, "dist", self.TYPE) + )) + + def render(self, pkg_ctx): + if self.TEMPLATES is None: + return + + for filename in self.TEMPLATES: + template = self._render_ctx.get_template(filename) + with open(os.path.join(self._repo, filename), "wb") as fp: + template.stream(pkg_ctx.as_dict()).dump(fp, "utf-8") + + # TODO: copy the other files too. + + def _pre_commit(self, msg): + pass + + def commit(self, msg): + self._pre_commit(msg) + + dirty = bool(len(subprocess.check_output([ + HG_EXECUTABLE, "-R", self._repo, "status" + ]))) + if dirty: + subprocess.check_call([ + HG_EXECUTABLE, "-R", self._repo, "commit", "-m", msg + ]) + return dirty + + +class DebianPackage(DownstreamPackage): + + TYPE = "dpkg" + + _CHANGELOG_ENTRY_FORMAT = ( +"""lightsd ({version}-1) unstable; urgency=low + + * {msg} + + -- {author} {date} + +""" # noqa + ) + + def render(self, pkg_ctx): + self._version = pkg_ctx.version + + def _pre_commit(self, msg): + changelog_path = os.path.join(self._repo, "debian", "changelog") + staging_changelog_path = "-".join([changelog_path, "next"]) + user_date_locale = locale.getlocale(locale.LC_TIME) + utcnow = datetime.datetime.now(pytz.utc) + + # prepare new changelog: + with open(staging_changelog_path, "wb") as ofp: + try: + locale.setlocale(locale.LC_TIME, "C") + new_entry = self._CHANGELOG_ENTRY_FORMAT.format( + version=self._version, + msg=msg, + author=COMMIT_AUTHOR, + date=utcnow.strftime("%a, %d %b %Y %H:%M:%S %z") + ).encode("utf-8") + ofp.write(new_entry) + with open(changelog_path, "rb") as ifp: + prev_entry = next(ifp) # get the first line + if new_entry.startswith(prev_entry): + os.unlink(staging_changelog_path) + return # we already released that version. + ofp.write(prev_entry) + for chunk in readfile(ifp): + ofp.write(chunk) + except Exception: + os.unlink(staging_changelog_path) + raise + finally: + user_date_locale = locale.setlocale( + locale.LC_TIME, user_date_locale + ) + + # and replace the old one: + os.replace(staging_changelog_path, changelog_path) + + +class HomebrewPackage(DownstreamPackage): + + TYPE = "homebrew" + TEMPLATES = ("lightsd.rb",) + + +class OpenWRTPackage(DownstreamPackage): + + TYPE = "openwrt" + TEMPLATES = ("utils/lightsd/Makefile",) + + +class PKGBUILDPackage(DownstreamPackage): + + TYPE = "pkgbuild" + TEMPLATES = ("PKGBUILD", ".SRCINFO") + + +PACKAGES = ( + DebianPackage(repopath("dpkg-lightsd")), + HomebrewPackage(repopath("homebrew-lightsd")), + OpenWRTPackage(repopath("openwrt-lightsd")), + PKGBUILDPackage(repopath("pkgbuild-lightsd")), +) + +LIGHTSD_VERSION_CMAKE_TEMPLATE = ( +"""# NOTE: auto-generated by the release target +SET(CPACK_PACKAGE_VERSION_MAJOR "{major}") +SET(CPACK_PACKAGE_VERSION_MINOR "{minor}") +SET(CPACK_PACKAGE_VERSION_PATCH "{patch}") +SET(LIGHTSD_PRERELEASE "{prerelease}") +SET(LIGHTSD_BUILD "{build}") +SET(LIGHTSD_VERSION "{version}") +""" # noqa +) + + +def _update_lightsd_version_cmake_include(version): + version_parts = { + k: v if v is not None else "" + for k, v in semver.parse(version).items() + } + lightsd_version_file = os.path.join( + LIGHTSD_SOURCE_DIR, "CMakeScripts", "LightsdVersion.cmake" + ) + with open(lightsd_version_file, "wb") as fp: + fp.write(LIGHTSD_VERSION_CMAKE_TEMPLATE.format( + version=version, **version_parts + ).encode("utf-8")) + + +def _release(version, next_version): + revision, branch = [ + part.strip() for part in subprocess.check_output([ + HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, "id", "--id", "--branch" + ]).split() + ] + qapplied = bool(len(subprocess.check_output([ + HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, + "--config", "extensions.mq=", "qapplied" + ]))) + if qapplied or revision.endswith("+") or branch != "default": + error_echo( + "Can't do a release over a dirty repository! " + "(rev={}, branch={}, patched={})".format( + revision.decode("utf-8"), branch.decode("utf-8"), qapplied + ) + ) + sys.exit(1) + + # Re-gen LightsdVersion.cmake with major.minor.patch, tag, and re-gen + # LightsdVersion.cmake after bumping minor adding a prerelease tag: + version = click.prompt( + "Confirm the version to release", + default=version, + type=lambda arg: semver.format_version(**semver.parse(arg)) + ) + _update_lightsd_version_cmake_include(version) + subprocess.check_call([ + HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, + "tag", "-m", "Tagging release {}".format(version), version + # TODO: use docutils to extract the changelog section + ]) + _update_lightsd_version_cmake_include(next_version) + subprocess.check_call([ + HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, + "commit", "-m", "Back to development, {}".format(next_version) + ]) + + subprocess.check_call([HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, "out"]) + if click.confirm("Are you ready to push those commit?"): + return + subprocess.check_call([HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, "push"]) + + +@click.group() +def cli(): + pass + + +@cli.command() +def pre_release(): + version = semver.parse(LIGHTSD_VERSION) + if version["prerelease"] is None: + version = next_pre_release(version) + _release( + semver.format_version(**version), + semver.format_version(**next_pre_release(version)), + ) + + +@cli.command() +def release(): + version = semver.parse(LIGHTSD_VERSION) + version["prerelease"] = version["build"] = None + _release( + semver.format_version(**version), + semver.format_version(**next_dev_version(version)), + ) + + +@cli.command() +def package_release(release): + version = semver.parse(LIGHTSD_VERSION) + # TODO: version = previous_release (including build metadata) + # (maybe downloads.lightsd.io can help) + version = next_build_release(version) + _release( + semver.format_version(**version), + semver.format_version(**next_build_release(version)), + ) + + +@cli.command() +def new_tag(): + if not LIGHTSD_PKGS_DIR or not LIGHTSD_ARCHIVES_DIR: + error_echo( + "Please configure the project with LIGHTSD_RELEASE_PACKAGES_DIR " + "and LIGHTSD_RELEASE_ARCHIVES_DIR to use this command." + ) + sys.exit(1) + + archive_name = "lightsd-{}.tar".format(LIGHTSD_VERSION) + archive = os.path.join(LIGHTSD_BINARY_DIR, "dist", archive_name) + gz_archive_name = ".".join([archive_name, "gz"]) + gz_archive = os.path.join(LIGHTSD_ARCHIVES_DIR, gz_archive_name) + gz_archive_url = "https://downloads.lightsd.io/releases/{}".format( + gz_archive_name + ) + + action_echo("Checking for an existing release") + response = requests.head(gz_archive_url, allow_redirects=True) + if response.status_code == requests.codes.ok: + error_echo("Release already found at {}!".format(gz_archive_url)) + + prereq_echo("Cleaning-up the source tree") + subprocess.check_call([ + HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, + "--config", "extensions.purge=", "purge", "--abort-on-err", "--all" + ]) + + # NOTE: I wanted to use hg export but then dpkg gave me troubles because + # the archive had extra files or something: + action_echo("Tarballing the sources into {}".format(archive)) + if not os.path.exists(archive): + subprocess.check_call([ + BSDTAR_EXECUTABLE, + "-C", LIGHTSD_SOURCE_DIR, + "-cf", archive, + "-s", "/^\\./{}/".format(os.path.basename(archive)), + "--exclude", ".hg", + "." + ]) + os.makedirs(LIGHTSD_ARCHIVES_DIR, exist_ok=True) + for suffix, bin, extra_flags in TARBALL_COMPRESSORS: + dest = ".".join([ + os.path.join(LIGHTSD_ARCHIVES_DIR, archive_name), suffix + ]) + if os.path.exists(dest): + click.echo("[=] compressing with {}".format(suffix)) + continue + cmd = itertools.chain.from_iterable([ + [bin, "--stdout"], extra_flags, [archive] + ]) + click.echo("[+] compressing with {}".format(suffix)) + with open(dest, "wb") as fp: + subprocess.check_call(cmd, stdout=fp) + + action_echo("Computing MD5 and SHA256 checksums for {}".format(gz_archive)) + gz_archive_md5 = hashlib.md5() + gz_archive_sha256 = hashlib.sha256() + with open(gz_archive, "rb") as fp: + for chunk in readfile(fp): + gz_archive_md5.update(chunk) + gz_archive_sha256.update(chunk) + gz_archive_md5 = gz_archive_md5.hexdigest() + gz_archive_sha256 = gz_archive_sha256.hexdigest() + click.echo("[+] MD5 {}".format(gz_archive_md5)) + click.echo("[+] SHA256 {}".format(gz_archive_sha256)) + + pkg_ctx = PackageContext( + version=LIGHTSD_VERSION, + dev_version=next_dev_version(semver.parse(LIGHTSD_VERSION)), + archive_name=gz_archive_name, + archive_md5=gz_archive_md5, + archive_sha256=gz_archive_sha256, + archive_url=gz_archive_url, + ) + action_echo("Updating packages") + for pkg in PACKAGES: + dirty = pkg.render(pkg_ctx) + if not dirty: + click.echo("[=] {} package".format(pkg.TYPE)) + continue + click.echo("[+] {} package".format(pkg.TYPE)) + pkg.commit("New upstream release {}".format(LIGHTSD_VERSION)) + + result_echo("New upstream release {}".format(LIGHTSD_VERSION)) + + +@cli.command() +def docs(): + version = semver.parse(LIGHTSD_VERSION) + dest_dir = os.path.join(LIGHTSD_DOCS_DIR, LIGHTSD_VERSION) + docs_dir = os.path.join(LIGHTSD_BINARY_DIR, "docs", "_build") + os.makedirs(dest_dir, exist_ok=True) + if version["prerelease"] is None and version["build"] is None: + alias = "current" + else: + alias = "latest" + action_echo("Copying files into {}".format(dest_dir)) + subprocess.check_call([ + "cp", "-a", docs_dir + os.path.sep, dest_dir + os.path.sep + ]) + action_echo("Updating alias {}".format(alias)) + subprocess.check_call([ + "ln", "-snf", dest_dir, os.path.join(LIGHTSD_DOCS_DIR, alias) + ]) + result_echo("{} ({}) updated".format(dest_dir, alias)) + + +if __name__ == "__main__": + cli() diff --git a/dist/requirements-release.txt b/dist/requirements-release.txt new file mode 100644 --- /dev/null +++ b/dist/requirements-release.txt @@ -0,0 +1,6 @@ +click>=6.6,<7.0 +jinja2>=2.8,<3.0 +requests>=2.9.1,<3.0 +semver>=2.4.1,<3.0.0 + +pytz