2014-04-02 17:03:20 +02:00
# encoding: utf-8
# ruby: 2.1.0
= begin
Rakefile to manage gEDA hardware projects
= end
2014-03-02 18:40:00 +01:00
require 'rake/clean'
2014-04-06 10:10:11 +02:00
require 'csv' # to export BOM and costs
require 'open-uri' # to parse URLs
require 'nokogiri' # to scrape sites
require 'net/http' # to ask octopart
require 'json' # to parse octopart reponses
2014-03-02 18:40:00 +01:00
# =================
# project variables
# =================
2014-03-26 11:49:19 +01:00
# main names used for filenames
2014-04-06 10:10:11 +02:00
raise " define project name(s) in 'name' file " unless File . exist? " name "
2014-03-26 11:49:19 +01:00
names = IO . read ( " name " ) . split ( " \n " ) . select { | target | ! target . empty? }
raise " define project name(s) in 'name' file " if names . empty?
2014-03-02 18:40:00 +01:00
# project version, read from "version" file
2014-04-06 10:10:11 +02:00
raise " define project name(s) in 'name' file " unless File . exist? " name "
2014-03-02 18:40:00 +01:00
version = IO . read ( " version " ) . split ( " \n " ) [ 0 ]
raise " define project version in 'version' file " unless version
# current date for stamping output
date = Time . now . strftime ( " %Y-%m-%d " )
2014-03-26 11:49:19 +01:00
# create targets for each name
targets = [ ]
names . each do | name |
# schema
sch = " #{ name } .sch "
# pcb layout
pcb = " #{ name } .pcb "
# schematic revision, based on the number of schematic commits
sch_rev = ` git log --pretty=oneline " #{ sch } " | wc -l ` . chomp . to_i
# pcb layout revision, based on the number of pcb commits
2014-03-26 11:51:10 +01:00
pcb_rev = ` git log --pretty=oneline " #{ pcb } " | wc -l ` . chomp . to_i
2014-03-26 11:49:19 +01:00
# schema name with version and revition
vsch = " #{ name } _v #{ version } . #{ sch_rev . to_s . rjust ( 3 , '0' ) } .sch "
# pcb layout name with version and revition
vpcb = " #{ name } _v #{ version } . #{ pcb_rev . to_s . rjust ( 3 , '0' ) } .pcb "
# add to targets
targets << { name : name , sch : sch , pcb : pcb , sch_rev : sch_rev , pcb_rev : pcb_rev , vsch : vsch , vpcb : vpcb }
end
2014-03-02 18:40:00 +01:00
# ==========
# main tasks
# ==========
desc " main building task "
2014-04-02 18:20:28 +02:00
task :default = > [ :version , :print , :notes , :bom , :gerber ]
2014-03-02 18:40:00 +01:00
desc " create release file "
2014-03-26 12:08:17 +01:00
release = " hardware-release_v #{ version } .tar.gz "
2014-04-02 18:20:28 +02:00
task :release = > [ :default , :photo , release ]
2014-03-26 12:45:42 +01:00
CLOBBER . include ( release )
2014-03-02 18:40:00 +01:00
desc " set version in schematic and layout "
2014-03-26 12:31:17 +01:00
versions = targets . collect { | target | [ target [ :vsch ] , target [ :vpcb ] ] } . flatten
task :version = > versions
2014-03-26 12:45:42 +01:00
CLEAN . include ( versions )
2014-03-26 11:49:19 +01:00
targets . each do | target |
2014-03-26 12:45:42 +01:00
CLOBBER . include ( " #{ target [ :name ] } _*.sch " )
CLOBBER . include ( " #{ target [ :name ] } _*.pcb " )
2014-03-26 11:49:19 +01:00
end
2014-03-26 12:23:15 +01:00
2014-03-02 18:40:00 +01:00
desc " print schematic and layout (as pdf) "
2014-03-26 12:31:17 +01:00
prints = targets . collect { | target | [ " #{ target [ :name ] } _schematic.pdf " , " #{ target [ :name ] } _layout.pdf " ] } . flatten
task :print = > prints
2014-03-26 12:45:42 +01:00
CLEAN . include ( prints )
2014-03-02 18:40:00 +01:00
desc " export notes from schematic "
2014-03-26 12:31:17 +01:00
notes = targets . collect { | target | " #{ target [ :name ] } _notes.txt " }
task :notes = > notes
2014-03-26 12:45:42 +01:00
CLEAN . include ( notes )
2014-03-02 18:40:00 +01:00
2014-04-02 18:20:28 +02:00
desc " export BOMs from schematic "
boms = targets . collect { | target | " #{ target [ :name ] } _bom.csv " }
task :bom = > boms
CLEAN . include ( boms )
2014-04-06 10:10:11 +02:00
desc " get cost estimation for the BOMs "
costs = targets . collect { | target | " #{ target [ :name ] } _cost.csv " }
task :cost = > costs
CLEAN . include ( costs )
2014-03-02 18:40:00 +01:00
desc " convert schematic to pcb layout "
2014-03-26 13:37:57 +01:00
task :sch2pcb do
targets . each do | target |
2014-03-27 14:15:27 +01:00
sh " gsch2pcb #{ target [ :sch ] } --elements-dir #{ File . dirname ( __FILE__ ) } /lib/footprints --skip-m4 --output-name #{ target [ :name ] } "
2014-03-26 13:37:57 +01:00
end
2014-03-02 18:40:00 +01:00
end
2014-04-02 17:04:31 +02:00
targets . each do | target |
CLOBBER . include ( " #{ target [ :name ] } .net " )
CLOBBER . include ( " #{ target [ :name ] } .cmd " )
CLOBBER . include ( " #{ target [ :name ] } .new.pcb " )
end
2014-03-02 18:40:00 +01:00
2014-03-26 12:45:42 +01:00
photos = targets . collect { | target | [ " #{ target [ :name ] } _layout-top.png " , " #{ target [ :name ] } _layout-bottom.png " ] } . flatten
2014-03-02 18:40:00 +01:00
desc " render layout "
2014-03-26 12:45:42 +01:00
task :photo = > photos
CLOBBER . include ( photos )
2014-03-02 18:40:00 +01:00
desc " export gerber "
2014-03-26 16:08:13 +01:00
task :gerber = > :version do
2014-03-26 13:34:53 +01:00
targets . each do | target |
2014-03-26 16:08:13 +01:00
export = true # export only if the gerbers are all older than the layout
Dir . foreach ( " . " ) do | file |
next unless file . start_with? target [ :name ]
next unless file . end_with? " .gbr " or file . end_with? " .cnc "
export & = ( File . ctime ( target [ :vpcb ] ) > File . ctime ( file ) )
end
sh " pcb -x gerber --gerberfile #{ target [ :name ] } --all-layers #{ target [ :vpcb ] } " if export
2014-03-26 13:34:53 +01:00
end
end
CLOBBER . include ( " *.gbr " )
CLOBBER . include ( " *.cnc " )
2014-03-02 18:40:00 +01:00
desc " reformat gerber and drill output (some programs like LPKF CircuitPro have difficulties with gEDA pcb output) "
2014-03-26 13:34:53 +01:00
task :reformat do
Dir . foreach ( " . " ) do | file |
next unless File . file? file
if file . end_with? " .gbr " then
sh " gerbv --export=rs274x --output= #{ file } #{ file } "
elsif file . end_with? " .cnc " then
sh " gerbv --export=drill --output= #{ file } #{ file } "
2014-03-02 18:40:00 +01:00
end
end
end
# ================
# helper functions
# ================
# generate gnetlist bom2 and parse them
2014-03-27 14:37:05 +01:00
# arguments: schematic=schematic to use, attributes=the attributes to use for generating bom2
2014-04-02 17:03:20 +02:00
# returns an array of hash. key is the attribute name, value is the attribute value
2014-03-02 18:40:00 +01:00
def bom2 ( schematic , attributes )
to_return = [ ]
# force attributes to be an array
2014-04-02 18:20:28 +02:00
attributes = case attributes
2014-03-02 18:40:00 +01:00
when String
[ attributes ]
when Array
attributes
else
[ attributes . to_s ]
end
# generate bom2
2014-04-02 17:03:20 +02:00
list = ` gnetlist -g bom2 -Oattribs= #{ attributes * ',' } -q -o - #{ schematic } `
2014-04-02 18:20:28 +02:00
list . encode! ( " UTF-8 " , " ISO-8859-1 " )
list . gsub! ( / ( \ d[Mkmµ]?) \ ? / , '\1Ω' )
2014-03-02 18:40:00 +01:00
# parse bom2
2014-04-02 18:20:28 +02:00
csv = CSV . parse ( list , { :col_sep = > " : " } )
2014-04-02 17:03:20 +02:00
csv [ 1 .. - 1 ] . each do | row |
line = { }
2014-04-02 17:14:05 +02:00
row . each_index do | col |
2014-04-02 17:03:20 +02:00
line [ csv [ 0 ] [ col ] ] = row [ col ] unless row [ col ] == " unknown "
2014-03-02 18:40:00 +01:00
end
2014-04-02 17:03:20 +02:00
to_return << line
2014-03-02 18:40:00 +01:00
end
2014-04-02 17:14:05 +02:00
return to_return
2014-03-02 18:40:00 +01:00
end
2014-04-06 10:10:11 +02:00
# return actual USD $ to EUR € rate
def usd2eur_rate
unless $u2e then
rate_http = Net :: HTTP . get_response ( URI . parse ( " https://rate-exchange.appspot.com/currency?from=USD&to=EUR " ) )
rate_json = JSON . parse ( rate_http . body )
$u2e = rate_json [ " rate " ] . to_f
end
return $u2e
end
# return part price
def octopart ( seller , sku )
seller = { 'digikey-id' = > " Digi-Key " , 'farnell-id' = > " Farnell " , 'mouser-id' = > " Mouser " } [ seller ]
return nil unless seller
to_return = { stock : nil , currency : nil , prices : [ ] }
# octopart API key to get cost estimations
unless $octopart_api_key then
raise " provide octopart API key in 'octopart' file to get cost estimations " unless File . exist? " octopart "
key = IO . read ( " octopart " ) . lines [ 0 ]
raise " provide octopart API key in 'octopart' file to get cost estimations " if key . empty?
$octopart_api_key = key
end
# query octopart
query = [ { :seller = > seller , :sku = > sku } ]
url = 'http://octopart.com/api/v3/parts/match?'
url += 'queries=' + URI . encode ( JSON . generate ( query ) )
url += '&apikey=' + $octopart_api_key
resp = Net :: HTTP . get_response ( URI . parse ( url ) )
octo_info = JSON . parse ( resp . body )
# get the right response
octo_info [ 'results' ] . each do | result |
result [ 'items' ] . each do | item |
item [ 'offers' ] . each do | offer |
next unless offer [ 'seller' ] [ 'name' ] == seller
next unless offer [ 'sku' ] == sku
to_return [ :stock ] = offer [ 'in_stock_quantity' ]
offer [ 'prices' ] . each do | currency , prices |
next unless currency == " USD " or currency == " EUR "
next if to_return [ :currency ] == " EUR "
to_return [ :currency ] = currency
prices . each do | price |
price [ 1 ] = price [ 1 ] . to_f
end
to_return [ :prices ] = prices
end
end
end
end
return to_return
end
def scrape_digikey ( sku )
to_return = { stock : nil , currency : " EUR " , prices : [ ] }
# get page
url = " http://www.digikey.de/product-detail/en/all/ #{ sku } / "
doc = Nokogiri :: HTML ( open ( URI . escape ( url ) ) )
# get stock
stock_doc = doc . xpath ( '//td[@id="quantityavailable"]' ) [ 0 ]
to_return [ :stock ] = stock_doc . text . gsub ( / [ ,]+ / , " " ) . scan ( / \ d+ / ) [ 0 ] . to_i
# get prices
doc . xpath ( '//table[@id="pricing"]/tr' ) . each do | row |
next unless ( col = row . xpath ( 'td' ) ) . size == 3
2014-04-06 10:51:35 +02:00
qty = col [ 0 ] . text . gsub ( / [^ \ d]+ / , " " )
qty = ( qty =~ / ^ \ d+$ / ? qty . to_i : nil )
price = col [ 1 ] . text . gsub ( / [^ \ d \ .]+ / , " " )
price = ( price =~ / ^ \ d+( \ . \ d+)?$ / ? price . to_f : nil )
to_return [ :prices ] << [ qty , price ] if qty and price
2014-04-06 10:10:11 +02:00
end
return to_return
end
def scrape_farnell ( sku )
to_return = { stock : nil , currency : " EUR " , prices : [ ] }
# get page
url = " http://de.farnell.com/ #{ sku } "
doc = Nokogiri :: HTML ( open ( URI . escape ( url ) ) )
# get stock
stock_doc = doc . xpath ( '//td[@class="prodDetailAvailability"]' ) [ 0 ]
if stock_doc then
to_return [ :stock ] = stock_doc . text . lines [ - 1 ] . to_i
else # when several stocks are available
stock_doc = doc . xpath ( '//div[@class="stockDetail"]' ) [ 0 ]
to_return [ :stock ] = stock_doc . text . gsub ( " . " , " " ) . scan ( / \ d+ / ) [ - 1 ] . to_i # the last match should be for EU
end
# get prices
doc . xpath ( '//div[@class="price"]/*/tr' ) . each do | row |
next unless row . xpath ( 'td' ) . size == 2
2014-04-06 10:51:35 +02:00
qty = row . xpath ( 'td' ) [ 0 ] . text . split ( " - " ) [ 0 ] . gsub ( / [^ \ d]+ / , " " )
qty = ( qty =~ / ^ \ d+$ / ? qty . to_i : nil )
price = row . xpath ( 'td' ) [ 1 ] . text . gsub ( " , " , " . " ) . gsub ( / [^ \ d \ .]+ / , " " )
price = ( price =~ / ^ \ d+( \ . \ d+)?$ / ? price . to_f : nil )
to_return [ :prices ] << [ qty , price ] if qty and price
2014-04-06 10:10:11 +02:00
end
return to_return
end
def scrape_mouser ( sku )
to_return = { stock : nil , currency : " EUR " , prices : [ ] }
# get page
url = " http://de.mouser.com/Search/ProductDetail.aspx?R=0virtualkey0virtualkey #{ sku } "
doc = Nokogiri :: HTML ( open ( URI . escape ( url ) ) )
# get stock
stock_doc = doc . xpath ( '//table[contains(@id,"availability")]/tr/td' ) [ 0 ]
to_return [ :stock ] = stock_doc . text . gsub ( " . " , " " ) . to_i
# get prices
doc . xpath ( '//table[@class="PriceBreaks"]/tr' ) . each do | row |
qty_doc = row . xpath ( 'td[@class="PriceBreakQuantity"]' )
qty = qty_doc [ 0 ] . text . gsub ( / [ \ s: \ .]+ / , " " ) . to_i unless qty_doc . empty?
price_doc = row . xpath ( 'td[@class="PriceBreakPrice"]' )
price = price_doc [ 0 ] . text . gsub ( / \ s+ / , " " ) . gsub ( " € " , " " ) . gsub ( " , " , " . " ) . to_f unless price_doc . empty?
price = nil if price == 0
to_return [ :prices ] << [ qty , price ] if qty and price
end
return to_return
end
def scrape_prices ( seller , sku )
return case seller
when 'digikey-id'
scrape_digikey ( sku )
when 'farnell-id'
scrape_farnell ( sku )
when 'mouser-id'
scrape_mouser ( sku )
else
nil
end
end
2014-03-02 18:40:00 +01:00
# ===============
# file generation
# ===============
desc " copy schematic to version it: include version, revision, and date "
2014-03-26 11:54:06 +01:00
targets . each do | target |
2014-03-26 11:55:21 +01:00
file target [ :vsch ] = > target [ :sch ] do | t |
2014-04-06 12:23:25 +02:00
# embed symbols
2014-03-26 11:49:19 +01:00
sh " cp #{ t . prerequisites . join ( ' ' ) } #{ t . name } "
2014-04-06 12:23:25 +02:00
sh " gschlas -e #{ t . name } "
2014-03-26 11:49:19 +01:00
# on \ is to prevent ruby interpreting it, th other is for sed
# the version
sh " sed -i 's/ \\ (version= \\ ) \\ $Version \\ $/ \\ 1 #{ version } /' #{ t . name } "
# the date
sh " sed -i 's/ \\ (date= \\ ) \\ $Date \\ $/ \\ 1 #{ date } /' #{ t . name } "
# the revision
2014-03-26 12:23:15 +01:00
sh " sed -i 's/ \\ (revision= \\ ) \\ $Revision \\ $/ \\ 1 #{ target [ :sch_rev ] } /' #{ t . name } "
2014-03-26 11:49:19 +01:00
end
2014-03-02 18:40:00 +01:00
end
2014-03-26 11:54:46 +01:00
2014-03-02 18:40:00 +01:00
desc " copy layout to version it: include version, date, and run teardrops when available "
2014-03-26 11:54:46 +01:00
targets . each do | target |
2014-03-26 11:55:21 +01:00
file target [ :vpcb ] = > target [ :pcb ] do | t |
2014-03-26 11:49:19 +01:00
sh " cp #{ t . prerequisites . join ( ' ' ) } #{ t . name } "
# on \ is to prevent ruby interpreting it, th other is for sed
# the version and revision
2014-03-26 11:58:17 +01:00
version_revision = " v #{ version } . #{ target [ :pcb_rev ] . to_s . rjust ( 3 , '0' ) } "
2014-03-26 11:49:19 +01:00
sh " sed -i 's/ \\ $version \\ $/ #{ version_revision } /' #{ t . name } "
# the date
sh " sed -i 's/ \\ $date \\ $/ #{ date } /' #{ t . name } "
# run teardrop for vias and pins
if File . exist? " #{ Dir . home } /.pcb/plugins/teardrops.so " then
sh " pcb --action-string \" djopt(splitlines) Teardrops() s() q() \" #{ t . name } "
end
2014-03-02 18:40:00 +01:00
end
end
2014-03-26 12:23:15 +01:00
2014-03-02 18:40:00 +01:00
desc " generate printable version (PDF) of schematic "
2014-03-26 12:23:15 +01:00
targets . each do | target |
file " #{ target [ :name ] } _schematic.pdf " = > target [ :vsch ] do | t |
sh " gaf export -f pdf -c -o #{ t . name } #{ t . prerequisites . join ( ' ' ) } 2> /dev/null "
end
2014-03-02 18:40:00 +01:00
end
desc " generate printable documentation (PDF) from layout "
2014-03-26 12:23:15 +01:00
targets . each do | target |
file " #{ target [ :name ] } _layout.pdf " = > target [ :vpcb ] do | t |
sh " pcb -x ps --psfile #{ t . name } .ps #{ t . prerequisites . join ( ' ' ) } 2> /dev/null "
sh " ps2pdf #{ t . name } .ps #{ t . name } 2> /dev/null "
sh " rm #{ t . name } .ps 2> /dev/null "
end
2014-03-02 18:40:00 +01:00
end
desc " generate note file from schematic, listing the 'note' attributes from elements "
2014-03-26 12:31:17 +01:00
targets . each do | target |
file " #{ target [ :name ] } _notes.txt " = > target [ :vsch ] do | t |
notes_data = bom2 ( t . prerequisites [ 0 ] , " note " )
File . open ( t . name , " w " ) do | notes_file |
notes_data . each do | note |
2014-04-02 17:03:20 +02:00
next unless note [ 'note' ]
notes_file . puts " #{ note [ 'refdes' ] } : \n #{ note [ 'note' ] } \n \n "
2014-03-26 12:31:17 +01:00
end
2014-03-02 18:40:00 +01:00
end
end
end
2014-04-02 18:20:28 +02:00
desc " generate BOM file from schematic "
targets . each do | target |
2014-04-06 10:10:11 +02:00
file " #{ target [ :name ] } _bom.csv " = > target [ :sch ] do | t |
2014-04-02 18:20:28 +02:00
attributes = [ " category " , " device " , " value " , " description " , " manufacturer " , " manufacturer-id " , " digikey-id " , " farnell-id " , " mouser-id " ]
bom_data = bom2 ( t . prerequisites [ 0 ] , attributes )
CSV . open ( t . name , " wb " ) do | csv |
all_attributes = [ " refdes " , " qty " ] + attributes
csv << all_attributes
bom_data . each do | line |
csv << all_attributes . collect { | attribute | line [ attribute ] }
end
end
end
end
2014-04-06 10:10:11 +02:00
desc " generate cost estimation from schematic "
targets . each do | target |
file " #{ target [ :name ] } _cost.csv " = > target [ :sch ] do | t |
2014-04-06 10:51:35 +02:00
sellers = [ 'digikey-id' , 'farnell-id' , 'mouser-id' ] # provide the (supported) seller SKU as value to this attribute name in the symbols/schematic
boards = [ 1 , 10 ] # calculate the price for as many boards
2014-04-06 11:58:45 +02:00
sum = Array . new ( sellers . size ) { Array . new ( boards . size , 0 . 0 ) } # total cost
stocks = Array . new ( sellers . size ) { Array . new ( boards . size ) { [ ] } } # is there enough stock
2014-04-06 10:10:11 +02:00
# get component information
attributes = [ " manufacturer " , " manufacturer-id " ] + sellers
parts = bom2 ( t . prerequisites [ 0 ] , attributes )
2014-04-06 11:58:45 +02:00
parts . collect! { | part | part [ 'manufacturer' ] and part [ 'manufacturer-id' ] ? part : nil }
parts . compact!
2014-04-06 10:10:11 +02:00
# put result in CVS
CSV . open ( t . name , " wb " ) do | csv |
2014-04-06 10:51:35 +02:00
csv << [ " refdes " , " quantity " , " manufacturer " , " part number " ] + ( sellers . collect { | seller | [ seller , " stock " , " currency " ] + boards . collect { | qty | [ " unit price for #{ qty } board(s) " , " total price for #{ qty } board(s) " ] } } ) . flatten
2014-04-06 10:10:11 +02:00
parts . each do | part |
part [ 'qty' ] = part [ 'qty' ] . to_i
line = [ part [ 'refdes' ] , part [ 'qty' ] , part [ 'manufacturer' ] , part [ 'manufacturer-id' ] ]
2014-04-06 11:58:45 +02:00
sellers . each_index do | i |
seller = sellers [ i ]
2014-04-06 10:10:11 +02:00
if part [ seller ] then
begin
prices = scrape_prices ( seller , part [ seller ] )
rescue
$stderr . puts " #{ part [ 'manufacturer' ] } #{ part [ 'manufacturer-id' ] } not available using #{ seller } #{ part [ seller ] } "
2014-04-06 10:51:35 +02:00
line += [ part [ seller ] ] + [ nil ] * ( 2 + boards . size * 2 )
2014-04-06 10:10:11 +02:00
next
end
line << part [ seller ]
line << prices [ :stock ]
line << prices [ :currency ]
2014-04-06 10:51:35 +02:00
unit = [ ] # the unit price
2014-04-06 11:58:45 +02:00
boards . each_index do | j |
2014-04-06 10:51:35 +02:00
if prices [ :prices ] . empty? then
line += [ nil ] * 2
else
prices [ :prices ] . each do | price |
2014-04-06 11:58:45 +02:00
unit [ j ] = price [ 1 ] if ( ! unit [ j ] or price [ 1 ] < unit [ j ] ) and price [ 0 ] < = part [ 'qty' ] * boards [ j ]
2014-04-06 10:51:35 +02:00
end
2014-04-06 11:58:45 +02:00
if unit [ j ] then
line << unit [ j ]
line << unit [ j ] * part [ 'qty' ] * boards [ j ]
stocks [ i ] [ j ] << true if part [ 'qty' ] * boards [ j ] < = prices [ :stock ]
sum [ i ] [ j ] += unit [ j ] * part [ 'qty' ] * boards [ j ]
2014-04-06 10:51:35 +02:00
else # use the minimum quantity
line << prices [ :prices ] [ 0 ] [ 1 ]
line << prices [ :prices ] [ 0 ] [ 1 ] * prices [ :prices ] [ 0 ] [ 0 ]
2014-04-06 11:58:45 +02:00
stocks [ i ] [ j ] << true
sum [ i ] [ j ] += prices [ :prices ] [ 0 ] [ 1 ] * prices [ :prices ] [ 0 ] [ 0 ]
2014-04-06 10:51:35 +02:00
end
end
2014-04-06 10:10:11 +02:00
end
else
2014-04-06 10:51:35 +02:00
line += [ nil ] * ( 3 + boards . size * 2 )
2014-04-06 10:10:11 +02:00
end
end
csv << line
end
2014-04-06 11:58:45 +02:00
# summary
line = [ nil ] * 4
sellers . each_index do | i |
line += [ nil , nil , nil ]
boards . each_index do | j |
line << ( stocks [ i ] [ j ] . size == parts . size ? " " : " not " ) + " enough stock "
line << sum [ i ] [ j ]
end
end
csv << line
2014-04-06 10:10:11 +02:00
end
end
end
2014-03-02 18:40:00 +01:00
desc " generate photo realistic picture from layout (front side) "
2014-03-26 12:45:42 +01:00
targets . each do | target |
file " #{ target [ :name ] } _layout-top.png " = > target [ :vpcb ] do | t |
sh " pcb -x png --dpi 600 --format PNG --photo-mode --outfile #{ t . name } #{ t . prerequisites . join ( ' ' ) } "
end
2014-03-02 18:40:00 +01:00
end
desc " generate photo realistic picture from layout (bottom side) "
2014-03-26 12:45:42 +01:00
targets . each do | target |
file " #{ target [ :name ] } _layout-bottom.png " = > target [ :vpcb ] do | t |
sh " pcb -x png --dpi 600 --format PNG --photo-mode --photo-flip-x --outfile #{ t . name } #{ t . prerequisites . join ( ' ' ) } "
end
2014-03-02 18:40:00 +01:00
end
desc " create archive with release files "
2014-03-26 13:34:53 +01:00
SOURCES = targets . collect { | target | [ target [ :sch ] , target [ :pcb ] ] } . flatten
2014-03-26 13:04:14 +01:00
ATTACHMENTS = [ " cern_ohl_v_1_2_howto.pdf " , " CHANGES.txt " , " LICENSE.txt " , " PRODUCT.txt " ]
2014-04-02 18:20:28 +02:00
file release = > SOURCES + prints + notes + boms + photos + ATTACHMENTS do | t |
2014-03-26 13:34:53 +01:00
gerbers = Dir . entries ( " . " ) . select { | file | file . end_with? " .gbr " or file . end_with? " .cnc " }
sh " tar -acf ' #{ t . name } ' #{ ( t . prerequisites + gerbers ) . join ( ' ' ) } "
2014-03-02 18:40:00 +01:00
end