netfira-installer-generator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bee147204dd4460b4bcf0834bc98afdc95b636b9
4
+ data.tar.gz: 2c580bb0b62fd6259a62dc0c2d085a37a18d1957
5
+ SHA512:
6
+ metadata.gz: 4c3b48fafe6632d6088b694dce95aa4f0bf234109a299221fe65c129d4ee224533d84bc0e3b36b7b888463b2597a886d8ae2e1b2c958d33b5fc66f2962c7d42f
7
+ data.tar.gz: 03dd5bf1168791d6f151165d2b5f951d1de790d167ba32222379e6e5c6733d850e5444dd19345d38c4f52b9169dd1ac8d0a3c49fcb313404d2168d0fe2de6e14
@@ -0,0 +1 @@
1
+ TODO
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/netfira-installer-generator.rb'
3
+ Netfira::InstallerGenerator::Cli.main
@@ -0,0 +1,8 @@
1
+ require 'pathname'
2
+ require_relative 'netfira/installer_generator'
3
+
4
+ module Netfira
5
+ class InstallerGenerator
6
+ GEM_ROOT = Pathname(__FILE__).parent.parent
7
+ end
8
+ end
@@ -0,0 +1,130 @@
1
+ require_relative 'installer_generator/version'
2
+ require_relative 'installer_generator/nsis_template'
3
+ require_relative 'installer_generator/binary'
4
+ require_relative 'installer_generator/exception'
5
+ require_relative 'installer_generator/cli'
6
+
7
+ require 'uri'
8
+ require 'fileutils'
9
+ require 'tmpdir'
10
+ require 'securerandom'
11
+ require 'pathname'
12
+
13
+ module Netfira
14
+ class InstallerGenerator
15
+ include FileUtils
16
+
17
+ def self.preflight!
18
+ [Binary::Makensis, Binary::Signcode].each do |klass|
19
+ raise "No binaries available from [ #{klass.bin_files.join ' | '} ]" unless klass.available?
20
+ end
21
+ end
22
+
23
+ # Because the writers are created en masse:
24
+ # noinspection RubyResolve
25
+ attr_reader :icon, :source, :signing_cert, :signing_key
26
+
27
+ attr_accessor :target, :shop_id, :shop_url, :sync_url, :use_ssl,
28
+ :installer_name, :installer_filename, :temp_dir, :auth_server,
29
+ :signing_description, :signing_url,
30
+ :output_device
31
+
32
+ REQUIRED_VALUES = %i[shop_id shop_url sync_url icon source signing_cert signing_key target]
33
+
34
+ def initialize
35
+ self.output_device = :null
36
+ self.use_ssl = true
37
+ self.installer_name = 'Netfira Installer'
38
+ self.installer_filename = 'netfira_dlm.exe'
39
+ self.temp_dir = 'netfireb'
40
+ self.auth_server = 'auth.netfira.biz'
41
+ end
42
+
43
+ { icon: 'Icon',
44
+ source: 'Source executable',
45
+ signing_cert: 'Signing certificate',
46
+ signing_key: 'Signing private key'
47
+
48
+ }.each do |method, description|
49
+ define_method :"#{method}=" do |path|
50
+ raise "#{description} not found at #{path}" unless File.exist? path
51
+ instance_variable_set :"@#{method}", path
52
+ end
53
+ end
54
+
55
+ def generate!
56
+
57
+ # Ensure we have all our binary friends
58
+ self.class.preflight!
59
+
60
+ # Ensure we have no missing required values
61
+ missing = REQUIRED_VALUES.select { |key| send(key).nil? }
62
+ raise Exception, "Missing value(s) for #{missing.join ', '}" unless missing.empty?
63
+
64
+ # Make a temporary build dir
65
+ build_dir = Pathname(Dir.tmpdir) + SecureRandom.uuid
66
+ mkdir build_dir
67
+
68
+ begin
69
+
70
+ # Copy the source exe and icon to the build dir
71
+ cp icon, build_dir + 'setup.ico'
72
+ cp source, build_dir + installer_filename
73
+
74
+ # Write the NSIS script to the build dir
75
+ File.write build_dir + 'nsis_script.nsi', render_nsis_template
76
+
77
+ # Run makensis
78
+ makensis build_dir or raise Exception, 'makensis failed'
79
+
80
+ # Run signcode
81
+ signcode build_dir or raise Exception, 'signcode failed'
82
+
83
+ # Write target file
84
+ mkdir_p File.dirname(target)
85
+ mv build_dir + 'signed.exe', target
86
+
87
+ ensure
88
+ rm_rf build_dir
89
+ end
90
+
91
+ end
92
+
93
+ private
94
+
95
+ def render_nsis_template
96
+ # noinspection RubyStringKeysInHashInspection
97
+ values = {
98
+ 'INSTALLER_NAME' => installer_name,
99
+ 'TEMP_DIR' => temp_dir,
100
+ 'INSTALLER_FILENAME' => installer_filename,
101
+ 'WHO_AM_I_GUID' => shop_id,
102
+ 'AUTHENTICATION_SERVER_1' => auth_server,
103
+ 'WEBSTORE_SYNC_URL' => sync_url,
104
+ 'WEBSTORE_FRONT_URL' => shop_url,
105
+ 'SHOP_ADDRESS' => URI.parse(shop_url).host,
106
+ 'NO_USE_SSL' => use_ssl ? '0' : '1'
107
+ }
108
+ NsisTemplate.sub values
109
+ end
110
+
111
+ def makensis(build_dir)
112
+ b = Binary::Makensis.new
113
+ b.template_file_name = 'nsis_script.nsi'
114
+ b.build_dir = build_dir
115
+ b.run output_device
116
+ end
117
+
118
+ def signcode(build_dir)
119
+ b = Binary::Signcode.new
120
+ b.spc_path = signing_cert
121
+ b.key_path = signing_key
122
+ b.url = signing_url || shop_url
123
+ b.description = signing_description || installer_name
124
+ b.source_path = build_dir + 'nsis_generated.exe'
125
+ b.target_path = build_dir + 'signed.exe'
126
+ b.run output_device
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,28 @@
1
+ require 'shellwords'
2
+
3
+ module Netfira
4
+ class InstallerGenerator
5
+ class Binary
6
+
7
+ def self.available?
8
+ @available = !bin_file.nil?
9
+ end
10
+
11
+ def self.bin_file
12
+ @bin_file = bin_files.select{ |file| system "which #{file} > /dev/null" }.first
13
+ end
14
+
15
+ def run(output_device = :null)
16
+ system "#{command} > /dev/#{output_device}"
17
+ end
18
+
19
+ def esc(string)
20
+ Shellwords.escape string
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+
27
+ require_relative 'binary/makensis'
28
+ require_relative 'binary/signcode'
@@ -0,0 +1,15 @@
1
+ require 'shellwords'
2
+
3
+ class Netfira::InstallerGenerator
4
+ class Binary::Makensis < Binary
5
+
6
+ def self.bin_files; %w[makensis] end
7
+
8
+ attr_accessor :build_dir, :template_file_name
9
+
10
+ def command
11
+ "cd #{esc build_dir}; makensis #{esc template_file_name}"
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,54 @@
1
+ class Netfira::InstallerGenerator
2
+ class Binary::Signcode < Binary
3
+
4
+ def self.bin_files; %w[osslsigncode signcode] end
5
+
6
+ attr_accessor :spc_path, :key_path, :description, :url, :source_path, :target_path
7
+
8
+ def command
9
+ send :"#{self.class.bin_file}_cmd"
10
+ end
11
+
12
+ private
13
+
14
+ # See http://development.adaptris.net/users/lchan/blog/2013/06/07/signing-windows-installers-on-linux/
15
+
16
+ def osslsigncode_cmd
17
+ parts = [
18
+ 'osslsigncode',
19
+ '-spc', esc(spc_path),
20
+ '-key', esc(key_path),
21
+ '-n', esc(description || 'Netfira'),
22
+ '-i', esc(url || 'http://netfira.com'),
23
+ '-t http://timestamp.verisign.com/scripts/timstamp.dll',
24
+ '-in', esc(source_path),
25
+ '-out', esc(target_path)
26
+ ]
27
+ parts.join ' '
28
+ end
29
+
30
+ # From Amel's rendition:
31
+ # $signCommand = "signcode -spc {$certFileBase}authenticode.spc -v {$certFileBase}authenticode.pvk -a sha1 -$ commercial -n Netfira ";
32
+ # $signCommand .= "-i http://netfira.com -t http://timestamp.verisign.com/scripts/timstamp.dll -tr 10 ".$fileName;
33
+ #
34
+ # See http://manpages.ubuntu.com/manpages/precise/man1/signcode.1.html
35
+
36
+ def signcode_cmd
37
+ parts = [
38
+ 'cp', esc(source_path), esc(target_path), '&&',
39
+ 'signcode',
40
+ '-spc', esc(spc_path),
41
+ '-v', esc(key_path),
42
+ '-a sha1', # Hash algorithm
43
+ '-$ commercial', # Publisher information
44
+ '-n', esc(description || 'Netfira'),
45
+ '-i', esc(url || 'http://netfira.com'),
46
+ '-t http://timestamp.verisign.com/scripts/timstamp.dll',
47
+ '-tr 3 -tw 5', # Try timestamping 3 times, 5 seconds apart
48
+ esc(target_path)
49
+ ]
50
+ parts.join ' '
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,53 @@
1
+ require 'optparse'
2
+
3
+ module Netfira
4
+ class InstallerGenerator
5
+ module Cli
6
+ class << self
7
+
8
+ def main
9
+
10
+ generator = InstallerGenerator.new
11
+ generator.output_device = :stdout
12
+
13
+ option_parser = OptionParser.new do |opts|
14
+
15
+ opts.separator "\nInput/Output"
16
+
17
+ opts.on('-s', '--source [PATH]', 'Source EXE file') { |path| generator.source = path }
18
+ opts.on('-t', '--target [PATH]', 'The EXE file to write') { |path| generator.target = path }
19
+ opts.on('-i', '--icon [PATH]', 'The icon file to use for the generated installer') { |path| generator.icon = path }
20
+
21
+ opts.separator "\nSigning"
22
+
23
+ opts.on('-c', '--cert [PATH]', 'Signing certificate path') { |path| generator.signing_cert = path }
24
+ opts.on('-k', '--key [PATH]', 'Signing certificate private key path') { |path| generator.signing_key = path }
25
+ opts.on('-d', '--desc [TEXT]', 'Signing description') { |text| generator.signing_description = text }
26
+ opts.on('-r', '--url [URL]', 'Signing URL') { |url| generator.signing_url = url }
27
+
28
+ opts.separator "\nConfiguration"
29
+
30
+ opts.on('-n', '--name [TEXT]', 'Installer name') { |text| generator.installer_name = text }
31
+ opts.on('-x', '--temp-file [NAME]', 'Temporary installer filename') { |name| generator.installer_filename = name }
32
+ opts.on('-u', '--shop-id [VALUE]', 'Shop ID') { |id| generator.shop_id = id }
33
+ opts.on('-f', '--shop-url [URL]', 'Shop URL') { |url| generator.shop_url = url }
34
+ opts.on('-b', '--sync-url [URL]', 'Sync URL') { |url| generator.sync_url = url }
35
+ opts.on('-a', '--auth-server [URL]', 'Authentication server') { |url| generator.auth_server = url }
36
+ opts.on('-e', '--temp-dir [DIR]', 'Temporary installation directory') { |dir| generator.temp_dir = dir }
37
+
38
+ end
39
+
40
+ begin
41
+ option_parser.parse!
42
+ generator.generate!
43
+ puts "Wrote #{generator.target}"
44
+ rescue => exception
45
+ puts "#{exception.message}\n\n#{option_parser}"
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,7 @@
1
+ module Netfira
2
+ class InstallerGenerator
3
+ class Exception < RuntimeError
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,74 @@
1
+ module Netfira
2
+ class InstallerGenerator
3
+ module NsisTemplate
4
+
5
+ def self.sub(variables)
6
+ template.gsub(/\{([A-Z][_A-Z]*)\}/) { variables[$1] }
7
+ end
8
+
9
+ private
10
+
11
+ def self.template
12
+ @template ||= <<-__EOF__
13
+ ; This script creates the bootstrap installer for the Netfira download manager.
14
+
15
+ ;--------------------------------
16
+ ; No output from this bootstrap installer:
17
+ SilentInstall silent
18
+
19
+ ; The name of the installer
20
+ Name "{INSTALLER_NAME}"
21
+ Icon setup.ico
22
+
23
+ ; The file to write
24
+ OutFile "nsis_generated.exe"
25
+
26
+ ; The default installation directory
27
+ InstallDir $TEMP\{TEMP_DIR}
28
+
29
+ ; The stuff to install
30
+ Section ""
31
+
32
+ ; Set output path to the installation directory.
33
+ SetOutPath $INSTDIR
34
+
35
+ ; Put file Netfira download manager in the temp directory
36
+ File {INSTALLER_FILENAME}
37
+
38
+ ; WhoAmIGUID
39
+ ReadRegStr $1 HKLM "Software\Netfire\AMIPS" "WhoAmIGUID"
40
+
41
+ ; if the registry value is empty - set it, otherwise continue
42
+ StrCmp $1 "" 0 +2
43
+ WriteRegStr HKLM "Software\Netfire\AMIPS" "WhoAmIGUID" "{WHO_AM_I_GUID}"
44
+
45
+ ; AuthenticationServer1
46
+ ReadRegStr $1 HKLM "Software\Netfire\AMIPS" "AuthenticationServer1"
47
+
48
+ ; if the registry value is empty - set it, otherwise continue
49
+ StrCmp $1 "" 0 +2
50
+ WriteRegStr HKLM "Software\Netfire\AMIPS" "AuthenticationServer1" "{AUTHENTICATION_SERVER_1}"
51
+
52
+ ; Webstore
53
+ ReadRegStr $1 HKLM "Software\Netfire\Webstore" "SyncURL"
54
+
55
+ ; if the registry value is empty - set it, otherwise continue
56
+ StrCmp $1 "" 0 +2
57
+ WriteRegStr HKLM "Software\Netfire\Webstore" "SyncURL" "{WEBSTORE_SYNC_URL}"
58
+ StrCmp $1 "" 0 +2
59
+ WriteRegStr HKLM "Software\Netfire\Webstore" "StoreFrontURL" "{WEBSTORE_FRONT_URL}"
60
+ StrCmp $1 "" 0 +2
61
+ WriteRegStr HKLM "Software\Netfire\Webstore" "Server" "{SHOP_ADDRESS}"
62
+ StrCmp $1 "" 0 +2
63
+ WriteRegStr HKLM "Software\Netfire\Networking" "NoUseSsl" "{NO_USE_SSL}"
64
+
65
+ ; Execute the download manager:
66
+ Exec '"$INSTDIR\{INSTALLER_FILENAME}"'
67
+
68
+ SectionEnd
69
+ __EOF__
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,5 @@
1
+ module Netfira
2
+ class InstallerGenerator
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: netfira-installer-generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Neil E. Pearson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Netfira Windows App Installer Generator
14
+ email:
15
+ - neil@helium.net.au
16
+ executables:
17
+ - make_nf_installer
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - README.md
22
+ - bin/make_nf_installer
23
+ - lib/netfira-installer-generator.rb
24
+ - lib/netfira/installer_generator.rb
25
+ - lib/netfira/installer_generator/binary.rb
26
+ - lib/netfira/installer_generator/binary/makensis.rb
27
+ - lib/netfira/installer_generator/binary/signcode.rb
28
+ - lib/netfira/installer_generator/cli.rb
29
+ - lib/netfira/installer_generator/exception.rb
30
+ - lib/netfira/installer_generator/nsis_template.rb
31
+ - lib/netfira/installer_generator/version.rb
32
+ homepage: http://netfira.com.au/
33
+ licenses:
34
+ - Proprietary
35
+ metadata: {}
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 2.2.2
53
+ signing_key:
54
+ specification_version: 4
55
+ summary: Netfira Windows App Installer Generator
56
+ test_files: []