Module: PackShoes

Defined in:
lib/shoes/packshoes.rb,
lib/package/merge-exe.rb,
lib/package/merge-fpm.rb,
lib/package/merge-osx.rb

Class Method Summary collapse

Class Method Details

.custom_installer(opts) ⇒ Object



591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
# File 'lib/shoes/packshoes.rb', line 591

def PackShoes.custom_installer opts
  defshy = opts['app']
  if opts['advopts'] != true
      return defshy
  end
  #opts.each {|k, v| puts "#{k} => #{v}"}
  if ! defshy[/\.shy$/] then
      raise "Must be a shy"
  end
  appname = File.basename(defshy,".shy")
  shydir = File.dirname(defshy)
  tmp_dir = File.join(opts['packtmp'], "+shy", appname)
  FileUtils.rm_rf(tmp_dir)
  FileUtils.mkdir_p(tmp_dir)

  FileUtils.cp(defshy, tmp_dir)
  if opts['custominstaller'] 
    # user knows best!
    FileUtils.cp opts['custominstaller'], File.join(tmp_dir, "#{appname}-install.rb")
  else
    # default custom installer - copy app-install.tmpl with rewrite
    File.open(File.join(tmp_dir, "#{appname}-install.rb"), 'wb') do |a|
     rewrite a, File.join(DIR, "static", "stubs", "app-install.tmpl"),
       'SHYFILE' => "#{defshy}"
    end
  end
  FileUtils.cp(opts['installer-icon'], File.join(tmp_dir, "installer-icon.png"))
  FileUtils.cp(opts['png'], File.join(tmp_dir,"#{appname}.png")) if opts['png']
  FileUtils.cp(opts['ico'], File.join(tmp_dir,"#{appname}.ico")) if opts['ico']
  FileUtils.cp(opts['icns'], File.join(tmp_dir,"#{appname}.icns")) if opts['icns']
  # Copy gemspack 
  if opts['gempack'] 
    puts "Copy gempack"
    FileUtils.cp(opts['gempack'], File.join(tmp_dir, 'gempack.tgz'))
  end
  # make a yaml to pass options the installer might need (expandshy for one)
  File.open(File.join(tmp_dir,"#{appname}.yaml"),'w') {|f| YAML.dump(opts, f)}
  # Create a shy header for the installer.
  shy_desc = Shy.new
  shy_desc.launch = "#{appname}-install.rb"
  shy_desc.name = appname
  shy_desc.version = "1.0"
  shy_desc.creator = "Shoes"
  # Create the new shy. Grrr -- read shy.rb
  new_shypath = File.join(opts['packtmp'], '+shy')
  Dir.chdir(new_shypath) do
    Shy.c(appname+'.shy', shy_desc, tmp_dir)
  end
  #puts "New: #{new_shypath}\n and #{defshy}"
  # write over the incoming shy with the new one - Bad Idea. Bad Cecil!
  #FileUtils.cp File.join(new_shypath,"#{appname}.shy"), defshy
  FileUtils.cp File.join(new_shypath,"#{appname}.shy"), File.join(shydir,"#{appname}-custom.shy")
  # delete the +shy temp stuff
  #return defshy
  return File.join(shydir,"#{appname}-custom.shy")
end

.dnlif_exe(opts) ⇒ Object

—– Windows —–



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/shoes/packshoes.rb', line 20

def PackShoes.dnlif_exe opts
  script = custom_installer opts
  #puts "win script = #{script}"
  size = File.size(script)
  f = File.open(script, 'rb')
  inf = File.join(DIR, "static", "stubs", 'shoes-stub.exe')
  exe = Winject::EXE.new(inf)
  exe.inject_string(Winject::EXE::SHOES_APP_NAME, File.basename(script))
  exe.inject_file(Winject::EXE::SHOES_APP_CONTENT, f.read)
  exe.inject_string(Winject::EXE::SHOES_DOWNLOAD_SITE, opts['dnlhost'])
  exe.inject_string(Winject::EXE::SHOES_DOWNLOAD_PATH, opts['dnlpath'])
  if opts['winargs']
    puts "injecting #{opts['winargs']}"
    exe.inject_string(Winject::EXE::SHOES_USE_ARGS, opts['winargs'])
  end
  if opts['ico']
    exe.inject_icons(opts['ico'])
  end
  exe.save(script.gsub(/\.\w+$/, '') + ".exe") 
  f.close
end

.dnlif_linux(opts) ⇒ Object

—— Linux ——



74
75
76
77
78
79
80
81
82
83
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
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/shoes/packshoes.rb', line 74

def PackShoes.dnlif_linux opts
  arch = opts['arch']
  script = custom_installer opts
  name = File.basename(script).gsub(/\.\w+$/, '')
  app_name = name.capitalize.gsub(/[-_](\w)/) { $1.capitalize }
  run_path = script.gsub(/\.\w+$/, '') + "-#{arch}.run"
  tgz_path = script.gsub(/\.\w+$/, '') + "-#{arch}.tgz"
  tar_path = script.gsub(/\.\w+$/, '') + "-#{arch}.tar"
  tmp_dir = File.join(opts['packtmp'], "+run")
  FileUtils.mkdir_p(tmp_dir)
  # rewrite the static/stubs/sh-install.tmpl to point to the download
  # website, path and script/shy
  File.open(File.join(tmp_dir, "sh-install"), 'wb') do |a|
 rewrite a, File.join(DIR, "static", "stubs", "sh-install.tmpl"),
   'HOST' => opts['dnlhost'], 'ARCH' => arch, 
   'PATH' => opts['dnlpath'],
   'RELNAME' => opts['relname'],
   'SCRIPT' => "#{File.basename(script)}"
  end
  FileUtils.cp(script, File.join(tmp_dir, File.basename(script)))
  # add sh-install and script to the modes list
  @tarmodes = {}
  @tarmodes[File.basename(script)] = "0755".oct
  @tarmodes['sh-install'] = "0755".oct
  raw = Shy.du(tmp_dir)
 
  # create a tgz of tmp_dir
  # Create tar file with correct modes (he hopes)
  File.open(tar_path,'wb') do |tf|
    tb = fastcf(tf, tmp_dir, @tarmodes)
  end
  # compress tar file 
  File.open(tgz_path,'wb') do |tgz|
    z = Zlib::GzipWriter.new(tgz)
    File.open(tar_path,'rb') do |tb|
      z.write tb.read
    end
    z.close
  end
  FileUtils.rm tar_path
  
  md5, fsize = Shy.md5sum(tgz_path), File.size(tgz_path)
  File.open(run_path, 'wb') do |f|
 rewrite f, File.join(DIR, "static", "stubs", "blank.run"),
  'CRC' => '0000000000', 'MD5' => md5, 'LABEL' => app_name, 'NAME' => name,
  'SIZE' => fsize, 'RAWSIZE' => (raw / 1024) + 1, 'TIME' => Time.now, 'FULLSIZE' => raw
    File.open(tgz_path, 'rb') do |f2|
    f.write f2.read(8192) until f2.eof
 end
  end
  FileUtils.chmod 0755, run_path
  FileUtils.rm_rf(tgz_path)
  FileUtils.rm_rf(tmp_dir)
 
end

.dnlif_osx(opts) ⇒ Object

—— OSX —–



216
217
218
219
220
221
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
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
356
357
358
359
360
361
362
363
364
# File 'lib/shoes/packshoes.rb', line 216

def PackShoes.dnlif_osx opts
   script = custom_installer opts
   name = File.basename(script).gsub(/\.\w+$/, '')
   app_name = name.capitalize.gsub(/[-_](\w)/) { $1.capitalize }
   #vol_name = name.capitalize.gsub(/[-_](\w)/) { " " + $1.capitalize }
   tar_path = script.gsub(/\.\w+$/, '') + "-osx.tar"
   tgz_path = script.gsub(/\.\w+$/, '') + "-osx.tgz"
   app_app = "#{app_name}.app"
   vers = [2, 0]

   tmp_dir = File.join(opts['packtmp'], "+dmg")
   FileUtils.rm_rf(tmp_dir)
   FileUtils.mkdir_p(tmp_dir)
   # deal with custom icons. Brutish
   icon_path = ''
   if opts['advopts'] && opts['icns'] 
     icon_path = opts['icns']
   else
     # use Shoes
     icon_path = File.join(DIR, "static", "Shoes.icns")
   end
   icon_name = File.basename(icon_path)
    
   @tarmodes = {}

   app_dir = File.join(tmp_dir, app_app)

   res_dir = File.join(tmp_dir, app_app, "Contents", "Resources")
   mac_dir = File.join(tmp_dir, app_app, "Contents", "MacOS")
   [res_dir, mac_dir].map { |x| FileUtils.mkdir_p(x) }
   #FileUtils.cp(File.join(DIR, "static", "Shoes.icns"), app_dir)
   #FileUtils.cp(File.join(DIR, "static", "Shoes.icns"), res_dir)
   FileUtils.cp(icon_path, app_dir)
   FileUtils.cp(icon_path, res_dir)
   # make cache entries for the files above to keep the console quiet
   #@tarmodes["#{app_app}/Contents/Resources/Shoes.icns"] = 0644
   #@tarmodes["#{app_app}/Shoes.icns"] = 0644
   @tarmodes["#{app_app}/Contents/Resources/#{icon_name}"] = 0644
   @tarmodes["#{app_app}/#{icon_name}"] = 0644
   # more permissions cache entries 
   ["#{app_app}", "#{app_app}/Contents", "#{app_app}/Contents/Resources",
    "#{app_app}/Contents/MacOS" ].each {|d| @tarmodes[d] = 0755}
   ["#{app_app}/Contents/PkgInfo", "#{app_app}/Contents/version.plist",
    "#{app_app}/Contents/Info.plist" ].each {|f| @tarmodes[f] = 0644}
   File.open(File.join(app_dir, "Contents", "PkgInfo"), 'w') do |f|
     f << "APPL????"
   end
   # info.plist with substitutions
   #@dnlsel = '/public/select/osx.rb'
   File.open(File.join(app_dir, "Contents", "Info.plist"), 'w') do |f|
     f << <<END
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>CFBundleGetInfoString</key>
 <string>#{app_name} #{vers.join(".")}</string>
 <key>CFBundleExecutable</key>
 <string>osx-app</string>
 <key>CFBundleIdentifier</key>
 <string>org.hackety.#{name}</string>
 <key>CFBundleName</key>
 <string>#{app_name}</string>
 <key>CFBundleIconFile</key>
 <string>#{icon_name}</string>
 <key>CFBundleShortVersionString</key>
 <string>#{vers.join(".")}</string>
 <key>CFBundleInfoDictionaryVersion</key>
 <string>6.0</string>
 <key>CFBundlePackageType</key>
 <string>APPL</string>
 <key>IFMajorVersion</key>
 <integer>#{vers[0]}</integer>
 <key>IFMinorVersion</key>
 <integer>#{vers[1]}</integer>
</dict>
</plist>
END
   end
   File.open(File.join(app_dir, "Contents", "version.plist"), 'w') do |f|
     f << <<END
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>BuildVersion</key>
 <string>1</string>
 <key>CFBundleVersion</key>
 <string>#{vers.join(".")}</string>
 <key>ProjectName</key>
 <string>#{app_name}</string>
 <key>SourceVersion</key>
 <string>#{Time.now.strftime("%Y%m%d")}</string>
</dict>
</plist>
END
   end
   File.open(File.join(mac_dir, "#{name}-launch"), 'wb') do |f|
     f << <<END
#!/bin/bash
APPPATH="${0%/*}"
this_dir=$APPPATH
unset DYLD_LIBRARY_PATH
APPPATH=/Applications/Shoes.app/Contents/MacOS
cd "$APPPATH"
#echo "[Pango]" > pangorc
#echo "ModuleFiles=$APPPATH/pango.modules" >> pangorc
#echo "ModulesPath=$APPPATH/pango/modules" >> pangorc
#PANGO_RC_FILE="$APPPATH/pangorc" ./pango-querymodules > pango.modules
#DYLD_LIBRARY_PATH="$APPPATH" SHOES_RUBY_ARCH="#{opts['shoesruby']}" ./shoes-bin "$this_dir/#{File.basename(script)}"
open -a /Applications/Shoes.app "$this_dir/#{File.basename(script)}"
END
   end
   ls = File.join(mac_dir, "#{name}-launch")
   FileUtils.chmod 0755, ls
   @tarmodes["#{app_app}/Contents/MacOS/#{name}-launch"] = 0755
   FileUtils.cp(script, File.join(mac_dir, File.basename(script)))
   @tarmodes["#{app_app}/Contents/MacOS/#{File.basename(script)}"] = 0644
   # copy the downloader 
   FileUtils.cp(File.join(DIR, "static", "stubs", "shoes-osx-install"),
     File.join(mac_dir, "shoes-osx-install"))
   @tarmodes["#{app_app}/Contents/MacOS/shoes-osx-install"] = 0755
   
   # make the 1st script to run (installs shoes if needed, runs Shoes
   File.open(File.join("#{mac_dir}", "osx-app"), 'wb') do |a|
  rewrite a, File.join(DIR, "static", "stubs", "osx-app-install.tmpl"),
    'HOST' => "http://#{opts['dnlhost']}", 'ARCH' => opts['arch'], 
    'PATH' => opts['dnlpath'],
    'RELNAME' => opts['relname'],
    'SCRIPT' => "#{name}-launch"
   end
   @tarmodes["#{app_app}/Contents/MacOS/osx-app"] = 0755
   
   #Create tar file with correct modes (he hopes)
   File.open(tar_path,'wb') do |tf|
     tb = fastcf(tf, tmp_dir, @tarmodes)
   end
   # compress tar file 
   File.open(tgz_path,'wb') do |tgz|
     z = Zlib::GzipWriter.new(tgz)
     File.open(tar_path,'rb') do |tb|
       z.write tb.read
     end
     z.close
   end
#    FileUtils.rm_rf(tmp_dir)
   FileUtils.rm_rf(tar_path)
   #@pkgstat = inscription "Done packaging #{$script_path} for OSX"
end

.fastcf(outf, indir, modes) ⇒ Object



565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
# File 'lib/shoes/packshoes.rb', line 565

def PackShoes.fastcf outf, indir, modes
  begin
   Gem::Package::TarWriter.new outf do |tar|
     Dir[File.join(indir, "**/*")].each do |file|
       relative_file = file.sub(/^#{Regexp::escape indir}\/?/, '')
       mode = modes[relative_file] 
       if !mode
         puts "Failed #{relative_file} #{file}"
         mode = File.stat(file).mode
       end
       if File.directory?(file)
         tar.mkdir relative_file, mode
       else
         tar.add_file relative_file, mode do |tf|
           File.open(file, "rb") { |f| tf.write f.read }
         end
       end
     end #Dir
   end # Tarwriter	  
	rescue StandardError => e
 puts "Exception: #{e}"
	end
	outf.rewind
	outf
end

.fastxzf(infile, outdir, modes = {}, osx = '') ⇒ Object



528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
# File 'lib/shoes/packshoes.rb', line 528

def PackShoes.fastxzf infile, outdir, modes = {}, osx = ''
  #from blog post http://dracoater.blogspot.com/2013/10/extracting-files-from-targz-with-ruby.html
  # modified by Cecil Coupe - Jun 27+, 2014. Thanks to Juri Timošin   
  
  tar_longlink = '././@LongLink'

  Gem::Package::TarReader.new( Zlib::GzipReader.open infile ) do |tar|
    dest = nil
    tar.each do |entry|
      if entry.full_name == tar_longlink
        dest = File.join outdir, entry.read.strip
        next
      end
      dest ||= File.join outdir, entry.full_name
      hashname = entry.full_name.gsub('./','')
      hashname.gsub!(/Shoes.app/, osx) if osx
      hashname.chomp!('/')
      #@pkgstat.text = hashname
      modes[hashname] = entry.header.mode
      if entry.directory?
        FileUtils.rm_rf dest unless File.directory? dest
        FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
      elsif entry.file?
        FileUtils.rm_rf dest unless File.file? dest
        File.open dest, "wb" do |f|
          f.print entry.read
        end
        FileUtils.chmod entry.header.mode, dest, :verbose => false
      elsif entry.header.typeflag == '2' #Symlink!
        #puts "Symlink #{entry.header.linkname} Ignore"
        # File.symlink entry.header.linkname, dest
      end
      dest = nil
    end
  end
end

.make_shy(dest_path, in_dir, desc) ⇒ Object

—– create a shy ——



8
9
10
11
12
13
14
15
16
# File 'lib/shoes/packshoes.rb', line 8

def PackShoes.make_shy(dest_path, in_dir, desc)
  #desc is a hash 'name', 'version', 'creator'. 'launch'
  FileUtils.mkdir_p (File.dirname dest_path)
  shy_desc = Shy.new
  for name in desc.keys
    shy_desc.send("#{name}=".intern, desc[name])
  end
  Shy.c(dest_path, shy_desc, in_dir)
end

.merge_exe(opts) {|"Copy Shoes"| ... } ⇒ Object

Yields:



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/package/merge-exe.rb', line 17

def PackShoes.merge_exe opts, &blk
  # setup defaults if not in the opts
 #packdir = 'packdir'
  packdir = "#{opts['packdir']}/#{opts['app_name']}"
  opts['publisher'] = 'shoerb' unless opts['publisher']
  opts['website'] = 'http://shoesrb.com/' unless opts['website']
  opts['hkey_org'] = 'mvmanila.com'
 opts['app_ico'] = "#{DIR}/lib/package/nsis/shoes.ico" unless opts['app_ico']
 opts['app_installer_ico'] = "#{DIR}/lib/package/nsis/shoes.ico" unless opts['app_installer_ico']
 opts['nsis_name'] = opts['installer_header'] ? opts['installer_header'] : opts['app_name']
 opts['app_startmenu'] = opts['app_name'] unless opts['app_startmenu']
 opts['app_version'] = '1'
 incl_gems = opts['include_gems'] || []
 ruby_ver = RUBY_VERSION[/\d.\d/].to_str
	
  toplevel = []
  yield "Copy Shoes" if blk
  Dir.chdir(DIR) { Dir.glob('*') {|f| toplevel << f} }
  exclude = %w(static CHANGELOG.txt cshoes.exe gmon.out README.txt samples tmp)
  rm_rf packdir
  mkdir_p(packdir) # where makensis will find it.
  (toplevel-exclude).each { |p| cp_r File.join(DIR, p), packdir }

  # do the license stuff
  licf = File.open("#{packdir}/COPYING.txt", 'w')
  if opts['license'] && File.exist?(opts['license'])
    IO.foreach(opts['license']) {|ln| licf.puts ln}
  end
  IO.foreach("#{DIR}/COPYING.txt") {|ln| licf.puts ln}
  licf.close
	
  # we need some statics for console to work. 
  mkdir_p "#{packdir}/static"
  Dir.glob("#{DIR}/static/icon*.png") { |p| cp p, "#{packdir}/static" }
  opts['app_png'] ? ( cp "#{opts['app_loc']}/#{opts['app_png']}", "#{packdir}/static/app-icon.png" ) : nil
=begin
  # remove chipmonk and ftsearch unless requested
  exts = opts['include_exts'] || []
  if  !exts || ! exts.include?('ftsearch')
    puts "removing ftsearchrt.so"
    rm_rf "#{packdir}/lib/shoes/help.rb"
    rm_rf "#{packdir}/lib/shoes/search.rb"
  end
  if  !exts || ! exts.include?('chipmunk')
    puts "removing chipmunk"
    rm "#{packdir}/lib/shoes/chipmunk.rb"
  end
=end
  yield "remove uneeded" if blk
  # get rid of some things in lib
  rm_rf "#{packdir}/lib/exerb"
  rm_rf "#{packdir}/lib/package"
  rm_rf "#{packdir}/lib/gtk-2.0" if File.exist? "#{packdir}/lib/gtk-2.0"
  # remove unreachable code in packdir/lib/shoes/ like help, app-package ...
  not_needed = ['cobbler', 'debugger', 'shoes_irb', 'pack', 'app_package', 'packshoes', 'remote_debugger', 'winject', 'envgem']
 not_needed.each {|f| rm "#{packdir}/lib/shoes/#{f}.rb" }
  yield "copy application"
  # copy app contents (file/dir at a time)
  app_contents = Dir.glob("#{opts['app_loc']}/*")
  app_contents.each { |p| cp_r p, packdir }
  #create new lib/shoes.rb with rewrite
  newf = File.open("#{packdir}/lib/shoes.rb", 'w')
  rewrite newf, "#{DIR}/lib/package/min-shoes.rb", {'APP_START' => opts['app_start'] }
  newf.close
  # create a new lib/shoes/log.rb with rewrite
  logf = File.open("#{packdir}/lib/shoes/log.rb", 'w')
  rewrite logf, "#{DIR}/lib/package/min-log.rb", {'CONSOLE_HDR' => "#{opts['app_name']} Errors"}
  logf.close
  yield "process gems" if blk
  # Delete all gems besides the chosen one //dredknight
 sgpath = "#{packdir}/lib/ruby/gems/#{ruby_ver}.0"
 Dir.glob("#{sgpath}/specifications/**/*gemspec").each do |p|
  gem = File.basename(p, '.gemspec')
  if !incl_gems.any? {|g| gem.include?(g) } then
	  puts "Deleting #{gem}"
	  rm_rf "#{sgpath}/specifications/#{gem}.gemspec"
  	rm_rf "#{sgpath}/specifications/default/#{gem}.gemspec"
  	rm_rf "#{sgpath}/extensions/x86-mingw32/#{ruby_ver}.0/#{gem}"
  	rm_rf "#{sgpath}/gems/#{gem}"
  end
    incl_gems.delete(gem)
 end
  yield "User gems" if blk
  # copy requested gems from user's Shoes ~/.shoes/+gem/
  # incl_gems will be empty if there are none
  gloc = "#{ENV['APPDATA'].tr("\\",'/')}/Local/Shoes/+gem/"
  incl_gems.each do |name| 
    next if !File.exist?("#{gloc}/specifications/#{name}.gemspec")
    puts "Copy #{name} from user dir"
    cp "#{gloc}/specifications/#{name}.gemspec", "#{sgpath}/specifications"
    # does the gem have binary?
    built = "#{gloc}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}/gem.build_complete"
    if File.exist? built
      mkdir_p "#{sgpath}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}"
      cp "#{GEMS_DIR}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}/gem.build_complete",
        "#{sgpath}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}"
    end
    cp_r "#{gloc}/gems/#{name}", "#{sgpath}/gems"
  end
  yield "make installer - patience please" if blk
  puts "make_installer"
  #mkdir_p "pkg"
  rm_rf "#{packdir}/nsis"
  cp_r  "#{DIR}/lib/package/nsis", "#{packdir}"
  # Icon for installer
  cp opts['app_installer_ico'], "#{packdir}/nsis/setup.ico"
  # change nsis side bar and top images (bmp only)
  sb_img = opts['installer_sidebar_bmp'] 
  sb_img ? ( cp sb_img, "#{packdir}/nsis/installer-1.bmp" ) : nil
  tp_img = opts['installer_header_bmp']
  tp_img ? ( cp tp_img, "#{packdir}/nsis/installer-2.bmp") : nil
  # stuff icon into a new app_name.exe using shoes.exe 
  Dir.chdir(packdir) do |p|
  winico_path = "#{opts['app_ico'].tr('/','\\')}"
  cmdl = "\"#{opts['RESH']}\" -modify  shoes.exe, \"#{opts['app_name']}.exe\", \"#{winico_path}\", icongroup,32512,1033"
  if system(cmdl)
	  rm 'shoes.exe' if File.exist?("#{opts['app_name']}.exe")
  else
	  puts "FAIL: #{$?} #{cmdl}"
  end
  end
  newn = File.open("#{packdir}/nsis/#{opts['app_name']}.nsi", 'w')
  rewrite newn, "#{packdir}/nsis/base.nsi", {
    'APPNAME' => "#{opts['app_name']}",
    'WINVERSION' => opts['app_version'],
   'STARTMENU_NAME' => opts['app_startmenu'],
    'PUBLISHER' => opts['publisher'],
    'WEBSITE' => opts['website'],
    'HKEY_ORG' => opts['hkey_org'],
   'NSIS_NAME' => "#{opts['nsis_name']}"
    }
  newn.close
  Dir.chdir("#{packdir}/nsis") do |p|
    cmdl = "\"#{opts['NSIS']}\" \"#{opts['app_name']}\".nsi\""
   if system(cmdl)
      Dir.glob('*.exe') { |p| mv p, '../../' }
    else
      puts "FAIL: #{$7} #{cmdl}"
    end
  end
  yield "All Done!" if blk
end

.merge_fpm(opts) {|"Copy Shoes"| ... } ⇒ Object

Yields:



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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
187
188
189
190
191
192
193
194
195
196
197
198
199
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
# File 'lib/package/merge-fpm.rb', line 19

def PackShoes.merge_fpm opts, &blk
  # setup defaults if not in the opts
  #puts opts.inspect
  opts['publisher'] = 'shoerb' unless opts['publisher']
  opts['website'] = 'http://shoesrb.com/' unless opts['website']
  opts['linux_where'] = '/usr/local' unless opts['linux_where']
 rbmm = RUBY_VERSION[/\d.\d/].to_str
  toplevel = []
  Dir.chdir(DIR) do
    Dir.glob('*') {|f| toplevel << f}
  end
  exclude = %w(static CHANGELOG cshoes.exe gmon.out README.md
    samples package VERSION.txt tmp)
  packdir = "#{opts['packdir']}/#{opts['app_name']}" 
  rm_rf packdir
  mkdir_p packdir 
  # copy shoes
  yield "Copy Shoes" if blk
  (toplevel-exclude).each do |p|
    cp_r File.join(DIR, p), packdir
  end
  # do the license stuff
  licf = File.open("#{packdir}/COPYING.txt", 'w')
  if opts['license'] && File.exist?(opts['license'])
    IO.foreach(opts['license']) {|ln| licf.puts ln}
    rm_rf "#{packdir}/#{File.basename(opts['license'])}"
  end
  IO.foreach("#{DIR}/COPYING.txt") {|ln| licf.puts ln}  
  licf.close
  # we do need some statics for console to work. 
  mkdir_p "#{packdir}/static"
  Dir.glob("#{DIR}/static/icon*.png") {|p| cp p, "#{packdir}/static" }
  if opts['app_png']
    cp "#{opts['app_loc']}/#{opts['app_png']}", "#{packdir}/static/app-icon.png"
  end
  # get rid of some things in lib
  rm_rf "#{packdir}/lib/exerb"
  rm_rf "#{packdir}/lib/gtk-2.0" if File.exist? "#{packdir}/lib/gtk-2.0"
  # remove unreachable code in packdir/lib/shoes/ like help, app-package ...
  ['cobbler', 'debugger', 'shoes_irb', 'pack', 'app_package', 'packshoes',
    'remote_debugger', 'winject', 'envgem'].each {|f| rm "#{packdir}/lib/shoes/#{f}.rb" }

  # copy app contents (file/dir at a time)
  yield "Copy #{opts['app_name']}" if blk
  app_contents = Dir.glob("#{opts['app_loc']}/*")
  app_contents.each do |p|
   cp_r p, packdir
  end
  #create new lib/shoes.rb with rewrite
  newf = File.open("#{packdir}/lib/shoes.rb", 'w')
  rewrite newf, "#{DIR}/lib/package/min-shoes.rb", {'APP_START' => opts['app_start'] }
  newf.close
  # create a new lib/shoes/log.rb with rewrite
  logf = File.open("#{packdir}/lib/shoes/log.rb", 'w')
  rewrite logf, "#{DIR}/lib/package/min-log.rb", {'CONSOLE_HDR' => "#{opts['app_name']} Errors"}
  logf.close
  # copy/remove gems - tricksy - pay attention
  # remove the Shoes built-in gems if NOT IN the list 
  yield "Copy gems" if blk
  incl_gems = opts['include_gems']
  rm_gems = []
  Dir.glob("#{packdir}/lib/ruby/gems/#{rbmm}.0/specifications/*gemspec") do |p|
    gem = File.basename(p, '.gemspec')
    if incl_gems.include?(gem)
      puts "Keeping Shoes gem: #{gem}"
      incl_gems.delete(gem)
    else
      rm_gems << gem
    end
  end
  sgpath = "#{packdir}/lib/ruby/gems/#{rbmm}.0"
=begin
  # sqlite is a special case so delete it differently - trickery
  if !incl_gems.include?('sqlite3')
    spec = Dir.glob("#{sgpath}/specifications/sqlite3*.gemspec")
    rm spec[0]
    rm_gems << File.basename(spec[0],'.gemspec')
  else
    incl_gems.delete("sglite3")
  end
=end
  rm_gems.each do |g|
    puts "Deleting #{g}"
    rm_rf "#{sgpath}/specifications/#{g}.gemspec"
    rm_rf "#{sgpath}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{g}"
    rm_rf "#{sgpath}/gems/#{g}"
  end
  yield "User gems" if blk
  # copy requested gems from user's Shoes ~/.shoes/+gem/
  # incl_gems will be empty if there are none
  gloc = "#{ENV['HOME']}/.shoes/+gem/"
  incl_gems.each do |name| 
    puts "Copy #{name} from user dir"
    cp "#{gloc}/specifications/#{name}.gemspec", "#{sgpath}/specifications"
    # does the gem have binary?
    built = "#{gloc}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}/gem.build_complete"
    if File.exist? built
      mkdir_p "#{sgpath}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}"
      cp "#{GEMS_DIR}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}/gem.build_complete",
        "#{sgpath}/extensions/#{RUBY_PLATFORM}/#{rbmm}.0/#{name}"
    end
    cp_r "#{gloc}/gems/#{name}", "#{sgpath}/gems"
  end
      
  # hide shoes-bin and shoes launch script names
  yield "Setup_installer" if blk
  after_install = "#{opts['app_name']}_install.sh"
  before_remove = "#{opts['app_name']}_remove.sh"
  where = opts['linux_where']
  Dir.chdir(packdir) do
    mv 'shoes-bin', "#{opts['app_name']}-bin"
    File.open("#{opts['app_name']}", 'w') do |f|
      f << <<SCR
#!/bin/bash
REALPATH=`readlink -f $0`
APPPATH="${REALPATH%/*}"
if [ "$APPPATH" = "." ]; then
APPPATH=`pwd`
fi
LD_LIBRARY_PATH=$APPPATH $APPPATH/#{opts['app_name']}-bin
SCR
    end
    chmod 0755, "#{opts['app_name']}"
    rm_rf 'shoes'
    rm_rf 'debug'
    rm_rf 'Shoes.desktop.tmpl'
    rm_rf 'Shoes.remove.desktop'
    rm_rf 'Shoes.remove.tmpl'
    rm_rf 'shoes-install.sh'
    rm_rf 'shoes-uninstall.sh'
    rm_rf 'Shoes.desktop'
    # still inside packdir. Make an fpm after-install script and some 
    # xdg .desktops
    if opts['create_menu'] == true
      File.open("#{opts['app_name']}.desktop",'w') do |f|
        f << "[Desktop Entry]\n"
        f << "Name=#{opts['app_name']}\n"
        f << "Exec=#{where}/bin/#{opts['app_name']}\n"
        f << "StartupNotify=true\n"
        f << "Terminal=false\n"
        f << "Type=Application\n"
        f << "Comment=#{opts['purpose']}\n"
        f << "Icon=#{where}/lib/#{opts['app_name']}/#{opts['app_png']}\n"
        f << "Categories=#{opts['category']};\n"
      end
    end
    File.open(after_install, 'w') do |f|
      f << "#!/bin/bash\n"
      f << "cd #{where}/bin\n"
      f << "ln -s #{where}/lib/#{opts['app_name']}/#{opts['app_name']} .\n"
      # do we have a menu?
      if opts['create_menu'] == true
        f << "cd #{where}/lib/#{opts['app_name']}\n"
        f << "xdg-desktop-menu install --novendor  #{opts['app_name']}.desktop\n"
      end
    end
    chmod 0755, after_install
    File.open(before_remove, 'w') do |f|
      f << "#!/bin/bash\n"
      f << "rm -rf #{where}/bin/#{opts['app_name']}\n"
      f << "cd #{where}/lib/#{opts['app_name']}\n"
      if opts['create_menu'] == true
        f << "xdg-desktop-menu uninstall #{opts['app_name']}.desktop\n"
      end
    end
    chmod 0755, before_remove
  end
  # now we do fpm things - lets build a bash script for debugging/use
  arch = `uname -m`.strip
  ptype = opts['fpm_type']  # 'deb', 'rpm', 'freebsd'
  scriptp = opts['packdir']
  bscr = "#{scriptp}/fpm.sh"
  File.open(bscr,'w') do |f|
    f << <<SCR
#!/bin/bash
echo $PATH
fpm --verbose -t #{ptype} -s dir -p #{packdir}.#{ptype} -f -n #{opts['app_name']} \
--prefix '#{opts['linux_where']}/lib' --after-install #{opts['app_name']}/#{after_install} \
-a #{arch} --url "#{opts['website']}" --license '#{opts['license_tag']}' --before-remove #{opts['app_name']}/#{before_remove} \
--vendor '#{opts['publisher']}' --category #{opts['category']} \
--description "#{opts['purpose']}" -m '#{opts['maintainer']}' "#{opts['app_name']}"
SCR
  end
  chmod 0755, bscr
  puts "Please examine fpm.sh and then ./ftm.sh to build the #{ptype}"
  #puts `echo $PATH`
  #`#{bscr}`  # no rvm in that shell so no fpm, grrr
  yield "Please do './fpm.sh' in #{scriptp}" if blk
=begin
  # This is troublsome - almost works
  ARGV.clear
  args = ["--verbose", "-t", "deb", "-s", "dir", "-p", "#{packdir}.deb",
   "-f", "-n",  "#{opts['app_name']}", "--prefix", "#{opts['linux_where']}/lib",
   "--after-install", "#{packdir}/#{after_install}", "-a", "#{arch}", "--url",
  "#{opts['website']}", "--license", "\'#{opts['license_tag']}\'", "--before-remove",
  "#{packdir}/#{before_remove}", "--vendor", "'#{opts['publisher']}'", 
   "--category", "#{opts['category']}", "--description", "'#{opts['purpose']}'",
   "-m", "'#{opts['maintainer']}'", "#{packdir}"]
  args.each {|i| ARGV.push i}
  puts ARGV.inspect
  require "rubygems"
  #$: << File.join(File.dirname(__FILE__), "..", "lib")
  puts "Gem path: #{Gem.bin_path('fpm')}"
  require "fpm"
  require "fpm/command"
  FPM::Command.run ARGV
  yield "Your app is in #{scriptp}" if blk
=end
end

.merge_osx(opts) {|"using #{app_dir}"| ... } ⇒ Object

Yields:

  • ("using #{app_dir}")


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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
187
188
189
190
191
192
193
194
195
196
197
198
199
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
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
# File 'lib/package/merge-osx.rb', line 18

def PackShoes.merge_osx(opts, &blk)
  app_dir = opts['packdir']
  yield "using #{app_dir}" if blk
  # setup defaults if not in the opts
  rbvstr = opts['target_ruby'] ? opts['target_ruby'] : RUBY_VERSION
  rbmm = rbvstr[/\d.\d/].to_str
  # user gems can have a different arch from shoes (hypthen)
  tarch = opts['target_ruby_arch']
  flds = tarch.split('-')
  if flds.size == 2
    rbarch = tarch
    ver = flds[1][/\d\d/]
    puts "parse #{ver.inspect}"
    gemarch = flds[0]+'-darwin-'+ver
    puts "rbarch-1: #{rbarch} garch: #{gemarch}"
  else # assume 3
    gemarch = tarch
    rbarch = "#{flds[0]}-#{flds[1]}#{flds[2]}"
    puts "rbarch-2: #{rbarch} garch: #{gemarch}"
  end
  opts['publisher'] = 'shoerb' unless opts['publisher']
  opts['website'] = 'http://shoesrb.com/' unless opts['website']
  opts['osx_identifier'] = "com.mvmanila" unless opts['osx_identifier']
  toplevel = []
  Dir.chdir(DIR) do
    Dir.glob('*') {|f| toplevel << f}
  end
  exclude = %w(static CHANGELOG.txt cshoes gmon.out README.txt
    samples package VERSION.txt Shoes.app tmp pangorc command-manual.rb)

  rm_rf "#{app_dir}/#{opts['app_name']}.app"
  mkdir_p "#{app_dir}/#{opts['app_name']}.app/Contents/MacOS"
  mkdir_p "#{app_dir}/#{opts['app_name']}.app/Contents/Resources/English.lproj"
  packdir = "#{app_dir}/#{opts['app_name']}.app/Contents/MacOS"
  # create the resource and sub icons
  app_name = opts['app_name']
  icon_name = File.basename(opts['app_icns'])
  cp opts['app_icns'], "#{app_dir}/#{opts['app_name']}.app/"
  cp opts['app_icns'], "#{app_dir}/#{opts['app_name']}.app/Contents/Resources/"
  vers =[0, 1]
  File.open(File.join(app_dir, "#{opts['app_name']}.app", "Contents", "PkgInfo"), 'w') do |f|
    f << "APPL????"
  end
  File.open(File.join(app_dir, "#{opts['app_name']}.app", "Contents", "Info.plist"), 'w') do |f|
    f << <<END
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleGetInfoString</key>
<string>#{app_name} #{vers.join(".")}</string>
<key>CFBundleExecutable</key>
<string>#{app_name}-launch</string>
<key>CFBundleIdentifier</key>
<string>#{opts['osx_identifier']}.#{name}</string>
<key>CFBundleName</key>
<string>#{app_name}</string>
<key>CFBundleIconFile</key>
<string>#{icon_name}</string>
<key>CFBundleShortVersionString</key>
<string>#{vers.join(".")}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>IFMajorVersion</key>
<integer>#{vers[0]}</integer>
<key>IFMinorVersion</key>
<integer>#{vers[1]}</integer>
</dict>
</plist>
END
  end
File.open(File.join(app_dir, "#{opts['app_name']}.app", "Contents", "version.plist"), 'w') do |f|
    f << <<END
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildVersion</key>
<string>1</string>
<key>CFBundleVersion</key>
<string>#{vers.join(".")}</string>
<key>ProjectName</key>
<string>#{app_name}</string>
<key>SourceVersion</key>
<string>#{Time.now.strftime("%Y%m%d")}</string>
</dict>
</plist>
END
  end
  File.open(File.join(packdir, "#{app_name}-launch"), 'wb') do |f|
    f << <<END
#!/bin/bash
APPPATH="${0%/*}"
unset DYLD_LIBRARY_PATH
cd "$APPPATH"
DYLD_LIBRARY_PATH="$APPPATH"  SHOES_RUBY_ARCH="#{opts['target_ruby_arch']}" ./#{app_name}-bin 
END
  end
  chmod 0755, File.join("#{packdir}/#{app_name}-launch")
  yield "Copy Ruby" if blk
  (toplevel-exclude).each do |p|
    cp_r File.join(DIR, p), packdir
  end
  # do the license stuff
  licf = File.open("#{packdir}/COPYING.txt", 'w')
  if opts['license'] && File.exist?(opts['license'])
    IO.foreach(opts['license']) {|ln| licf.puts ln}
    rm_rf "{packdir}/#{File.basename(opts['license'])}"		# TODO?
  end
  IO.foreach("#{DIR}/COPYING.txt") {|ln| licf.puts ln}  
  licf.close
  # we do need some statics for console to work. 
  mkdir_p "#{packdir}/static"
  Dir.glob("#{DIR}/static/icon*.png") {|p| cp p, "#{packdir}/static" }
  if opts['app_png']
    cp "#{opts['app_loc']}/#{opts['app_png']}", "#{packdir}/static/app-icon.png"
  end
=begin
  # remove chipmonk and ftsearch unless requested
  exts = opts['include_exts'] # returns []
  if  !exts || ! exts.include?('ftsearch')
    puts "removing ftsearchrt"
    rm "#{packdir}/lib/ruby/#{rbmm}.0/#{rbarch}/ftsearchrt.bundle" 
    rm_rf "#{packdir}/lib/shoes/help.rb"
    rm_rf "#{packdir}/lib/shoes/search.rb"
  end
  if  !exts || ! exts.include?('chipmunk')
    puts "removing chipmunk"
    rm "#{packdir}/lib/ruby/#{rbmm}.0/#{rbarch}/chipmunk.bundle"
    rm "#{packdir}/lib/shoes/chipmunk.rb"
  end
=end
  # get rid of some things in lib
  rm_rf "#{packdir}/lib/exerb"
  rm_rf "#{packdir}/lib/gtk-2.0" if File.exist? "#{packdir}/lib/gtk-2.0"
  # remove unreachable code in packdir/lib/shoes/ like help, app-package ...
  ['cobbler', 'debugger', 'shoes_irb', 'pack', 'app_package', 'packshoes',
    'remote_debugger', 'winject', 'envgem'].each {|f| rm "#{packdir}/lib/shoes/#{f}.rb" }

  # copy app contents (file/dir at a time)
  yield "Copy application" if blk
  app_contents = Dir.glob("#{opts['app_loc']}/*")
  app_contents.each do |p|
   cp_r p, packdir
  end
  #create new lib/shoes.rb with rewrite
  newf = File.open("#{packdir}/lib/shoes.rb", 'w')
  rewrite newf, "#{DIR}/lib/package/min-shoes.rb", {'APP_START' => opts['app_start'] }
  newf.close
  # create a new lib/shoes/log.rb with rewrite
  logf = File.open("#{packdir}/lib/shoes/log.rb", 'w')
  rewrite logf, "#{DIR}/lib/package/min-log.rb", {'CONSOLE_HDR' => "#{opts['app_name']} Errors"}
  logf.close
  # copy/remove gems - tricksy - pay attention
  # remove the Shoes built-in gems if not in the list 
  incl_gems = opts['include_gems']
  rm_gems = []
  Dir.glob("#{packdir}/lib/ruby/gems/#{rbmm}.0/specifications/*gemspec") do |p|
    gem = File.basename(p, '.gemspec')
    if incl_gems.include?(gem)
      puts "Keeping Shoes gem: #{gem}"
      incl_gems.delete(gem)
    else
      rm_gems << gem
    end
  end
  sgpath = "#{packdir}/lib/ruby/gems/#{rbmm}.0"
=begin
  # sqlite is a special case so delete it differently - trickery
  if !incl_gems.include?('sqlite3')
    spec = Dir.glob("#{sgpath}/specifications/default/sqlite3*.gemspec")
    rm spec[0]
    rm_gems << File.basename(spec[0],'.gemspec')
  else
    incl_gems.delete("sglite3")
  end
=end
  rm_gems.each do |g|
    puts "Deleting #{g}"
    rm_rf "#{sgpath}/specifications/#{g}.gemspec"
    rm_rf "#{sgpath}/extensions/#{rbarch}/#{rbmm}.0/#{g}"
    rm_rf "#{sgpath}/gems/#{g}"
  end

  # HACK ahead! Copy remaining Shoes gems gem.build_complete files
  # to different arch name because it's needed . Don't know why.
  bld = Dir.glob("#{sgpath}/extensions/#{rbarch}/#{rbmm}.0/*") do |p|
    nm = File.basename(p)
    puts "hack for #{nm}"
    cp_r "#{sgpath}/extensions/#{rbarch}/#{rbmm}.0/#{nm}", 
        "#{sgpath}/extensions/#{gemarch}/#{rbmm}.0"
  end

  # copy requested gems from user's GEMS_DIR - usually ~/.shoes/+gem
  #incl_gems.delete('sqlite3') if incl_gems.include?('sqlite3')
  incl_gems.each do |name| 
    puts "Copy #{name}"
    cp "#{GEMS_DIR}/specifications/#{name}.gemspec", "#{sgpath}/specifications"
    # does the gem have binary?
    built = "#{GEMS_DIR}/extensions/#{gemarch}/#{rbmm}.0/#{name}/gem.build_complete"
    if File.exist? built
      mkdir_p "#{sgpath}/extensions/#{rbarch}/#{rbmm}.0/#{name}"
      cp "#{GEMS_DIR}/extensions/#{gemarch}/#{rbmm}.0/#{name}/gem.build_complete",
        "#{sgpath}/extensions/#{rbarch}/#{rbmm}.0/#{name}"
        
      mkdir_p "#{sgpath}/extensions/#{gemarch}/#{rbmm}.0/#{name}"
      cp "#{GEMS_DIR}/extensions/#{gemarch}/#{rbmm}.0/#{name}/gem.build_complete",
        "#{sgpath}/extensions/#{gemarch}/#{rbmm}.0/#{name}"
      
    end
    cp_r "#{GEMS_DIR}/gems/#{name}", "#{sgpath}/gems"
  end
  
  # hide shoes-bin and shoes launch script names
  yield "make_installer" if blk
  Dir.chdir(packdir) do
    mv 'shoes-bin', "#{opts['app_name']}-bin"
    #chmod 0755, "#{opts['app_name']}"
    rm_rf 'shoes'
    rm_rf 'debug'
    rm_rf 'Shoes.desktop.tmpl'
    rm_rf 'Shoes.remove.desktop'
    rm_rf 'Shoes.remove.tmpl'
    rm_rf 'shoes-install.sh'
    rm_rf 'shoes-uninstall.sh'
    rm_rf 'Shoes.desktop'
    rm_rf 'shoes-launch'
  end

  arch = `uname -m`.strip
=begin
  # !!! pkgbuild doesn't work yet!!!
  # create the plist for pkgbuild to use
  File.open('pkg.plist','w') do |f|
    f << <<END
<?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">
<array>
<dict>
  <key>BundleHasStrictIdentifier</key>
  <true/>
  <key>BundleIsRelocatable</key>
  <true/>
  <key>BundleIsVersionChecked</key>
  <true/>
  <key>BundleOverwriteAction</key>
  <string>upgrade</string>
  <key>RootRelativeBundlePath</key>
  <string>Applications/#{app_dir}</string>
</dict>
</array>
</plist>
END
  end
  File.open("#{app_dir}/pkg.sh", 'w') do |f|
    f << <<SCR
pkgbuild --root #{app_dir} --identifier #{opts['osx_identifier']}.#{app_name} \\
--component-plist pkg.plist #{app_name}.pkg
SCR
  end
  chmod 0755, "#{app_dir}/pkg.sh"
  # puts "Please examine pkg.sh and then ./pkg.sh to build the .pkg"
  
  # the following works! 
  #`bsdtar -cjf #{app_name}.bz #{app_dir}`
=end
  
  # build a dmg assumes create_dmg is in ./yoursway-create-dmg
  bgp = opts['dmg_background']
  Dir.chdir(app_dir) do
 File.open("dmg.sh", 'w') do |f|
   f << <<SCR
#!/bin/bash 
test -f #{app_name}-Installer.dmg && rm #{app_name}-Installer.dmg
#{DIR}/lib/package/yoursway-create-dmg/create-dmg --volname "#{app_name} Installer" \
--window-pos 200 120 \
--window-size 400 300 \
--background #{bgp} \
--icon-size 80 \
--icon #{app_name}.app 150 10 \
--hide-extension #{app_name}.app \
--app-drop-link 150 185 \
--eula #{opts['license']} \
#{app_name}-Installer.dmg #{app_dir}
SCR
 end
 chmod 0755, "#{app_dir}/dmg.sh"
 #puts "For a dmg, do './dmg.sh'"
 `./dmg.sh`
 yield "All done!" if blk
	end
end

.repack_exe(opts, &blk) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/shoes/packshoes.rb', line 42

def PackShoes.repack_exe (opts, &blk)
  script = custom_installer opts
  size = File.size(script)
  f = File.open(script, 'rb')
  exe = Winject::EXE.new(File.join(DIR, "static", "stubs", "shoes-stub.exe"))
  exe.inject_string(Winject::EXE::SHOES_APP_NAME, File.basename(script))
  exe.inject_file(Winject::EXE::SHOES_APP_CONTENT, f.read)
  exe.inject_string(Winject::EXE::SHOES_DOWNLOAD_SITE, opts['dnlhost'])
  exe.inject_string(Winject::EXE::SHOES_DOWNLOAD_PATH, opts['dnlpath'])
  if opts['winargs']
    puts "injecting #{opts['winargs']}"
    exe.inject_string(Winject::EXE::SHOES_USE_ARGS, opts['winargs'])
  end
  if opts['ico']
    exe.inject_icons(opts['ico'])
  end
  f2 = File.open(opts['shoesdist'],'rb')
  if blk 
    blk.call "Repack Shoes.exe #{opts['shoesdist']} distribution"
  end
  exe.inject_file(Winject::EXE::SHOES_SYS_SETUP, f2.read)
  exe.save(script.gsub(/\.\w+$/, '') + ".exe") do |len|
  end
  f.close
  f2.close
  if blk
    blk.call "Done packaging Windows"
  end
end

.repack_linux(opts, &blk) ⇒ Object



130
131
132
133
134
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/shoes/packshoes.rb', line 130

def PackShoes.repack_linux opts, &blk
  arch = opts['arch']
  script = custom_installer opts
  name = File.basename(script).gsub(/\.\w+$/, '')
  app_name = name.capitalize.gsub(/[-_](\w)/) { $1.capitalize }
  run_path = script.gsub(/\.\w+$/, '') + "-#{arch}.run"
  tgz_path = script.gsub(/\.\w+$/, '') + "-#{arch}.tgz"
  tar_path = script.gsub(/\.\w+$/, '') + "-#{arch}.tar"
  tmp_dir = File.join(opts['packtmp'], "+run")
  FileUtils.mkdir_p(tmp_dir)
  pkgf = open(opts['shoesdist'],'rb')  # downloaded/cached .run/.install
  if blk 
    blk.call"Expanding #{arch} distribution. Patience is needed"
  end
  # skip to the tar contents in the .run
 size = Shy.hrun(pkgf)
 # Copy the rest to a new file
 wk_dir = File.join(opts['packtmp'], "+tmp")
  FileUtils.mkdir_p(wk_dir)
 wkf = open(File.join(wk_dir,"run.gz"),'wb')
 buff = ''
 while pkgf.read(32768, buff) != nil do
   wkf.write(buff) 
  end
 wkf.close
 if blk 
   blk.call "Start extract"
 end
 @tarmodes = {}
 fastxzf(wkf, tmp_dir, @tarmodes)
  FileUtils.rm_rf(wk_dir)
  if blk 
    blk.call "Copy script and stubs"
  end
  FileUtils.cp(script, File.join(tmp_dir, File.basename(script)))
  File.open(File.join(tmp_dir, "sh-install"), 'wb') do |a|
   rewrite a, File.join(DIR, "static", "stubs", "sh-install"),
       'SCRIPT' => "./#{File.basename(script)}"
  end
  FileUtils.chmod 0755, File.join(tmp_dir, "sh-install")
  # add sh-install and script to the modes list
  @tarmodes[File.basename(script)] = "0755".oct
  @tarmodes['sh-install'] = "0755".oct
  # debug - dump @tarmodes
  #@tarmodes.each { |k,v| puts "#{k} #{sprintf('%4o',v)}" }
 
  if blk
    blk.call "Compute size and compress"
  end
  raw = Shy.du(tmp_dir)
      
  #Create tar file with correct modes (he hopes)
  File.open(tar_path,'wb') do |tf|
    tb = fastcf(tf, tmp_dir, @tarmodes)
  end
  # compress tar file 
  File.open(tgz_path,'wb') do |tgz|
    z = Zlib::GzipWriter.new(tgz)
    File.open(tar_path,'rb') do |tb|
      z.write tb.read
    end
    z.close
  end
  FileUtils.rm tar_path
  if blk 
    blk.call "Checksum, install  and copy"
  end
  md5, fsize = Shy.md5sum(tgz_path), File.size(tgz_path)
  File.open(run_path, 'wb') do |f|
   rewrite f, File.join(DIR, "static", "stubs", "blank.run"),
    'CRC' => '0000000000', 'MD5' => md5, 'LABEL' => app_name, 'NAME' => name,
    'SIZE' => fsize, 'RAWSIZE' => (raw / 1024) + 1, 'TIME' => Time.now, 'FULLSIZE' => raw
    File.open(tgz_path, 'rb') do |f2|
    f.write f2.read(8192) until f2.eof
   end
  end
  if blk
    blk.call "Done packing Linux"
  end
  FileUtils.chmod 0755, run_path
  FileUtils.rm_rf(tgz_path)
  FileUtils.rm_rf(tmp_dir)
end

.repack_osx(opts, &blk) ⇒ Object



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
# File 'lib/shoes/packshoes.rb', line 367

def PackShoes.repack_osx opts, &blk
  
  script = custom_installer opts
  name = File.basename(script).gsub(/\.\w+$/, '')
  app_name = name.capitalize.gsub(/[-_](\w)/) { $1.capitalize }
  #vol_name = name.capitalize.gsub(/[-_](\w)/) { " " + $1.capitalize }
  tar_path = script.gsub(/\.\w+$/, '') + "-osx.tar"
  tgz_path = script.gsub(/\.\w+$/, '') + "-osx.tgz"
  app_app = "#{app_name}.app"
  vers = [1, 0]

  tmp_dir = File.join(opts['packtmp'], "+dmg")
  FileUtils.rm_rf(tmp_dir)
  FileUtils.mkdir_p(tmp_dir)
  # expand download into ~/.shoes/+dmg/Shoes.app
  pkgf = open(opts['shoesdist'], 'rb')
  if blk
    blk.call"Expanding OSX distribution. Patience is needed"
  end
	#Shy.xzf(pkgf, tmp_dir)   
	@tarmodes = {}
	fastxzf(pkgf, tmp_dir, @tarmodes, app_app)
	# debug 
	# @tarmodes.each_key {|k| puts "entry #{k} = #{@tarmodes[k]}" }
  app_dir = File.join(tmp_dir, app_app)
  # rename Shoes.app to app_dir
  Dir.chdir tmp_dir do
    FileUtils.mv "Shoes.app", app_app
  end
  # deal with custom icons. 
  icon_path = ''
  if  opts['icns'] 
    icon_path = opts['icns']
  else
    # use Shoes icons
    icon_path = File.join(DIR, "static", "Shoes.icns")
  end
  icon_name = File.basename(icon_path)
 
  res_dir = File.join(tmp_dir, app_app, "Contents", "Resources")
  mac_dir = File.join(tmp_dir, app_app, "Contents", "MacOS")
  [res_dir, mac_dir].map { |x| FileUtils.mkdir_p(x) }
  #FileUtils.cp(File.join(DIR, "static", "Shoes.icns"), app_dir)
  #FileUtils.cp(File.join(DIR, "static", "Shoes.icns"), res_dir)
  FileUtils.cp(icon_path, app_dir)
  FileUtils.cp(icon_path, res_dir)
  # make cache entries for two files above just to keep the consoles
  # messages away. 
  @tarmodes["#{app_app}/Contents/Resources/#{icon_name}"] = 0644
  @tarmodes["#{app_app}/#{icon_name}"] = 0644
  File.open(File.join(app_dir, "Contents", "PkgInfo"), 'w') do |f|
    f << "APPL????"
  end
  File.open(File.join(app_dir, "Contents", "Info.plist"), 'w') do |f|
    f << <<END
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleGetInfoString</key>
<string>#{app_name} #{vers.join(".")}</string>
<key>CFBundleExecutable</key>
<string>#{name}-launch</string>
<key>CFBundleIdentifier</key>
<string>org.hackety.#{name}</string>
<key>CFBundleName</key>
<string>#{app_name}</string>
<key>CFBundleIconFile</key>
<string>#{icon_name}</string>
<key>CFBundleShortVersionString</key>
<string>#{vers.join(".")}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>IFMajorVersion</key>
<integer>#{vers[0]}</integer>
<key>IFMinorVersion</key>
<integer>#{vers[1]}</integer>
</dict>
</plist>
END
  end
  File.open(File.join(app_dir, "Contents", "version.plist"), 'w') do |f|
    f << <<END
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildVersion</key>
<string>1</string>
<key>CFBundleVersion</key>
<string>#{vers.join(".")}</string>
<key>ProjectName</key>
<string>#{app_name}</string>
<key>SourceVersion</key>
<string>#{Time.now.strftime("%Y%m%d")}</string>
</dict>
</plist>
END
  end
  File.open(File.join(mac_dir, "#{name}-launch"), 'wb') do |f|
    f << <<END
#!/bin/bash
APPPATH="${0%/*}"
unset DYLD_LIBRARY_PATH
cd "$APPPATH"
echo "[Pango]" > pangorc
#echo "ModuleFiles=$APPPATH/pango.modules" >> pangorc
#echo "ModulesPath=$APPPATH/pango/modules" >> pangorc
#PANGO_RC_FILE="$APPPATH/pangorc" ./pango-querymodules > pango.modules
DYLD_LIBRARY_PATH="$APPPATH" PANGO_RC_FILE="$APPPATH/pangorc" SHOES_RUBY_ARCH="#{opts['shoesruby']}" ./shoes-bin -f "#{File.basename(script)}"
END
  end
  ls = File.join(mac_dir, "#{name}-launch")
  FileUtils.chmod 0755, ls
  @tarmodes["#{app_app}/Contents/MacOS/#{name}-launch"] = 0755
  FileUtils.cp(script, File.join(mac_dir, File.basename(script)))
  @tarmodes["#{app_app}/Contents/MacOS/#{File.basename(script)}"] = 0644
  #FileUtils.cp(File.join(DIR, "static", "stubs", "cocoa-install"),
  #  File.join(mac_dir, "cocoa-install"))
  if blk
    blk.call "Creating new archive"
  end
  #File.open(tgz_path, 'wb') do |f|
	#  Shy.czf(f, tmp_dir)
  #end
  # #Create tar file with correct modes (he hopes)
  File.open(tar_path,'wb') do |tf|
    tb = fastcf(tf, tmp_dir, @tarmodes)
  end
  # compress tar file 
  File.open(tgz_path,'wb') do |tgz|
    z = Zlib::GzipWriter.new(tgz)
    File.open(tar_path,'rb') do |tb|
      z.write tb.read
    end
    z.close
  end
  FileUtils.rm_rf(tmp_dir)
  FileUtils.rm_rf(tar_path)
end

.rewrite(a, before, hsh) ⇒ Object

only sub matches.



514
515
516
517
518
519
520
521
522
523
524
525
526
# File 'lib/shoes/packshoes.rb', line 514

def PackShoes.rewrite a, before, hsh
  File.open(before) do |b|
    b.each do |line|
      a << line.gsub(/\#\{(\w+)\}/) {
        if hsh[$1] 
          hsh[$1]
        else
          '#{'+$1+'}'
        end
      }
    end
  end
end

.tar_extract(opened_file) ⇒ Object



648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
# File 'lib/shoes/packshoes.rb', line 648

def PackShoes.tar_extract opened_file
  Gem::Package::TarReader.new( Zlib::GzipReader.new(opened_file)) do |tar|
    tar.each do |entry|
      dest = entry.full_name
     if entry.directory?
       FileUtils.rm_rf dest unless File.directory? dest
        FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
     elsif entry.file?
       FileUtils.rm_rf dest unless File.file? dest
       File.open dest, "wb" do |f|
         f.print entry.read
        end
        FileUtils.chmod entry.header.mode, dest, :verbose => false
      elsif entry.header.typeflag == '2' #Symlink!
        alert "Cannot convert Symlinks. Contact #{hdr.creator}"
      end
    end
  end
end