netlinx-workspace 0.3.0 → 1.0.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.
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.