dk-tasklib 0.2.0__zip → 0.2.3__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {dk-tasklib-0.2.0 → srv/venv/dev/Lib/site-packages/dk_tasklib-0.2.3-py2.7.egg-info}/PKG-INFO +4 -4
  2. {dk-tasklib-0.2.0/dk_tasklib.egg-info → srv/venv/dev/Lib/site-packages/dk_tasklib-0.2.3-py2.7.egg-info}/SOURCES.txt +6 -0
  3. {dk-tasklib-0.2.0 → srv/venv/dev/Lib/site-packages}/dktasklib/__init__.py +1 -2
  4. srv/venv/dev/Lib/site-packages/dktasklib/__init__.pyc +0 -0
  5. srv/venv/dev/Lib/site-packages/dktasklib/_version.py +1 -0
  6. srv/venv/dev/Lib/site-packages/dktasklib/_version.pyc +0 -0
  7. srv/venv/dev/Lib/site-packages/dktasklib/clean.py +10 -0
  8. srv/venv/dev/Lib/site-packages/dktasklib/clean.pyc +0 -0
  9. srv/venv/dev/Lib/site-packages/dktasklib/docs.py +76 -0
  10. srv/venv/dev/Lib/site-packages/dktasklib/docs.pyc +0 -0
  11. srv/venv/dev/Lib/site-packages/dktasklib/executables.py +101 -0
  12. srv/venv/dev/Lib/site-packages/dktasklib/executables.pyc +0 -0
  13. {dk-tasklib-0.2.0 → srv/venv/dev/Lib/site-packages}/dktasklib/jstools.py +5 -4
  14. srv/venv/dev/Lib/site-packages/dktasklib/jstools.pyc +0 -0
  15. srv/venv/dev/Lib/site-packages/dktasklib/lessc.py +152 -0
  16. srv/venv/dev/Lib/site-packages/dktasklib/lessc.pyc +0 -0
  17. srv/venv/dev/Lib/site-packages/dktasklib/manage.py +35 -0
  18. srv/venv/dev/Lib/site-packages/dktasklib/manage.pyc +0 -0
  19. srv/venv/dev/Lib/site-packages/dktasklib/npm.py +64 -0
  20. srv/venv/dev/Lib/site-packages/dktasklib/npm.pyc +0 -0
  21. {dk-tasklib-0.2.0 → srv/venv/dev/Lib/site-packages}/dktasklib/package.py +36 -12
  22. srv/venv/dev/Lib/site-packages/dktasklib/package.pyc +0 -0
  23. srv/venv/dev/Lib/site-packages/dktasklib/runners.py +44 -0
  24. srv/venv/dev/Lib/site-packages/dktasklib/runners.pyc +0 -0
  25. srv/venv/dev/Lib/site-packages/dktasklib/utils.py +68 -0
  26. srv/venv/dev/Lib/site-packages/dktasklib/utils.pyc +0 -0
  27. {dk-tasklib-0.2.0 → srv/venv/dev/Lib/site-packages}/dktasklib/version.py +16 -7
  28. srv/venv/dev/Lib/site-packages/dktasklib/version.pyc +0 -0
  29. dk-tasklib-0.2.0/README.rst +0 -28
  30. dk-tasklib-0.2.0/dk_tasklib.egg-info/PKG-INFO +0 -44
  31. dk-tasklib-0.2.0/dktasklib/lessc.py +0 -109
  32. dk-tasklib-0.2.0/dktasklib/npm.py +0 -19
  33. dk-tasklib-0.2.0/dktasklib/utils.py +0 -88
  34. dk-tasklib-0.2.0/setup.cfg +0 -8
  35. dk-tasklib-0.2.0/setup.py +0 -59
  36. {dk-tasklib-0.2.0/dk_tasklib.egg-info → srv/venv/dev/Lib/site-packages/dk_tasklib-0.2.3-py2.7.egg-info}/dependency_links.txt +0 -0
  37. {dk-tasklib-0.2.0/dk_tasklib.egg-info → srv/venv/dev/Lib/site-packages/dk_tasklib-0.2.3-py2.7.egg-info}/not-zip-safe +0 -0
  38. {dk-tasklib-0.2.0/dk_tasklib.egg-info → srv/venv/dev/Lib/site-packages/dk_tasklib-0.2.3-py2.7.egg-info}/top_level.txt +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: dk-tasklib
3
- Version: 0.2.0
3
+ Version: 0.2.3
4
4
  Summary: dk-tasklib - short description
5
- Home-page: UNKNOWN
5
+ Home-page: https://github.com/datakortet/dk-tasklib
6
6
  Author: Bjorn Pettersen
7
7
  Author-email: bp@datakortet.no
8
8
  License: UNKNOWN
9
9
  Description:
10
- .. image:: https://travis-ci.org/thebjorn/dk-tasklib.svg?branch=master
11
- :target: https://travis-ci.org/thebjorn/dk-tasklib
10
+ .. image:: https://travis-ci.org/datakortet/dk-tasklib.svg?branch=master
11
+ :target: https://travis-ci.org/datakortet/dk-tasklib
12
12
 
13
13
 
14
14
  dk-tasklib -- pyinvoke task library
@@ -7,9 +7,15 @@ dk_tasklib.egg-info/dependency_links.txt
7
7
  dk_tasklib.egg-info/not-zip-safe
8
8
  dk_tasklib.egg-info/top_level.txt
9
9
  dktasklib/__init__.py
10
+ dktasklib/_version.py
11
+ dktasklib/clean.py
12
+ dktasklib/docs.py
13
+ dktasklib/executables.py
10
14
  dktasklib/jstools.py
11
15
  dktasklib/lessc.py
16
+ dktasklib/manage.py
12
17
  dktasklib/npm.py
13
18
  dktasklib/package.py
19
+ dktasklib/runners.py
14
20
  dktasklib/utils.py
15
21
  dktasklib/version.py
@@ -1,6 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ from ._version import __version__
3
4
  from .package import Package
4
5
  from . import lessc
5
- from .npm import isinstalled
6
- from .utils import changed_dir
@@ -0,0 +1 @@
1
+ __version__ = '0.2.3'
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from invoke import ctask as task
4
+
5
+
6
+ @task
7
+ def clean(ctx, directory):
8
+ """Remove all contents from build subdirectory `directory`.
9
+ """
10
+ ctx.run("rm -rf build/{directory}/*".format(directory=directory))
@@ -0,0 +1,76 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import os
4
+ import webbrowser
5
+ from os.path import join
6
+
7
+ from invoke import ctask as task, Collection
8
+
9
+
10
+ # Underscored func name to avoid shadowing kwargs in build()
11
+ @task(name='clean')
12
+ def _clean(ctx):
13
+ """Nuke docs build target directory so next build is clean.
14
+ """
15
+ builddir = ctx.docs.builddir
16
+ if os.path.exists(builddir) and len(os.listdir(builddir)) > 0:
17
+ ctx.run("rm -rf {0}/*".format(builddir))
18
+
19
+
20
+ # Ditto
21
+ @task(name='browse')
22
+ def _browse(ctx): # pragma: nocover
23
+ """Open build target's index.html in a browser (using the :py:mod:`webbrowser` module).
24
+ """
25
+ index = join(ctx.docs.builddir, ctx.docs.target_file)
26
+ webbrowser.open_new(index)
27
+
28
+
29
+ @task(default=True, help={
30
+ 'opts': "Extra sphinx-build options/args",
31
+ 'clean': "Remove build tree before building",
32
+ 'browse': "Open docs index in browser after building",
33
+ 'warn': "Build with stricter warnings/errors enabled",
34
+ 'builder': "Builder to use; defaults tto html",
35
+ 'force': "Force re-reading of all files (ignore cache)",
36
+ })
37
+ def build(ctx, clean=False, browse=False, warn=False,
38
+ builder='html',
39
+ force=True,
40
+ opts=""):
41
+ """
42
+ Build the project's Sphinx docs.
43
+ """
44
+ if clean:
45
+ _clean(ctx)
46
+ if opts is None: # pragma: nocover
47
+ opts = ""
48
+ opts += " -b %s" % builder
49
+ if warn:
50
+ opts += " -n -W"
51
+ if force:
52
+ opts += " -a -E"
53
+ cmd = "sphinx-build {opts} {ctx.docs.source} {ctx.docs.builddir}".format(
54
+ opts=opts, ctx=ctx)
55
+ ctx.run(cmd)
56
+ if browse: # pragma: nocover
57
+ _browse(ctx)
58
+
59
+
60
+ @task
61
+ def tree(ctx):
62
+ """Display the docs tree.
63
+ """
64
+ ignore = ".git|*.pyc|*.swp|dist|*.egg-info|_static|_build|_templates"
65
+ ctx.run('tree -Ca -I "{0}" {1}'.format(ignore, ctx.docs.source))
66
+
67
+
68
+ # Vanilla/default/parameterized collection for normal use
69
+ docs = Collection('docs', _clean, _browse, build, tree)
70
+ docs.configure({
71
+ 'docs': {
72
+ 'source': 'docs',
73
+ 'builddir': join('build', 'docs'),
74
+ 'target_file': 'index.html',
75
+ }
76
+ })
@@ -0,0 +1,101 @@
1
+ # -*- coding: utf-8 -*-
2
+ import sys
3
+ from dkfileutils.which import get_executable
4
+
5
+
6
+ class MissingCommand(Exception):
7
+ """Exception thrown when a command (executable) is not found.
8
+ """
9
+ pass
10
+
11
+
12
+ # noinspection PyShadowingNames
13
+ class Executables(object):
14
+ """Class for finding executables on the host system.
15
+ """
16
+ def __init__(self):
17
+ self._cache = {}
18
+
19
+ def require(self, *dependencies):
20
+ """Ensure that all dependencies are available.
21
+ You should not need to call this yourself, use the :func:`requires`
22
+ decorator instead.
23
+ """
24
+ for dep in dependencies:
25
+ self.find(dep)
26
+
27
+ def find(self, name, requires=(), install_txt='"'):
28
+ """Find the executable named ``name`` on the :envvar:`PATH`.
29
+
30
+ Args:
31
+ name (str): name of executable to find.
32
+ requires (List[str]): list of executables to find first.
33
+ install_txt (str): instructions for how to install the
34
+ executable if it is not found.
35
+ """
36
+ if name not in self._cache:
37
+ self.require(*requires)
38
+
39
+ if hasattr(self, 'find_' + name):
40
+ self._cache[name] = getattr(self, 'find_' + name)()
41
+ else:
42
+ self._cache[name] = self._find_exe(name, requires, install_txt)
43
+ return self._cache[name]
44
+
45
+ def _find_exe(self, name, requires=(), install_txt=None):
46
+ fexe = get_executable(name)
47
+ if not fexe: # pragma: nocover
48
+ if install_txt is None: # pragma: nocover
49
+ install_txt = "Missing command: %s %r" % (name, requires)
50
+ raise MissingCommand(install_txt)
51
+ return fexe
52
+
53
+ def find_nodejs(self): # pragma: nocover
54
+ """Find :program:`node`.
55
+ """
56
+ if sys.platform == 'win32':
57
+ node_exe = get_executable('node')
58
+ else:
59
+ node_exe = get_executable('nodejs') or get_executable('node')
60
+
61
+ if not node_exe: # pragma: nocover
62
+ raise MissingCommand("""
63
+ Install Node.js using your OS package manager
64
+ https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
65
+ """)
66
+ return node_exe
67
+
68
+ def find_npm(self):
69
+ """Find the node package manager (:program:`npm`).
70
+ """
71
+ npm_exe = get_executable('npm')
72
+ if not npm_exe: # pragma: nocover
73
+ raise MissingCommand("""
74
+ Install Node.js using your OS package manager
75
+ https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
76
+ """)
77
+ return npm_exe
78
+
79
+
80
+ #: public interface to the :py:class:`Executables` class
81
+ exe = Executables()
82
+
83
+
84
+ def requires(*deps):
85
+ """Decorator to declare global dependencies/requirements.
86
+
87
+ Usage (``@task`` must be last)::
88
+
89
+ @requires('nodejs', 'npm', 'lessc')
90
+ @task
91
+ def mytask(..)
92
+
93
+ """
94
+ def _wrapper(fn):
95
+ exe.require(*deps)
96
+ return fn
97
+ return _wrapper
98
+
99
+
100
+
101
+
@@ -10,14 +10,15 @@ def browserify(ctx, source, dest, require=(), external=(), entry=None):
10
10
  Run ``browserify``
11
11
 
12
12
  Args:
13
- ctx: context
14
- source: root source file
15
- dest: path/name of assembled file
16
- require:
13
+ ctx (pyinvoke.Context): context
14
+ source (str): root source file
15
+ dest (str): path/name of assembled file
16
+ require (iterable):
17
17
  external:
18
18
  entry:
19
19
 
20
20
  Returns:
21
+ None
21
22
 
22
23
  """
23
24
  options = ""
@@ -0,0 +1,152 @@
1
+ # -*- coding: utf-8 -*-
2
+ import os
3
+ import sys
4
+
5
+ from dkfileutils.changed import Directory
6
+ from invoke import ctask as task, Collection
7
+
8
+ from dktasklib.executables import requires
9
+ from .package import Package
10
+ from .utils import switch_extension, filename, min_name, version_name, join
11
+ from .version import add_version, update_template_version
12
+
13
+ bootstrap = os.path.join(os.environ.get('SRV', ''), 'lib', 'bootstrap', 'less')
14
+
15
+
16
+ @requires('nodejs', 'npm', 'lessc')
17
+ def lessc(ctx,
18
+ source, destination="",
19
+ include_path=None,
20
+ strict_imports=False,
21
+ inline_urls=True,
22
+ autoprefix=True,
23
+ cleancss=True):
24
+ """Run `lessc` with options.
25
+
26
+ Args:
27
+ source (str): the input file name
28
+ destination (Optional[str]): the output filename (if not specified
29
+ it will be the same as the input file name and a ``.css``
30
+ extension).
31
+ include_path (Optional[List[str]]): Optional list of directories
32
+ to search to satisfy ``@import`` directives.
33
+ strict_imports (bool): Re-fetch all imports.
34
+ inline_urls (bool): Should ``@url(.../foo.png)`` be inlined?
35
+ autoprefix (bool): Should the autoprefixer be run (last 4 versions)
36
+ cleancss (bool): Should the css be minified?
37
+
38
+ Returns:
39
+ str: The output file name.
40
+
41
+ """
42
+ if include_path is None:
43
+ include_path = []
44
+ if not destination:
45
+ destination = switch_extension(source, '.css', '.less')
46
+ options = ""
47
+ if getattr(ctx, 'verbose', False): # pragma: nocover
48
+ options += ' --verbose'
49
+ if include_path:
50
+ options += ' --include-path="%s"' % ';'.join(include_path)
51
+ if strict_imports:
52
+ options += " --strict-imports"
53
+ if inline_urls:
54
+ options += " --inline-urls"
55
+ if autoprefix:
56
+ options += ' --autoprefix="last 4 versions"'
57
+ if cleancss:
58
+ options += ' --clean-css="-b --s0 --advanced"'
59
+
60
+ ctx.run("lessc {options} {source} {destination}".format(**locals()))
61
+ return destination
62
+
63
+
64
+ def build_css(ctx,
65
+ lessfile, dest,
66
+ version='pkg',
67
+ use_bootstrap=True,
68
+ **kw):
69
+ """Build a ``.less`` file into a versioned and minified ``.css`` file.
70
+
71
+ Args:
72
+ lessfile (str): input file name
73
+ dest (str): output file name (should be the plain version of the
74
+ output file name, ie. foo.css, not foo.min.css).
75
+ version (str): the type of version number (pkg or hash)
76
+ use_bootstrap (bool): Should Bootstrap be compiled in?
77
+
78
+ Returns:
79
+ str: output file name
80
+
81
+ """
82
+ path = kw.pop('path', [])
83
+ if use_bootstrap:
84
+ path.append(ctx.lessc.bootstrap_less_src)
85
+
86
+ # foo.css -> foo.min.css
87
+ minfname = min_name(dest)
88
+
89
+ output_fname = lessc(
90
+ ctx,
91
+ lessfile,
92
+ os.path.join('build', 'css', minfname),
93
+ # minfname,
94
+ include_path=path,
95
+ strict_imports=True,
96
+ inline_urls=True,
97
+ autoprefix=True,
98
+ cleancss=True,
99
+ )
100
+
101
+ return add_version(
102
+ ctx,
103
+ output_fname,
104
+ version_name(output_fname),
105
+ kind=version)
106
+
107
+
108
+ @task(
109
+ default=True,
110
+ post=[update_template_version],
111
+ help={
112
+
113
+ }
114
+ )
115
+ def build(ctx, force=False, verbose=False, src=None, dst=None, **kw):
116
+ """Compile .less to .css (pakage.json[build_less_input/output]
117
+ """
118
+ if not hasattr(ctx, 'pkg'):
119
+ ctx.pkg = Package()
120
+ if not hasattr(ctx.pkg, 'build_less_input'):
121
+ ctx.pkg.build_less_input = src or 'less/{pkg.name}.less'.format(pkg=ctx.pkg)
122
+ if not hasattr(ctx.pkg, 'build_less_output'):
123
+ ctx.pkg.build_less_output = dst or 'static/{pkg.name}/{pkg.name}.css'.format(pkg=ctx.pkg)
124
+ if not hasattr(ctx, 'force'):
125
+ ctx.force = force
126
+ if not hasattr(ctx, 'verbose'):
127
+ ctx.verbose = verbose
128
+
129
+ if ctx.verbose: # pragma: nocover
130
+ print 'build_less input: ', ctx.pkg.build_less_input
131
+ print 'build_less output:', ctx.pkg.build_less_output
132
+
133
+ dirname = os.path.dirname(ctx.pkg.build_less_input)
134
+
135
+ if ctx.force or Directory(dirname).changed(glob='**/*.less'):
136
+ build_css(
137
+ ctx,
138
+ ctx.pkg.build_less_input,
139
+ ctx.pkg.build_less_output,
140
+ version='pkg',
141
+ **kw
142
+ )
143
+
144
+
145
+ less = Collection('lessc', build)
146
+ less.configure({
147
+ 'lessc': {
148
+ 'source': 'less/index.less',
149
+ 'target': '',
150
+ 'bootstrap_less_src': os.path.join(os.environ.get('BOOTSTRAPSRC', ''), 'less'),
151
+ }
152
+ })
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ import os
3
+ from invoke import ctask as task, run
4
+ from .utils import cd
5
+ from .package import Package
6
+
7
+
8
+ DEFAULT_SETTINGS_MODULE = 'datakortet.settings'
9
+ DEFAULT_MANAGE_PY_PATH = os.path.join(os.environ.get('SRV', ''), 'src', 'datakortet')
10
+
11
+
12
+ @task
13
+ def manage(ctx, cmd, settings=None, manage_path=None):
14
+ """Run manage.py with `settings` in a separate process.
15
+ """
16
+ # os.environ['DJANGO_SETTINGS_MODULE'] = settings or DEFAULT_SETTINGS_MODULE
17
+ with cd(manage_path or DEFAULT_MANAGE_PY_PATH):
18
+ run("python manage.py " + cmd)
19
+
20
+
21
+ @task
22
+ def collectstatic(ctx, verbose=False):
23
+ "Run collectstatic with settings from package.json ('django_settings_module')"
24
+ if not hasattr(ctx, 'pkg'):
25
+ ctx.pkg = Package()
26
+ if not hasattr(ctx, 'verbose'):
27
+ ctx.verbose = verbose
28
+
29
+ try:
30
+ settings = ctx.pkg.django_settings_module
31
+ except AttributeError:
32
+ settings = DEFAULT_SETTINGS_MODULE
33
+ if ctx.verbose:
34
+ print "using settings:", settings
35
+ manage(ctx, "collectstatic --noinput", settings)
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+ import shlex
3
+ import subprocess
4
+
5
+ # from invoke import run
6
+ from dktasklib.executables import exe
7
+ from .utils import null, win32
8
+
9
+
10
+ def npm(cmdline):
11
+ npm_exe = exe.find('npm', requires=['nodejs'])
12
+ return subprocess.check_output("npm " + cmdline, shell=True).decode('u8')
13
+
14
+ #
15
+ #
16
+ # def cmd2args(cmd):
17
+ # if isinstance(cmd, basestring):
18
+ # return cmd if win32 else shlex.split(cmd)
19
+ # # return cmd.split() if win32 else shlex.split(cmd)
20
+ # return cmd
21
+ #
22
+ #
23
+ # class RunError(Exception):
24
+ # def __init__(self, cmd, errno):
25
+ # self.errno = errno
26
+ # super(RunError, self).__init__(cmd, errno)
27
+ #
28
+ #
29
+ # def _run(cmd):
30
+ # popen = subprocess.Popen(
31
+ # cmd2args(cmd),
32
+ # stdout=subprocess.PIPE,
33
+ # stderr=subprocess.STDOUT,
34
+ # cwd=None,
35
+ # shell=win32
36
+ # )
37
+ #
38
+ # for line in iter(popen.stdout.readline, ""):
39
+ # # print ">>", line
40
+ # yield line
41
+ #
42
+ # exitcode = popen.wait()
43
+ # if exitcode != 0:
44
+ # raise RunError(cmd, exitcode)
45
+ #
46
+ #
47
+ # class run(object):
48
+ # def __init__(self, cmd):
49
+ # self.return_code = 0
50
+ # try:
51
+ # self.output = '\n'.join(line for line in _run(cmd))
52
+ # except RunError as e:
53
+ # self.return_code = e.errno
54
+
55
+
56
+ def global_package(pkgname):
57
+ """Check if an npm package is installed globally.
58
+ """
59
+ try:
60
+ # this is the 'correct' way, but it's increadably slow (4+ secs)
61
+ npm('ls -g --depth 0 ' + pkgname)
62
+ return True
63
+ except subprocess.CalledProcessError:
64
+ return False
@@ -3,20 +3,19 @@
3
3
  import json
4
4
  import os
5
5
 
6
- from ConfigParser import RawConfigParser
6
+ from ConfigParser import RawConfigParser, NoOptionError
7
7
  from dkfileutils.pfind import pfind
8
8
 
9
9
 
10
10
  class PackageInterface(object):
11
- def version(self):
12
- return self['version']
13
11
 
14
12
  def upversion(self, major=False, minor=False, patch=False):
15
13
  """Update package version (default patch-level increase).
16
14
  """
17
15
  if not (major or minor or patch):
18
- patch = True
19
- version = [int(n, 10) for n in self.version().split('.')]
16
+ # this is normally set by version.upversion
17
+ patch = True # pragma: nocover
18
+ version = [int(n, 10) for n in self.version.split('.')]
20
19
  if major:
21
20
  version[0] += 1
22
21
  if minor:
@@ -27,6 +26,21 @@ class PackageInterface(object):
27
26
  self['version'] = newversion
28
27
  return newversion
29
28
 
29
+ # for convenience (continue using [](__setitem__) for setting).
30
+ def __getattr__(self, item):
31
+ return self[item]
32
+
33
+ def __setitem__(self, key, value): # pragma: nocover
34
+ # should override
35
+ pass
36
+
37
+ def __getitem__(self, item, default=None): # pragma: nocover
38
+ # should override
39
+ return ''
40
+
41
+ def get(self, key, default=None):
42
+ return self.__getitem__(key, default)
43
+
30
44
 
31
45
  class PackageIni(PackageInterface):
32
46
  """Read package.ini or dkbuild.ini file::
@@ -39,10 +53,14 @@ class PackageIni(PackageInterface):
39
53
  def exists(cls):
40
54
  return pfind('.', 'package.ini') or pfind('.', 'dkbuild.ini')
41
55
 
42
- def __init__(self):
56
+ def __init__(self, *args, **kw):
43
57
  self.fname = pfind('.', 'package.ini') or pfind('.', 'dkbuild.ini')
44
- if self.fname is None:
45
- raise RuntimeError("I couldn't find a %s file" % packagejson)
58
+ if self.fname is None: # pragma: nocover
59
+ raise RuntimeError("""
60
+ I couldn't find a package.json, package.ini,
61
+ or dkbuild.ini file starting from %s.
62
+ """ % os.getcwd())
63
+ self.root = os.path.dirname(self.fname)
46
64
  self._package = None
47
65
 
48
66
  def _open(self, fname):
@@ -62,7 +80,8 @@ class PackageIni(PackageInterface):
62
80
  def __getitem__(self, attr, default=None):
63
81
  try:
64
82
  return self.package.get('package', attr)
65
- except KeyError:
83
+ except (KeyError, NoOptionError):
84
+ # return default
66
85
  if default is not None:
67
86
  return default
68
87
  raise AttributeError(
@@ -83,26 +102,31 @@ class PackageJson(PackageInterface):
83
102
  def __init__(self, basedir=None, packagejson='package.json'):
84
103
  if basedir is None:
85
104
  self.fname = pfind('.', packagejson)
86
- if self.fname is None:
105
+ if self.fname is None: # pragma: nocover
87
106
  raise RuntimeError("I couldn't find a %s file" % packagejson)
88
107
  else:
89
108
  self.fname = os.path.join(basedir, packagejson)
109
+ self.root = os.path.dirname(self.fname)
90
110
  self._package = None
91
111
 
92
112
  @property
93
113
  def package(self):
94
114
  if not self._package:
95
- self._package = json.loads(open(self.fname).read())
115
+ with open(self.fname) as fp:
116
+ self._package = json.loads(fp.read())
96
117
  return self._package
97
118
 
98
119
  def __setitem__(self, key, value):
99
120
  self.package[key] = value
100
- json.dump(open(self.fname, 'w'), self.package, indent=4)
121
+ # print "PACKAGE:", self.package
122
+ # print json.dumps(self.package, indent=4)
123
+ json.dump(self.package, open(self.fname, 'w'), indent=4)
101
124
 
102
125
  def __getitem__(self, attr, default=None):
103
126
  try:
104
127
  return self.package[attr]
105
128
  except KeyError:
129
+ # return default
106
130
  if default is not None:
107
131
  return default
108
132
  raise AttributeError(
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+ import subprocess
3
+
4
+
5
+ class Result(str):
6
+ cmd = None
7
+ returncode = None
8
+
9
+
10
+ def run(cmdline, throw=False):
11
+ try:
12
+ res = Result(
13
+ subprocess.check_output(
14
+ cmdline,
15
+ shell=True
16
+ ).decode('u8')
17
+ )
18
+ res.cmd = cmdline
19
+ return res
20
+ except subprocess.CalledProcessError as e:
21
+ if throw:
22
+ raise
23
+ res = Result(e.output)
24
+ res.cmd = cmdline
25
+ res.returncode = e.returncode
26
+ return res
27
+
28
+
29
+ def command(executable, dryrun=False):
30
+ def _call(*args, **kwargs):
31
+ cmdline = " ".join(args)
32
+ for k, v in kwargs.items():
33
+ if v is True:
34
+ cmdline += " --" + k
35
+ else:
36
+ if ' ' in v:
37
+ v = '"%s"' % v
38
+ cmdline += ' --%s=%s' % (k, v)
39
+
40
+ if dryrun:
41
+ print cmdline
42
+ else:
43
+ return run(cmdline)
44
+ return _call
@@ -0,0 +1,68 @@
1
+ # -*- coding: utf-8 -*-
2
+ import inspect
3
+ import os
4
+ from contextlib import contextmanager
5
+
6
+ import sys
7
+
8
+ from dkfileutils.changed import changed
9
+
10
+ join = os.path.join
11
+ null = "NUL" if sys.platform == 'win32' else '/dev/null'
12
+ win32 = sys.platform == 'win32'
13
+
14
+
15
+ def switch_extension(fname, ext="", old_ext=None):
16
+ """Switch file extension on `fname` to `ext`. Returns the resulting
17
+ file name.
18
+
19
+ Usage::
20
+
21
+ switch_extension('a/b/c/d.less', '.css')
22
+
23
+ """
24
+ name, _ext = os.path.splitext(fname)
25
+ if old_ext:
26
+ assert old_ext == _ext
27
+ return name + ext
28
+
29
+
30
+ def filename(fname):
31
+ """Return only the file name (removes the path)
32
+ """
33
+ return os.path.split(fname)[1]
34
+
35
+
36
+ def min_name(fname, min='.min'):
37
+ """Adds a `.min` extension before the last file extension.
38
+ """
39
+ name, ext = os.path.splitext(fname)
40
+ return name + min + ext
41
+
42
+
43
+ def version_name(fname):
44
+ """Returns a template string containing `{version}` in the correct
45
+ place.
46
+ """
47
+ if '.min.' in fname:
48
+ pre, post = fname.split('.min.')
49
+ return pre + '-{version}.min.' + post
50
+ else:
51
+ return min_name(fname, '-{version}')
52
+
53
+
54
+ @contextmanager
55
+ def cd(directory):
56
+ """Context manager to change directory.
57
+
58
+ Usage::
59
+
60
+ with cd('foo/bar'):
61
+ # current directory is now foo/bar
62
+ # current directory restored.
63
+
64
+ """
65
+ cwd = os.getcwd()
66
+ os.chdir(directory)
67
+ yield
68
+ os.chdir(cwd)
@@ -3,6 +3,8 @@ import re
3
3
  import os
4
4
  import hashlib
5
5
  import textwrap
6
+
7
+ from dkfileutils.path import Path
6
8
  from invoke import run, ctask as task
7
9
  # from .subversion import get_svn_version
8
10
  from .package import Package
@@ -10,12 +12,15 @@ from .package import Package
10
12
 
11
13
  @task(help=dict(
12
14
  dest_template="this filename template must contain '{version}'",
13
- kind="type of version number [pkg,svn,hash]",
15
+ kind="type of version number [pkg,hash]",
14
16
  ))
15
17
  def add_version(ctx, source, dest_template, kind="pkg", force=None):
16
18
  """Add version number to a file (either pkg version, svn revision, or hash).
19
+
20
+ Returns:
21
+ (str) output file name
17
22
  """
18
- if not hasattr(ctx, 'pkg'):
23
+ if kind == 'pkg' and not hasattr(ctx, 'pkg'):
19
24
  ctx.pkg = Package()
20
25
  if not hasattr(ctx, 'force'):
21
26
  ctx.force = bool(force)
@@ -23,13 +28,13 @@ def add_version(ctx, source, dest_template, kind="pkg", force=None):
23
28
  ctx.force = force
24
29
 
25
30
  if kind == "pkg":
26
- version = ctx.pkg.version
31
+ ver = ctx.pkg.version
27
32
  elif kind == "hash":
28
- version = hashlib.md5(open(source).read()).hexdigest()
33
+ ver = hashlib.md5(open(source).read()).hexdigest()
29
34
  # elif kind == "svn":
30
- # version = get_svn_version(source)
35
+ # ver = get_svn_version(source)
31
36
 
32
- ver_fname = dest_template.format(version=version)
37
+ ver_fname = dest_template.format(version=ver)
33
38
 
34
39
  if not ctx.force and os.path.exists(ver_fname):
35
40
  if open(source).read() != open(ver_fname).read():
@@ -39,13 +44,16 @@ def add_version(ctx, source, dest_template, kind="pkg", force=None):
39
44
  or pass --force to the build command.
40
45
  """
41
46
  else:
47
+ # copy file contents to versioned file name
42
48
  with open(ver_fname, 'wb') as fp:
43
49
  fp.write(open(source, 'rb').read())
44
50
 
51
+ return ver_fname
52
+
45
53
 
46
54
  @task
47
55
  def version(ctx):
48
- vnum = Package().version()
56
+ vnum = Package().version
49
57
  print vnum
50
58
  return vnum
51
59
 
@@ -74,6 +82,7 @@ def update_template_version(ctx, fname=None):
74
82
  fname = fname or ctx.pkg.update_template_version_fname
75
83
 
76
84
  if not os.path.exists(fname):
85
+ Path(ctx.pkg.root).makedirs(Path(fname).dirname())
77
86
  with open(fname, 'w') as fp:
78
87
  fp.write(textwrap.dedent("""
79
88
  {% load staticfiles %}
@@ -1,28 +0,0 @@
1
-
2
- .. image:: https://travis-ci.org/thebjorn/dk-tasklib.svg?branch=master
3
- :target: https://travis-ci.org/thebjorn/dk-tasklib
4
-
5
-
6
- dk-tasklib -- pyinvoke task library
7
- ==================================================
8
-
9
-
10
- Installing from PyPI
11
- --------------------
12
-
13
- This is what you want if you just want to use dk-tasklib:
14
-
15
- pip install dk-tasklib
16
-
17
-
18
- As a source package
19
- -------------------
20
- This is what you want if you are developing dk-tasklib or want
21
- to make local changes to the source code.
22
-
23
- pip install -e <path>
24
-
25
-
26
-
27
-
28
- See docs/ folder for documentation.
@@ -1,44 +0,0 @@
1
- Metadata-Version: 1.1
2
- Name: dk-tasklib
3
- Version: 0.2.0
4
- Summary: dk-tasklib - short description
5
- Home-page: UNKNOWN
6
- Author: Bjorn Pettersen
7
- Author-email: bp@datakortet.no
8
- License: UNKNOWN
9
- Description:
10
- .. image:: https://travis-ci.org/thebjorn/dk-tasklib.svg?branch=master
11
- :target: https://travis-ci.org/thebjorn/dk-tasklib
12
-
13
-
14
- dk-tasklib -- pyinvoke task library
15
- ==================================================
16
-
17
-
18
- Installing from PyPI
19
- --------------------
20
-
21
- This is what you want if you just want to use dk-tasklib:
22
-
23
- pip install dk-tasklib
24
-
25
-
26
- As a source package
27
- -------------------
28
- This is what you want if you are developing dk-tasklib or want
29
- to make local changes to the source code.
30
-
31
- pip install -e <path>
32
-
33
-
34
-
35
-
36
- See docs/ folder for documentation.
37
-
38
- Platform: UNKNOWN
39
- Classifier: Development Status :: 3 - Alpha
40
- Classifier: Intended Audience :: Developers
41
- Classifier: Programming Language :: Python
42
- Classifier: Programming Language :: Python :: 2
43
- Classifier: Programming Language :: Python :: 2.7
44
- Classifier: Topic :: Software Development :: Libraries
@@ -1,109 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- import os
3
- import sys
4
-
5
- from invoke import run, ctask as task
6
-
7
- from .package import Package
8
- from .utils import switch_extension, filename, min_name, version_name, join, changed_dir
9
- from .version import add_version, update_template_version
10
-
11
- bootstrap = os.path.join(os.environ['SRV'], 'lib', 'bootstrap', 'less')
12
-
13
-
14
- @task
15
- def version(ctx):
16
- "Display the lessc version"
17
- return run("lessc --version")
18
-
19
-
20
- @task
21
- def lessc(ctx, source, destination="",
22
- include_path=None,
23
- strict_imports=False,
24
- inline_urls=True,
25
- autoprefix=True,
26
- cleancss=True
27
- ):
28
- if include_path is None:
29
- include_path = []
30
- if not destination:
31
- destination = source[:-len('.less')] + '.css'
32
- options = ""
33
- if ctx.verbose:
34
- options += ' --verbose'
35
- if include_path:
36
- options += ' --include-path="%s"' % ';'.join(include_path)
37
- if strict_imports:
38
- options += " --strict-imports"
39
- if inline_urls:
40
- options += " --inline-urls"
41
- if autoprefix:
42
- options += ' --autoprefix="last 4 versions"'
43
- if cleancss:
44
- options += ' --clean-css="-b --s0 --advanced"'
45
-
46
- run("lessc {options} {source} {destination}".format(**locals()))
47
-
48
-
49
- @task
50
- def build_css(ctx, lessfile, dest, version='svn',
51
- build='build/css', use_bootstrap=True, **kw):
52
- """Build all .less files into .css.
53
- `dest` should be the target filename.
54
- """
55
- path = kw.pop('path', [])
56
- if use_bootstrap:
57
- path.append(bootstrap)
58
-
59
- cssfname = join(build, switch_extension(filename(lessfile), '.css'))
60
- minfname = min_name(dest)
61
-
62
- # rawcss = join(build, filename(dest))
63
-
64
- if ctx.verbose:
65
- print >>sys.stderr, 'lessc..'
66
-
67
- lessc(
68
- ctx,
69
- lessfile,
70
- minfname,
71
- include_path=path,
72
- strict_imports=True,
73
- inline_urls=True,
74
- autoprefix=True,
75
- cleancss=True,
76
- )
77
-
78
- if ctx.verbose:
79
- print >>sys.stderr, 'verisioning..'
80
- add_version(ctx, minfname, version_name(minfname), kind=version)
81
-
82
-
83
- @task(post=[update_template_version])
84
- def build_less(ctx, force=False, verbose=False, src=None, dst=None, **kw):
85
- """Compile .less to .css (pakage.json[build_less_input/output]
86
- """
87
- if not hasattr(ctx, 'pkg'):
88
- ctx.pkg = Package()
89
- if not hasattr(ctx.pkg, 'build_less_input'):
90
- ctx.pkg.build_less_input = src or 'less/{pkg.name}.less'.format(pkg=ctx.pkg)
91
- if not hasattr(ctx.pkg, 'build_less_output'):
92
- ctx.pkg.build_less_output = dst or 'static/{pkg.name}/{pkg.name}.css'.format(pkg=ctx.pkg)
93
- if not hasattr(ctx, 'force'):
94
- ctx.force = force
95
- if not hasattr(ctx, 'verbose'):
96
- ctx.verbose = verbose
97
- if ctx.verbose:
98
- print 'build_less input: ', ctx.pkg.build_less_input
99
- print 'build_less output:', ctx.pkg.build_less_output
100
-
101
- dirname = os.path.dirname(ctx.pkg.build_less_input)
102
- with changed_dir(dirname, '**/*.less', force=ctx.force):
103
- build_css(
104
- ctx,
105
- ctx.pkg.build_less_input,
106
- ctx.pkg.build_less_output,
107
- version='pkg',
108
- **kw
109
- )
@@ -1,19 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- from invoke import ctask as task
4
-
5
-
6
- @task
7
- def is_installed(ctx, pkgname, version=None):
8
- "Check if an npm package is installed."
9
- rc = ctx.run('npm ls -g --depth=0 {pkgname} >NUL'.format(**locals())).return_code
10
- ctx[pkgname] = rc == 0
11
-
12
-
13
- @task
14
- def isinstalled(ctx, pkgname):
15
- "Check if an npm package is installed."
16
- rc = ctx.run('which {pkgname}'.format(**locals()), hide=True).return_code
17
- ctx[pkgname] = rc == 0
18
-
19
-
@@ -1,88 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- import inspect
3
- import os
4
- from contextlib import contextmanager
5
-
6
- import sys
7
-
8
- from dkfileutils.changed import changed
9
-
10
- join = os.path.join
11
-
12
-
13
- def switch_extension(fname, ext="", old_ext=None):
14
- """Usage::
15
-
16
- switch_extension('a/b/c/d.less', '.css')
17
-
18
- """
19
- name, _ext = os.path.splitext(fname)
20
- if old_ext:
21
- assert old_ext == _ext
22
- return name + ext
23
-
24
-
25
- def filename(fname):
26
- return os.path.split(fname)[1]
27
-
28
-
29
- def min_name(fname, min='.min'):
30
- name, ext = os.path.splitext(fname)
31
- return name + min + ext
32
-
33
-
34
- def version_name(fname):
35
- if '.min.' in fname:
36
- pre, post = fname.split('.min.')
37
- return pre + '-{version}.min.' + post
38
- else:
39
- return min_name(fname, '-{version}')
40
-
41
-
42
- @contextmanager
43
- def cd(directory):
44
- cwd = os.getcwd()
45
- os.chdir(directory)
46
- yield
47
- os.chdir(cwd)
48
-
49
-
50
- class changed_dir(object):
51
- """Has `glob` changed in `dirname` or `force`
52
- """
53
- class NoChange(ValueError):
54
- pass
55
-
56
- def __init__(self,
57
- dirname,
58
- glob='**/*',
59
- filename='.md5',
60
- force=False,
61
- msg="nothing to do"):
62
- self.dirname = dirname
63
- self.glob = glob
64
- self.filename = filename
65
- self.force = force
66
- self.msg = msg
67
- self._trace = None
68
-
69
- def __enter__(self):
70
- if self.force or changed(self.dirname, self.glob, self.filename):
71
- return
72
- else:
73
- print self.msg
74
- # this horrid hack is just barely ok in task.py code...
75
- # (expect debuggers/pylint/coverage/etc. to be unhappy)
76
- self._trace = sys.gettrace()
77
- sys.settrace(lambda *args, **kw: None)
78
- frame = inspect.currentframe(1)
79
- # set the trace function below on parent frame
80
- frame.f_trace = self.trace
81
-
82
- def trace(self, frame, event, arg):
83
- # we just entered the with block.. cleanup and exit immediately
84
- sys.settrace(self._trace)
85
- raise changed_dir.NoChange()
86
-
87
- def __exit__(self, type, value, traceback):
88
- return isinstance(value, changed_dir.NoChange)
@@ -1,8 +0,0 @@
1
- [wheel]
2
- universal = 1
3
-
4
- [egg_info]
5
- tag_build =
6
- tag_date = 0
7
- tag_svn_revision = 0
8
-
dk-tasklib-0.2.0/setup.py DELETED
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- """dk-tasklib - short description
5
- """
6
- import os
7
- import sys
8
-
9
- classifiers = """\
10
- Development Status :: 3 - Alpha
11
- Intended Audience :: Developers
12
- Programming Language :: Python
13
- Programming Language :: Python :: 2
14
- Programming Language :: Python :: 2.7
15
- Topic :: Software Development :: Libraries
16
- """
17
-
18
- import setuptools
19
- from distutils.core import setup, Command
20
- from setuptools.command.test import test as TestCommand
21
- from ConfigParser import RawConfigParser
22
-
23
-
24
- version = '0.2.0'
25
-
26
-
27
- class PyTest(TestCommand):
28
- user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")]
29
-
30
- def initialize_options(self):
31
- TestCommand.initialize_options(self)
32
- self.pytest_args = []
33
-
34
- def finalize_options(self):
35
- TestCommand.finalize_options(self)
36
- self.test_args = []
37
- self.test_suite = True
38
-
39
- def run_tests(self):
40
- # import here, cause outside the eggs aren't loaded
41
- import pytest
42
- errno = pytest.main(self.pytest_args)
43
- sys.exit(errno)
44
-
45
-
46
- setup(
47
- name='dk-tasklib',
48
- version=version,
49
- requires=[],
50
- install_requires=[],
51
- author='Bjorn Pettersen',
52
- author_email='bp@datakortet.no',
53
- description=__doc__.strip(),
54
- classifiers=[line for line in classifiers.split('\n') if line],
55
- long_description=open('README.rst').read(),
56
- cmdclass={'test': PyTest},
57
- packages=['dktasklib'],
58
- zip_safe=False,
59
- )