Class: Bee::Task::Python
- Inherits:
-
Package
- Object
- Package
- Bee::Task::Python
- Defined in:
- lib/bee_task_python.rb
Overview
Package for Python tasks.
Instance Method Summary collapse
-
#compile(globs) ⇒ Object
Compile Python source files, checking syntax and generating .pyc files.
-
#coverage(params) ⇒ Object
Generate test coverage report.
-
#dependencies(deps) ⇒ Object
Check Python dependencies using PIP (see pypi.python.org/pypi/pip).
-
#epydoc(params) ⇒ Object
Generate documentation using Epydoc tool.
-
#pychecker(params) ⇒ Object
Check source files using Pychecker tool.
-
#pylint(params) ⇒ Object
Check source files using Pylint tool.
-
#python(source) ⇒ Object
Run a given Python source file.
-
#requirements(reqs) ⇒ Object
Check Python dependencies using PIP (see pypi.python.org/pypi/pip).
-
#test(globs) ⇒ Object
Run python test files.
Instance Method Details
#compile(globs) ⇒ Object
Compile Python source files, checking syntax and generating .pyc files. Parameter is a glob or list of globs for files to compile.
Example
- python.compile: "**/*.py"
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/bee_task_python.rb', line 32 def compile(globs) error "python.compile parameter is a String or Array of Strings" unless globs.kind_of?(String) or globs.kind_of?(Array) for glob in globs error "python.compile parameter is a String or Array of Strings" unless glob.kind_of?(String) files = Dir.glob(glob) size = (files.kind_of?(Array) ? files.size : 1) puts "Compiling #{size} Python source file(s)" if files.length > 0 script = File.join(File.(File.dirname(__FILE__)), '..', 'tools', 'compile', 'compile.py') for file in files puts "Compiling Python source file '#{file}'" if @verbose command = "python #{script} #{file}" puts "Running command: '#{command}'" if @verbose ok = system(command) error "Error compiling Python source file '#{file}'" unless ok end end end |
#coverage(params) ⇒ Object
Generate test coverage report.
-
src: directory or list of directories containing Python source files to measure test coverage for.
-
test: glob or list of globs for tests to run while measuring coverage.
-
dir: directory where to run unit tests. Optional, defaults to current directory.
-
dest: destination directory where to generate coverage report. Optional, will print report on console if not set.
-
data: file where to write coverage data. Optional, defaults to file .coverage in current directory.
-
path: a list of directories to add to Python path to run tests.
Example
- python.coverage:
src: "src"
test: "test/suite.py"
dir: "test"
dest: "build/coverage"
data: "build/.coverage"
path: "lib"
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
# File 'lib/bee_task_python.rb', line 283 def coverage(params) # check parameters params_desc = { :src => { :mandatory => true, :type => :string_or_array }, :test => { :mandatory => true, :type => :string_or_array }, :dir => { :mandatory => true, :type => :string }, :dest => { :mandatory => false, :type => :string }, :data => { :mandatory => false, :type => :string }, :path => { :mandatory => false, :type => :string_or_array }, } check_parameters(params, params_desc) src = params[:src] test = params[:test] dir = params[:dir] dest = params[:dest] data = File.(params[:data] || '.coverage') path = params[:path] path = path.map {|d| File.(d)} if path # manage directories and files src_files = [] for src_dir in src error "Coverage 'src' parameter must be existing directories" unless File.exists?(src_dir) and File.directory?(src_dir) src_files += Dir.glob("#{src_dir}/**/*.py") end src_files = src_files.map {|f| File.(f)}.uniq.sort sources = src_files.join(' ') test_files = [] for test_glob in test test_files += Dir.glob(test_glob) end test_files = test_files.map {|f| File.(f)}.uniq.sort error "Coverage 'dir' parameter must be an existing directory" unless File.exists?(dir) and File.directory?(dir) if dest dest = File.(dest) FileUtils.makedirs(dest) if not File.exists?(dest) report = File.join(dest, 'report.txt') end if path for path_dir in path error "Coverage 'path' parameter must be existing directories" unless File.exists?(path_dir) and File.directory?(path_dir) end end # build the python path add_python_path(path) # run coverage command puts "Generating coverage report for #{test_files.length} test(s)..." File.delete(data) if File.exists?(data) prev_dir = Dir.pwd for test_file in test_files begin Dir.chdir(dir) command = "coverage -x -f #{data} #{test_file}" puts "Running command: '#{command}'" if @verbose system(command) || error("Error running coverage report") ensure Dir.chdir(prev_dir) end end if dest command = "coverage -r -f #{data} -m #{sources} > #{report}" system(command) || error("Error generating coverage report") command = "coverage -a -f #{data} -d #{dest} #{sources}" puts "Running command: '#{command}'" if @verbose system(command) || error("Error generating coverage report") else command = "coverage -r -f #{data} -m #{sources}" puts "Running command: '#{command}'" if @verbose system(command) || error("Error generating coverage report") end end |
#dependencies(deps) ⇒ Object
Check Python dependencies using PIP (see pypi.python.org/pypi/pip). Takes a single parameter that is the map of dependencies that gives version for a given dependency. A version set to ~ (or nil) indicates that this dependency is needed in any version (useful for developement libraries used for development).
Example:
- python.dependencies: { Django: "1.2.3", PyYAML: ~ }
366 367 368 369 370 371 372 |
# File 'lib/bee_task_python.rb', line 366 def dependencies(deps) error "python.dependencies parameter is a Map" unless deps.kind_of?(Hash) puts "Checking Python dependencies..." installed = installed_dependencies() check_dependencies(deps, installed) end |
#epydoc(params) ⇒ Object
Generate documentation using Epydoc tool.
-
src: directory or list of directories containing Python source files to doc for.
-
dest: destination directory for generated documentation.
-
options: custom options to use on command line (optional).
Example
- python.pychecker:
src: ["lib", "test"]
dest: "build/doc"
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/bee_task_python.rb', line 200 def epydoc(params) # check parameters params_desc = { :src => { :mandatory => true, :type => :string_or_array }, :dest => { :mandatory => true, :type => :string }, :options => { :mandatory => false, :type => :string }, } check_parameters(params, params_desc) src = params[:src] dest = params[:dest] = params[:options] # build the list of python source files src = Array(src) files = [] for dir in src files += Dir.glob("#{dir}/**/*.py") end files.map! { |file| "\"#{file}\"" } files.uniq! # make destination directory if it doesn't exist FileUtils.makedirs(dest) if not File.exists?(dest) error "epydoc 'dest' parameter must be a writable directory" unless File.directory?(dest) and File.writable?(dest) # run epydoc command puts "Generating doc for #{files.length} Python source file(s)" command = "epydoc" command += " -o #{dest}" command += " #{options}" if command += " #{files.join(' ')}" puts "Running command: '#{command}'" if @verbose ok = system(command) error "Error generating documentation for Python source files" unless ok end |
#pychecker(params) ⇒ Object
Check source files using Pychecker tool. You may find documentation about this tool at this URL: pychecker.sourceforge.net/.
-
src: directory or list of directories containing Python source files to check.
-
options: custom options to use on command line (optional).
-
lenient: if set to true, doesn’t interrupt the build on error. Optional, defaults to false.
-
only: Tells if we must only check sources passed as parameters. Optional, defaults to true.
Example
- python.pychecker:
src: ["lib", "test"]
options: "--keepgoing"
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/bee_task_python.rb', line 84 def pychecker(params) # check parameters params_desc = { :src => { :mandatory => true, :type => :string_or_array }, :options => { :mandatory => false, :type => :string }, :lenient => { :mandatory => false, :type => :boolean, :default => false }, :only => { :mandatory => false, :type => :boolean, :default => true } } check_parameters(params, params_desc) src = params[:src] = params[:options] lenient = params[:lenient] only = params[:only] # build the list of python source files src = Array(src) files = [] for dir in src files += Dir.glob("#{dir}/**/*.py") end files.map! { |file| "\"#{file}\"" } files.uniq! # run pychecker command puts "Checking #{files.length} Python source file(s)" command = "pychecker" command += " #{options}" if command += " --only" if only command += " #{files.join(' ')}" puts "Running command: '#{command}'" if @verbose ok = system(command) error "Error checking Python source files" unless ok or lenient end |
#pylint(params) ⇒ Object
Check source files using Pylint tool. You may find documentation about this tool at: www.logilab.org/card/pylint_tutorial.
-
src: directory or list of directories containing Python source files to check.
-
files: a list of Python source files to check.
-
path: a list of additional directories to include in Python path. Optional, defaults to no directory.
-
options: custom options to use on command line (optional).
-
lenient: if set to true, doesn’t interrupt the build on error. Optional, defaults to false.
-
config: configuration file name. Optional.
Example
- python.pylint:
src: "lib"
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/bee_task_python.rb', line 135 def pylint(params) # check parameters params_desc = { :src => { :mandatory => false, :type => :string_or_array }, :files => { :mandatory => false, :type => :string_or_array }, :path => { :mandatory => false, :type => :string_or_array }, :options => { :mandatory => false, :type => :string }, :lenient => { :mandatory => false, :type => :boolean, :default => false }, :config => { :mandatory => false, :type => :string_or_array }, } check_parameters(params, params_desc) src = params[:src] files = params[:files] path = params[:path] = params[:options] lenient = params[:lenient] config = params[:config] # build the list of python source files error "Must set at least one of 'src' or 'files' in python.pylint" if not src and not files if files files = Array(files) else files = [] end if src src = Array(src) for dir in src files += Dir.glob("#{dir}/**/*.py") end end # build the list of source directory to include them in PYTHONPATH dirs = [] for file in files dir = File.(File.dirname(file)) dirs << dir if not dirs.include?(dir) end dirs += path if path add_python_path(dirs) files.map! { |file| "\"#{file}\"" } files.uniq! # run pylint command puts "Checking #{files.length} Python source file(s)" command = "pylint" command += " --rcfile=#{config}" if config command += " #{options}" if command += " #{files.join(' ')}" puts "Running command: '#{command}'" if @verbose ok = system(command) error "Error checking Python source files" unless ok or lenient end |
#python(source) ⇒ Object
Run a given Python source file. Parameter is the source file to run. Source file must be an existing readable file.
Example
- python.python: "my_script.py"
59 60 61 62 63 64 65 66 |
# File 'lib/bee_task_python.rb', line 59 def python(source) error "python.python parameter is a String" unless source.kind_of?(String) error "python.python parameter must be an existing file" unless File.exists?(source) and File.readable?(source) ok = system("python #{source}") error "Error running Python source file '#{source}'" unless ok end |
#requirements(reqs) ⇒ Object
Check Python dependencies using PIP (see pypi.python.org/pypi/pip). Takes a single parameter that is the requirements file name. A dependency may specify no version, in this case we check that dependency in installed in any version..
Example:
- python.requirements: requirements.txt
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/bee_task_python.rb', line 382 def requirements(reqs) error "python.requirements parameter is a string" unless reqs.kind_of?(String) puts "Checking Python requirements..." installed = installed_dependencies() content = File.read(reqs).strip dependencies = {} for line in content if line =~ /.+==.+/ name, version = line.scan(/[^=]+/).map{|e| e.strip} dependencies[name] = version else dependencies[line.strip] = nil end end check_dependencies(dependencies, installed) end |
#test(globs) ⇒ Object
Run python test files. Parameter is a glob or list of globs for test files to run.
Example
- python.test: "test/test_*.py"
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/bee_task_python.rb', line 241 def test(globs) error "python.test parameter is a String or Array of Strings" unless globs.kind_of?(String) or globs.kind_of?(Array) for glob in globs error "python.test parameter is a String or Array of Strings" unless glob.kind_of?(String) files = Dir.glob(glob) files.map! {|f| File.(f)} size = (files.kind_of?(Array) ? files.size : 1) puts "Running #{size} Python test file(s)" if files.length > 0 script = File.join(File.(File.dirname(__FILE__)), '..', 'tools', 'test', 'suite.py') command = "python #{script} #{files.join(' ')}" puts "Running command: '#{command}'" if @verbose ok = system(command) error "Error running Python test(s)" unless ok end end |