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(params) ⇒ 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"
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 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'lib/bee_task_python.rb', line 305 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: ~ }
388 389 390 391 392 393 394 |
# File 'lib/bee_task_python.rb', line 388 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"
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/bee_task_python.rb', line 222 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"
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/bee_task_python.rb', line 106 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"
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 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bee_task_python.rb', line 157 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(params) ⇒ Object
Run a given Python source file. Parameter is the source file to run (source file must be an existing readable file) or the following ones:
-
source: The source file to run.
-
args: the command line arguments to pass to the scripts.
-
lenient: If true, will not fail if return value if the process is different from 0 (which is the default).
Example
- python.python: "my_script.py"
- python.python:
source: "my_script.py"
args: ["foo", "bar"]
lenient: true
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/bee_task_python.rb', line 68 def python(params) lenient = false if params.kind_of?(String) error "python.python parameter must be an existing file" unless File.exists?(params) and File.readable?(params) ok = system("python #{params}") else params_desc = { :source => { :mandatory => true, :type => :string }, :args => { :mandatory => false, :type => :string_or_array }, :lenient => { :mandatory => false, :type => :boolean, :default => false } } check_parameters(params, params_desc) source = params[:source] args = [source] + params[:args] lenient = params[:lenient] ok = system('python', *args) end error "Error running Python source file '#{source}'" unless ok or lenient 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
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
# File 'lib/bee_task_python.rb', line 404 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 elsif line.strip.length > 0 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"
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/bee_task_python.rb', line 263 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 |