netlinx-workspace 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +206 -6
  3. data/bin/netlinx-workspace +27 -0
  4. data/doc/NetLinx.html +18 -7
  5. data/doc/NetLinx/Compile.html +15 -4
  6. data/doc/NetLinx/Compile/Extension.html +15 -4
  7. data/doc/NetLinx/Compile/Extension/APW.html +8 -8
  8. data/doc/NetLinx/Project.html +334 -90
  9. data/doc/NetLinx/Rake.html +128 -0
  10. data/doc/NetLinx/Rake/Workspace.html +128 -0
  11. data/doc/NetLinx/Rake/Workspace/CreateWorkspaceConfig.html +387 -0
  12. data/doc/NetLinx/Rake/Workspace/GenerateAPW.html +371 -0
  13. data/doc/NetLinx/System.html +1341 -217
  14. data/doc/NetLinx/SystemFile.html +454 -51
  15. data/doc/NetLinx/Workspace.html +434 -69
  16. data/doc/NetLinx/Workspace/YAML.html +398 -0
  17. data/doc/_index.html +66 -4
  18. data/doc/class_list.html +6 -2
  19. data/doc/file.README.html +218 -10
  20. data/doc/file.license.html +4 -4
  21. data/doc/file_list.html +5 -1
  22. data/doc/frames.html +1 -1
  23. data/doc/index.html +218 -10
  24. data/doc/js/full_list.js +4 -1
  25. data/doc/method_list.html +171 -23
  26. data/doc/top-level-namespace.html +3 -3
  27. data/lib/netlinx/compile/extension/apw.rb +3 -0
  28. data/lib/netlinx/rake/workspace.rb +14 -0
  29. data/lib/netlinx/rake/workspace/create_workspace_config.rb +49 -0
  30. data/lib/netlinx/rake/workspace/generate_apw.rb +41 -0
  31. data/lib/netlinx/workspace.rb +58 -14
  32. data/lib/netlinx/workspace/project.rb +107 -0
  33. data/lib/netlinx/workspace/system.rb +226 -0
  34. data/lib/netlinx/workspace/system_file.rb +98 -0
  35. data/lib/netlinx/workspace/yaml.rb +217 -0
  36. data/license.txt +1 -1
  37. metadata +53 -28
  38. data/lib/netlinx-workspace.rb +0 -1
  39. data/lib/netlinx/project.rb +0 -83
  40. data/lib/netlinx/system.rb +0 -122
  41. data/lib/netlinx/system_file.rb +0 -36
@@ -0,0 +1,98 @@
1
+ require 'rexml/document'
2
+
3
+ module NetLinx
4
+ # A file node in a NetLinx::System.
5
+ class SystemFile
6
+ attr_accessor :system
7
+ attr_accessor :name
8
+ attr_accessor :path
9
+ attr_accessor :description
10
+ attr_accessor :type
11
+ # Array of D:P:S strings that this file maps to.
12
+ attr_accessor :devices
13
+
14
+ # @option kwargs [NetLinx::System] :system This file's parent system node.
15
+ # @option kwargs [String] :name ('') Identifiable name.
16
+ # @option kwargs [String] :path ('') Relative file path.
17
+ # @option kwargs [String] :description ('')
18
+ # @option kwargs [:master,:source,:include,:duet,:tko,:module,:ir,:tp4,:tp5] :type (:master)
19
+ def initialize **kwargs
20
+ @system = kwargs.fetch :system, nil
21
+
22
+ @name = kwargs.fetch :name, ''
23
+ @path = kwargs.fetch :path, ''
24
+ @description = kwargs.fetch :description, ''
25
+ @type = kwargs.fetch :type, :master
26
+
27
+ @devices = []
28
+
29
+ system_file_element = kwargs.fetch :element, nil
30
+ parse_xml_element system_file_element if system_file_element
31
+ end
32
+
33
+ # Add a device that uses this file.
34
+ # @param device [String] D:P:S string.
35
+ def << device
36
+ devices << device
37
+ end
38
+
39
+ # @return the SystemFile's name.
40
+ def to_s
41
+ @name
42
+ end
43
+
44
+ # @return [REXML::Element] an XML element representing this file.
45
+ def to_xml_element
46
+ REXML::Element.new('File').tap do |file|
47
+ file.attributes['CompileType'] = 'Netlinx'
48
+
49
+ file.attributes['Type'] = type_lookup[type]
50
+
51
+ file.add_element('Identifier').tap { |e| e.text = name }
52
+ file.add_element('FilePathName').tap { |e| e.text = path }
53
+ file.add_element('Comments').tap { |e| e.text = description }
54
+
55
+ @devices.each do |dps|
56
+ file.add_element('DeviceMap').tap do |e|
57
+ text = dps.include?(':') ? "Custom [#{dps}]" : dps
58
+ e.attributes['DevAddr'] = text
59
+ e.add_element('DevName').text = text
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ # @return lookup table for symbol to XML NetLinx file types.
68
+ def type_lookup
69
+ {
70
+ master: 'MasterSrc',
71
+ source: 'Source',
72
+ include: 'Include',
73
+ duet: 'DUET',
74
+ tko: 'TKO',
75
+ module: 'Module',
76
+ ir: 'IR',
77
+ tp4: 'TP4',
78
+ tp5: 'TP5',
79
+ }
80
+ end
81
+
82
+ def parse_xml_element system_file
83
+ # Load system file params.
84
+ @name = system_file.elements['Identifier'].text.strip || ''
85
+ @type = type_lookup.invert[system_file.attributes['Type']] || :master
86
+ @path = system_file.elements['FilePathName'].text.strip || ''
87
+ @description = system_file.elements['Comments'].text || ''
88
+
89
+ system_file.each_element 'DeviceMap' do |device_map|
90
+ dev_addr = device_map.attributes['DevAddr']
91
+ @devices.push dev_addr.include?(':') ?
92
+ dev_addr.match(/.*?\[(.*?)\]/)[1] :
93
+ dev_addr
94
+ end
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,217 @@
1
+ require 'yaml'
2
+
3
+ module NetLinx
4
+ class Workspace
5
+ # Configure NetLinx workspaces with YAML.
6
+ class YAML
7
+
8
+ # @return {NetLinx::Workspace}
9
+ def self.parse string
10
+ yaml = ::YAML.load string
11
+ yaml_systems = yaml['systems']
12
+
13
+ workspace = NetLinx::Workspace.new
14
+
15
+ if yaml_systems
16
+ # Load systems into an implicit project and workspace.
17
+ workspace.name = yaml_systems.first['name']
18
+ project = NetLinx::Project.new name: yaml_systems.first['name']
19
+ workspace << project
20
+
21
+ parse_systems project, yaml_systems
22
+ else
23
+ # An explicit workspace is defined.
24
+ workspace.name = yaml['name'] if yaml['name']
25
+ workspace.description = yaml['description'] if yaml['description']
26
+
27
+ yaml_projects = yaml['projects']
28
+ yaml_projects.each do |yaml_project|
29
+ workspace << NetLinx::Project.new.tap do |project|
30
+ project.name = yaml_project['name'] if yaml_project['name']
31
+ project.designer = yaml_project['designer'].to_s if yaml_project['designer']
32
+ project.dealer = yaml_project['dealer'].to_s if yaml_project['dealer']
33
+ project.sales_order = yaml_project['sales_order'].to_s if yaml_project['sales_order']
34
+ project.purchase_order = yaml_project['purchase_order'].to_s if yaml_project['purchase_order']
35
+ project.description = yaml_project['description'] if yaml_project['description']
36
+
37
+ parse_systems project, yaml_project['systems']
38
+ end
39
+ end
40
+ end
41
+
42
+ # Ensure exactly one system in the workspace is set active.
43
+ a_system_is_active = false
44
+ workspace.projects.each do |project|
45
+ project.systems.each do |system|
46
+ if a_system_is_active
47
+ system.active = false
48
+ next
49
+ else
50
+ a_system_is_active = true if system.active
51
+ end
52
+ end
53
+ end
54
+
55
+ # No active systems. Set the first one active automatically.
56
+ workspace.projects.first.systems.first.active = true \
57
+ unless a_system_is_active \
58
+ or workspace.projects.empty? \
59
+ or workspace.projects.first.systems.empty?
60
+
61
+ workspace
62
+ end
63
+
64
+ # @return {NetLinx::Workspace}
65
+ def self.parse_file file
66
+ parse File.open(file, 'r').read
67
+ end
68
+
69
+ private
70
+
71
+ # @return [String] File name without the path or extension.
72
+ def self.to_file_name path
73
+ File.basename(path).gsub(/\.\w+\z/, '')
74
+ end
75
+
76
+ def self.add_file_to_system system, file_path, type
77
+ puts "WARNING: Nonexistent file #{file_path}" unless File.exists? file_path
78
+
79
+ NetLinx::SystemFile.new(
80
+ path: file_path,
81
+ name: to_file_name(file_path),
82
+ type: type
83
+ ).tap { |system_file| system << system_file }
84
+ end
85
+
86
+ def self.attach_devices system_file, yaml_node
87
+ devices = yaml_node['dps']
88
+ return unless devices
89
+
90
+ devices = [devices] unless devices.is_a? Array
91
+
92
+ system_file.devices = devices.map do |d|
93
+ # Convert to string if YAML parses the DPS as date/time.
94
+ d.is_a?(String) ? d : [d / 3600, d % 3600 / 60, d % 60].join(':')
95
+ end
96
+ end
97
+
98
+ def self.parse_connection_node system, connection_node
99
+ case connection_node
100
+ when String
101
+ if connection_node =~ /\Acom\d+(?::|\z)/i
102
+ # Serial Connection
103
+ com_port, baud_rate = connection_node.split ':'
104
+ system.com_port = com_port.downcase.to_sym
105
+ system.baud_rate = baud_rate.to_i if baud_rate
106
+ else
107
+ # IP Connection
108
+ ip_address, ip_port = connection_node.split ':'
109
+ system.ip_address = ip_address
110
+ system.ip_port = ip_port.to_i if ip_port
111
+ end
112
+ when Hash
113
+ if connection_node['host']
114
+ # IP Connection
115
+ system.ip_address = connection_node['host']
116
+ system.ip_port = connection_node['port'] if connection_node['port']
117
+ else
118
+ # Serial Connection
119
+ system.com_port = connection_node['port'].downcase.to_sym
120
+ system.baud_rate = connection_node['baud_rate'] if connection_node['baud_rate']
121
+ system.data_bits = connection_node['data_bits'] if connection_node['data_bits']
122
+ system.stop_bits = connection_node['stop_bits'] if connection_node['stop_bits']
123
+ system.parity = connection_node['parity'].downcase.to_sym if connection_node['parity']
124
+ end
125
+ end
126
+ end
127
+
128
+ def self.parse_systems project, yaml_systems
129
+ yaml_systems.each do |yaml_system|
130
+ project << NetLinx::System.new.tap do |system|
131
+ system.name = yaml_system['name'] if yaml_system['name']
132
+ system.active = yaml_system['active'] || false
133
+ system.id = yaml_system['id'] if yaml_system['id']
134
+ system.description = yaml_system['description'] if yaml_system['description']
135
+
136
+ root = yaml_system['root'] # File system root directory.
137
+
138
+ parse_connection_node system, yaml_system['connection']
139
+
140
+ # Auto-include master source file.
141
+ master_src_path = yaml_system['axs'] || "#{system.name}.axs"
142
+ master_src_path = "#{root}/#{master_src_path}" if root
143
+ add_file_to_system system, master_src_path, :master
144
+
145
+ yaml_excluded_files = yaml_system['excluded_files']
146
+
147
+ # Auto-include 'include' directory.
148
+ include_path = 'include/**/*.axi'
149
+ include_path = "#{root}/#{include_path}" if root
150
+ include_files = Dir[include_path]
151
+ include_files -= Dir[*yaml_excluded_files] if yaml_excluded_files
152
+ include_files.each do |file_path|
153
+ add_file_to_system system, file_path, :include
154
+ end
155
+
156
+ # Additional include paths.
157
+ yaml_files = yaml_system['includes']
158
+ if yaml_files
159
+ files = Dir[*yaml_files]
160
+ files -= Dir[*yaml_excluded_files] if yaml_excluded_files
161
+
162
+ files.each do |file_path|
163
+ add_file_to_system system, file_path, :include
164
+ end
165
+ end
166
+
167
+ # Auto-include 'module' directory.
168
+ module_path = 'module/**/*.{tko,jar}'
169
+ module_path = "#{root}/#{module_path}" if root
170
+ module_files = Dir[module_path]
171
+ module_files -= Dir[*yaml_excluded_files] if yaml_excluded_files
172
+ module_files.each do |file_path|
173
+ add_file_to_system system, file_path,
174
+ (File.extname(file_path) == '.jar') ?
175
+ :duet :
176
+ File.extname(file_path)[1..-1].downcase.to_sym
177
+ end
178
+
179
+ # Additional module paths.
180
+ yaml_files = yaml_system['modules']
181
+ if yaml_files
182
+ files = Dir[*yaml_files]
183
+ files -= Dir[*yaml_excluded_files] if yaml_excluded_files
184
+
185
+ files.each do |file_path|
186
+ add_file_to_system system, file_path, File.extname(file_path)[1..-1].downcase.to_sym
187
+ end
188
+ end
189
+
190
+ # Touch panel files.
191
+ yaml_touch_panels = yaml_system['touch_panels']
192
+ if yaml_touch_panels
193
+ yaml_touch_panels.each do |yaml_touch_panel|
194
+ file_path = "touch_panel/#{yaml_touch_panel['path']}"
195
+ file_path = "#{root}/#{file_path}" if root
196
+ add_file_to_system(system, file_path, File.extname(file_path)[1..-1].downcase.to_sym)
197
+ .tap { |file| attach_devices file, yaml_touch_panel }
198
+ end
199
+ end
200
+
201
+ # IR files.
202
+ yaml_ir_files = yaml_system['ir']
203
+ if yaml_ir_files
204
+ yaml_ir_files.each do |yaml_ir|
205
+ file_path = "ir/#{yaml_ir['path']}"
206
+ file_path = "#{root}/#{file_path}" if root
207
+ add_file_to_system(system, file_path, :ir)
208
+ .tap { |file| attach_devices file, yaml_ir }
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ end
216
+ end
217
+ end
@@ -1,4 +1,4 @@
1
- Copyright 2013 Alex McLain
1
+ Copyright 2013-2015 Alex McLain
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netlinx-workspace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex McLain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-09 00:00:00.000000000 Z
11
+ date: 2015-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: netlinx-compile
@@ -16,70 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.0
19
+ version: '3.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.0
26
+ version: '3.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '10.4'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '10.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: yard
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.8.7
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 0.8.7
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '3.2'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-its
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.1'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: fivemat
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: '1.3'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: '1.3'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: pry
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -111,20 +125,28 @@ dependencies:
111
125
  description: This library provides a developer API for working with NetLinx Studio
112
126
  workspaces in Ruby. It also adds compiler support to the NetLinx Compile gem for
113
127
  these workspaces.
114
- email: alex@alexmclain.com
115
- executables: []
128
+ email:
129
+ - alex@alexmclain.com
130
+ executables:
131
+ - netlinx-workspace
116
132
  extensions: []
117
133
  extra_rdoc_files: []
118
134
  files:
119
135
  - README.md
136
+ - bin/netlinx-workspace
120
137
  - doc/NetLinx.html
121
138
  - doc/NetLinx/Compile.html
122
139
  - doc/NetLinx/Compile/Extension.html
123
140
  - doc/NetLinx/Compile/Extension/APW.html
124
141
  - doc/NetLinx/Project.html
142
+ - doc/NetLinx/Rake.html
143
+ - doc/NetLinx/Rake/Workspace.html
144
+ - doc/NetLinx/Rake/Workspace/CreateWorkspaceConfig.html
145
+ - doc/NetLinx/Rake/Workspace/GenerateAPW.html
125
146
  - doc/NetLinx/System.html
126
147
  - doc/NetLinx/SystemFile.html
127
148
  - doc/NetLinx/Workspace.html
149
+ - doc/NetLinx/Workspace/YAML.html
128
150
  - doc/_index.html
129
151
  - doc/class_list.html
130
152
  - doc/css/common.css
@@ -140,14 +162,17 @@ files:
140
162
  - doc/js/jquery.js
141
163
  - doc/method_list.html
142
164
  - doc/top-level-namespace.html
143
- - lib/netlinx-workspace.rb
144
165
  - lib/netlinx/compile/extension/apw.rb
145
- - lib/netlinx/project.rb
146
- - lib/netlinx/system.rb
147
- - lib/netlinx/system_file.rb
166
+ - lib/netlinx/rake/workspace.rb
167
+ - lib/netlinx/rake/workspace/create_workspace_config.rb
168
+ - lib/netlinx/rake/workspace/generate_apw.rb
148
169
  - lib/netlinx/workspace.rb
170
+ - lib/netlinx/workspace/project.rb
171
+ - lib/netlinx/workspace/system.rb
172
+ - lib/netlinx/workspace/system_file.rb
173
+ - lib/netlinx/workspace/yaml.rb
149
174
  - license.txt
150
- homepage: https://sourceforge.net/projects/netlinx-workspace/
175
+ homepage: https://github.com/amclain/netlinx-workspace
151
176
  licenses:
152
177
  - Apache 2.0
153
178
  metadata: {}
@@ -167,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
192
  version: '0'
168
193
  requirements: []
169
194
  rubyforge_project:
170
- rubygems_version: 2.2.2
195
+ rubygems_version: 2.4.6
171
196
  signing_key:
172
197
  specification_version: 4
173
198
  summary: A library for working with AMX NetLinx Studio workspaces in Ruby.