smartdust-client 1.1.0 → 1.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5ad0e2e8968ddc2d92112ef56c8ad15403b99507f9699b45e18fd75c42adf76
4
- data.tar.gz: a44754161a3a0a3eb9ce069717c6c00e5ce2ffce12d00380c43764863172101d
3
+ metadata.gz: 816ea829cc813bc39511bf89151d1b059ba7acbe79ce3067f8a94fde987d363b
4
+ data.tar.gz: c564c0444b14986ca503408eea5d7b2686618ef3ddef7f3d509db0873f09d475
5
5
  SHA512:
6
- metadata.gz: 9ff4070a8ba7c49778a713b777e149487747a9aa28462f5cbc8bbbc7f0e8d918a344312f6652c49a4a6a2469fd4ab56d0ef09f4f6cb1b3feb1cb49598df3a7df
7
- data.tar.gz: 84bd40b60b759ea84d4b498c96b0a91c139be9bc398bb0de72c3cc71d89347b5713b0c502d034bc3e75edd25447bd38c36832263059b632754bf5dd8145ad03f
6
+ metadata.gz: c5b2abe3b36c04ec06a32eedc3fdb14b7952851e4e2b9ee693a312c2c78e2881c1bc588b9b51ed8554738d2ce0b27cbdb03db3274d34cd682d0a4ea8b0c9ab38
7
+ data.tar.gz: e8801265e92c781f29b7c50f0083dbdec4543e2063e9db7f279b0a612fe5572a7c653e6bd602f3a161ef725429cd53693089101e73b1ce2ecab602fcb1cc5c24
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smartdust-client (1.0.0)
4
+ smartdust-client (1.3.0)
5
5
  ADB (~> 0.5)
6
6
  dante (~> 0.2.0)
7
7
  dry-configurable (~> 0.1.4)
@@ -16,8 +16,9 @@ GEM
16
16
  childprocess (>= 0.3.5)
17
17
  addressable (2.8.1)
18
18
  public_suffix (>= 2.0.2, < 6.0)
19
- childprocess (4.1.0)
20
- concurrent-ruby (1.2.2)
19
+ childprocess (5.1.0)
20
+ logger (~> 1.5)
21
+ concurrent-ruby (1.3.5)
21
22
  crack (0.4.5)
22
23
  rexml
23
24
  dante (0.2.0)
@@ -29,9 +30,12 @@ GEM
29
30
  concurrent-ruby (~> 1.0)
30
31
  dry-configurable (~> 0.1, >= 0.1.3)
31
32
  facets (3.1.0)
32
- gli (2.21.0)
33
+ gli (2.22.2)
34
+ ostruct
33
35
  hashdiff (1.0.1)
34
36
  json (2.6.3)
37
+ logger (1.6.6)
38
+ ostruct (0.6.1)
35
39
  public_suffix (5.0.1)
36
40
  rack (1.6.13)
37
41
  rack-protection (1.5.5)
data/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  # Smartdust CLI client
6
6
  ![smartdust-logo-text-2021.png](smartdust-logo-text-2021.png)
7
+ Documentation: https://docs.smartdust.me/docs/cli-client.
8
+
7
9
  Automation client for connecting to Smartdust Lab devices via adb from a terminal.
8
10
  Designed with the following scenario in mind:
9
11
 
@@ -11,7 +13,7 @@ Designed with the following scenario in mind:
11
13
  2. Do something with the device via adb (Instrumentation Test, adb install, etc)
12
14
  3. Disconnect from device
13
15
 
14
- Due to it being a console tool, it's very easy to use it for test automation in a CI\CD pipeline, for example in Jenkins.
16
+ Due to it being a console tool, it's very easy to use it for test automation in a CI\CD pipeline, for example in Jenkins.
15
17
 
16
18
  Allows for filtering by any device description parameter
17
19
  as well as listing all available values of a given parameter
@@ -21,48 +23,61 @@ e.g. all unique names of devices in the lab instance.
21
23
  ## Prequisities
22
24
 
23
25
  - Ruby along with RubyGems installed - versions higher than 3.0.2 are not guaranteed to work
24
- - This repository cloned
26
+ - Android dependencies:
27
+ - adb (Android Debug Bridge)
28
+ - iOS dependencies:
29
+ - idevice_id (libimobiledevice)
30
+ - usbfluxd (https://github.com/corellium/usbfluxd/tree/master) (this needs to be patched to connect to multiple devices from the same Lab instance)
25
31
 
26
32
  ## Installation
27
- - Enter the directory where the repository is cloned
28
- - adding "sudo" before the following commands might be needed:
29
- - ```gem build smartdust-client.gemspec```
30
- - ```gem install smartdust-client-1.0.0.gem``` (or different version, see output of the previous command)
33
+ ### From RubyGems
34
+ - Install as a Ruby Gem:
35
+ ```gem install smartdust-client```
31
36
 
32
- - Run it by simply entering ```smartdust-client```
37
+ ### From sources
38
+ - Open your terminal
39
+ - "cd" into the directory where the repository is cloned
40
+ - Run the following commands: (adding "sudo" might be needed)
41
+ - ```gem build smartdust-client.gemspec```
42
+ - ```gem install smartdust-client-1.2.0.gem``` (or different version, see output of the previous command)
33
43
 
34
44
  ## Usage
35
45
 
36
46
  ```
37
47
  NAME
38
- stf-client - Smartphone Test Lab client
48
+ smartdust-client - Smartdust Lab client (version 1.2.0)
39
49
 
40
50
  SYNOPSIS
41
- stf-client [global options] command [command options] [arguments...]
51
+ smartdust-client [global options] command [command options] [arguments...]
42
52
 
43
53
  GLOBAL OPTIONS
44
54
  --help - Show this message
45
- -t, --token=arg - Authorization token, can also be set by environment variable STF_TOKEN (default: none)
46
- -u, --url=arg - URL to STF, can also be set by environment variable STF_URL (default: none)
55
+ --log=arg - Log file (default: none)
56
+ --pid=arg - PID file (default: none)
57
+ -t, --token=arg - Authorization token, can also be set by environment variable SD_TOKEN (default: none)
58
+ -u, --url=arg - URL to Smartdust Lab, can also be set by environment variable SD_URL (default: none)
47
59
  -v, --[no-]verbose - Be verbose
48
60
 
49
61
  COMMANDS
50
- clean - Frees all devices that are assigned to current user in STF. Doesn't modify local adb
51
- connect - Search for a device available in STF and attach it to local adb server
52
- disconnect - Disconnect device(s) from local adb server and remove device(s) from user devices in STF
62
+ clean - Frees all devices that are assigned to current user in Smartdust Lab. Doesn't modify local adb
63
+ connect - Search for a device available in Smartdust Lab and attach it to local adb server
64
+ disconnect - Disconnect device(s) from local adb server and remove device(s) from user devices in Smartdust Lab
53
65
  help - Shows a list of commands or help for one command
54
66
  keys - Show available keys for filtering
67
+ trustme - Add adb public key into Smartdust Lab
55
68
  values - Show known values for the filtering key
56
-
57
- ENVIRONMENT VARIABLES
58
- STF_TOKEN - Authorization token
59
- STF_URL - URL to STF
60
69
  ```
61
70
  - Authorization token can be obtained from the Smartdust Lab web interface in Settings -> Keys
62
71
  - When connecting with this tool for the first time, have the Smartdust Lab web interface open
63
72
  to accept adding a new ADB key. This is necessary for every new machine that hasn't connected
64
73
  yet to Remote Debug on a given Lab instance.
65
74
 
75
+ ## Development
76
+ - Install Ruby 3.0.2
77
+ - Install Ruby Bundler: ```gem install bundler -v 1.17.3```
78
+ - Run ```bundle install``` in the project directory (might require adjusting directory permissions or sudo)
79
+ - Run the program with ```bundle exec ruby lib/stf.rb```
80
+
66
81
  ## License
67
82
 
68
83
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/lib/di.rb CHANGED
@@ -10,8 +10,8 @@ require 'stf/interactor/remove_all_user_devices_interactor'
10
10
  require 'stf/interactor/get_keys_interactor'
11
11
  require 'stf/interactor/get_values_interactor'
12
12
  require 'stf/interactor/add_adb_public_key'
13
+ require 'stf/interactor/connect_ios_interactor'
13
14
  require 'stf/validate/uri_validator'
14
- require 'stf/model/device_enhancer'
15
15
 
16
16
  class DI
17
17
  class << self
@@ -22,7 +22,7 @@ class DI
22
22
 
23
23
  # one time object
24
24
  c.register(:dante_runner,
25
- -> {Dante::Runner.new('stf-client')})
25
+ -> {Dante::Runner.new('smartdust-client')})
26
26
 
27
27
  # one time object because dante is one time
28
28
  c.register(:demonizer,
@@ -70,8 +70,13 @@ class DI
70
70
  c.register(:add_adb_public_key_interactor,
71
71
  -> {Stf::AddAdbPublicKeyInteractor.new},
72
72
  memoize: true)
73
- c.register(:device_enhancer,
74
- -> {Stf::DeviceEnhancer.new},
73
+
74
+ c.register(:connect_ios,
75
+ -> {Stf::ConnectIosInteractor.new},
76
+ memoize: true)
77
+
78
+ c.register(:android_util,
79
+ -> {Stf::AndroidUtil.new},
75
80
  memoize: true)
76
81
  end
77
82
 
@@ -83,4 +88,4 @@ class DI
83
88
  @@container
84
89
  end
85
90
  end
86
- end
91
+ end
data/lib/stf/client.rb CHANGED
@@ -55,7 +55,7 @@ module Stf
55
55
  end
56
56
 
57
57
  def destroy_tunnel(ip, port)
58
- response = execute "/api/v1/tunnel", Net::HTTP::Delete, {ipAddress: ip, port: port}.to_json
58
+ response = execute "/api/v1/tunnel/{ip}/{port}", Net::HTTP::Delete, {ipAddress: ip, port: port}.to_json
59
59
  return response.success
60
60
  end
61
61
 
@@ -0,0 +1,45 @@
1
+ require 'ADB'
2
+ module Stf
3
+ class AndroidUtil
4
+ include ADB
5
+
6
+ def get_present_adb_devices_ids
7
+ adb_out = `adb devices`
8
+ adb_out = adb_out.split("\n")
9
+ adb_out.shift
10
+ adb_out = adb_out.select { |line| line.include? 'device' }
11
+ adb_out.map! { |line| line.split("\t").first }
12
+ end
13
+
14
+ def map_adb_urls_to_serial
15
+ adb_urls = get_present_adb_devices_ids
16
+ urls_to_serials = Hash.new
17
+ adb_urls.each do |adb_url|
18
+ serial = `adb -s #{adb_url} shell getprop ro.serialno`
19
+ serial = serial.strip
20
+ urls_to_serials[adb_url] = serial
21
+ end
22
+ urls_to_serials
23
+ end
24
+
25
+ def map_serials_to_adb_urls
26
+ adb_urls = get_present_adb_devices_ids
27
+ serials_to_urls = Hash.new
28
+ adb_urls.each do |adb_url|
29
+ serial = `adb -s #{adb_url} shell getprop ro.serialno`
30
+ serial = serial.strip
31
+ serials_to_urls[serial] = adb_url
32
+ end
33
+ serials_to_urls
34
+ end
35
+
36
+ def cleanup_adb_devices
37
+ to_disconnect = devices - get_present_adb_devices_ids
38
+ to_disconnect.each do |id|
39
+ execute_adb_with 30, "disconnect #{id}"
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,74 @@
1
+ require 'rexml/document'
2
+ require 'open3'
3
+ require 'mkmf'
4
+
5
+ require 'stf/log/log'
6
+
7
+ module Stf
8
+ class ConnectIosInteractor
9
+ include Log
10
+
11
+ @active = false
12
+
13
+ def initialize
14
+ if find_executable('usbfluxctl') != nil
15
+ stdout, stderr, status = Open3.capture3("usbfluxctl list xml")
16
+ unless stderr.include? "Failed"
17
+ @active = true
18
+ end
19
+ end
20
+ unless @active
21
+ logger.info "iOS dependencies not available. Install 'usbfluxd' distributed by SmartDust. Make sure to start 'usbfluxd -n' with root permissions before connecting to iOS devices. Also ensure that 'usbfluxctl' is in your $PATH."
22
+ end
23
+ end
24
+
25
+
26
+ def connect(url)
27
+ raise "iOS connecting is not active" unless @active
28
+ Open3.capture3("usbfluxctl add #{url}")
29
+ sleep(1)
30
+ logger.info ios_serials_to_urls.to_s
31
+ unless ios_serials_to_urls.values.include? url
32
+ raise "Cannot connect to iOS device"
33
+ end
34
+ end
35
+
36
+ def disconnect(url)
37
+ raise "iOS connecting is not active" unless @active
38
+ Open3.capture3("usbfluxctl del #{url}")
39
+ end
40
+
41
+ def ios_serials_to_urls
42
+ return {} unless @active
43
+ stdout, stderr, status = Open3.capture3("usbfluxctl list xml")
44
+ result = {}
45
+
46
+ doc = REXML::Document.new(stdout)
47
+ instances = doc.elements['plist/dict/dict']
48
+
49
+ if instances.nil?
50
+ return {}
51
+ end
52
+
53
+ instances.elements.each('dict') do |instance|
54
+ host = instance.elements["string[preceding-sibling::key[text()='Host']]"]
55
+ port = instance.elements["integer[preceding-sibling::key[text()='Port']]"]
56
+ if host.nil? || port.nil?
57
+ next
58
+ end
59
+ url = "#{host.text}:#{port.text}"
60
+
61
+ devices = instance.elements['array']
62
+ if devices
63
+ devices.elements.each do |device|
64
+ serial = device.text
65
+ result[serial] = url
66
+ end
67
+ end
68
+ end
69
+
70
+ result
71
+ end
72
+
73
+ end
74
+ end
@@ -1,8 +1,11 @@
1
1
  require 'ADB'
2
2
 
3
+ require 'di'
3
4
  require 'stf/client'
4
5
  require 'stf/log/log'
5
6
  require 'stf/model/device_list'
7
+ require 'stf/interactor/connect_ios_interactor'
8
+ require 'stf/interactor/android_util'
6
9
 
7
10
  module Stf
8
11
  class StartDebugSessionInteractor
@@ -44,8 +47,8 @@ module Stf
44
47
  return false
45
48
  end
46
49
 
47
- connected_count = count_connected_devices(filter)
48
- logger.info "Lower quantity achieved, already connected #{connected_count}"
50
+ connected_count = count_connected_devices(filter, force_filter)
51
+ logger.info "Number of connected devices: #{connected_count}"
49
52
 
50
53
  return true if nodaemon_flag
51
54
 
@@ -80,7 +83,7 @@ module Stf
80
83
  one_time_mode = !daemon_mode
81
84
 
82
85
  while true do
83
- cleanup_disconnected_devices(filter, force_filter, healthcheck)
86
+ DI[:stop_all_debug_sessions_interactor].disconnect_unwanted_devices(filter, force_filter, healthcheck)
84
87
 
85
88
  if one_time_mode && Time.now > finish_time
86
89
  raise "Connect loop timeout reached"
@@ -94,7 +97,7 @@ module Stf
94
97
  if all_flag
95
98
  to_connect = stf_devices.size
96
99
  else
97
- connected = devices & all_devices.as_connect_url_list
100
+ connected = (DI[:android_util].get_present_adb_devices_ids + DI[:connect_ios].ios_serials_to_urls.keys)
98
101
  to_connect = wanted - connected.size
99
102
  end
100
103
 
@@ -114,43 +117,13 @@ module Stf
114
117
  end
115
118
  end
116
119
 
117
- def count_connected_devices(filter)
120
+ def count_connected_devices(filter, force_filter)
118
121
  stf_devices = DeviceList.new(DI[:stf].get_user_devices)
119
- stf_devices = stf_devices.by_filter(filter) if filter
120
- connected = devices & stf_devices.as_connect_url_list
121
- connected.size
122
+ stf_devices = stf_devices.by_filter(filter) if filter && force_filter
123
+ connected = (DI[:android_util].map_serials_to_adb_urls.keys + DI[:connect_ios].ios_serials_to_urls.keys)
124
+ connected_filtered = stf_devices.asArray.map {|d| d.serial} & connected
125
+ connected_filtered.size
122
126
  end
123
127
 
124
- def cleanup_disconnected_devices(filter, force_filter, healthcheck)
125
- to_disconnect = []
126
- stf_devices = DeviceList.new(DI[:stf].get_user_devices)
127
-
128
- if filter && force_filter
129
- disconnect_because_filter = stf_devices.except_filter(filter).as_connect_url_list
130
- unless disconnect_because_filter.empty?
131
- logger.info 'will be disconnected by filter: ' + disconnect_because_filter.join(',')
132
- to_disconnect += disconnect_because_filter
133
- end
134
- end
135
-
136
- if healthcheck
137
- disconnect_by_health = stf_devices.select_not_healthy(healthcheck).as_connect_url_list
138
- unless disconnect_by_health.empty?
139
- logger.info 'will be disconnected by health check: ' + disconnect_by_health.join(',')
140
- to_disconnect += disconnect_by_health
141
- end
142
- end
143
-
144
- dead_persons = stf_devices.as_connect_url_list - devices
145
- unless dead_persons.empty?
146
- logger.info 'will be disconnected because not present locally: ' + dead_persons.join(',')
147
- to_disconnect += dead_persons
148
- end
149
-
150
- to_disconnect.reject {|url| url.to_s.empty?}.uniq.each do |url|
151
- logger.info 'Cleanup the device ' + url.to_s
152
- DI[:stop_debug_session_interactor].execute(url)
153
- end
154
- end
155
128
  end
156
129
  end
@@ -42,12 +42,19 @@ module Stf
42
42
  logger.error "Can't open tunnel to provider with IP #{provider_ip}"
43
43
  raise
44
44
  end
45
- remote_connect_tunneled_url = DI[:device_enhancer].get_tunneled_remote_connect_url(device)
45
+ remote_connect_tunneled_url = remote_connect_url_split[0] + ":" + result.port.to_s
46
46
  logger.info remote_connect_tunneled_url
47
- execute_adb_with 30, "connect #{remote_connect_tunneled_url}"
48
47
 
49
- shell('echo adbtest', {serial: "#{remote_connect_tunneled_url}"}, 30)
50
- raise ADBError, "Could not execute shell test" unless stdout_contains "adbtest"
48
+ case device.getValue "platform"
49
+ when "Android"
50
+ execute_adb_with 30, "connect #{remote_connect_tunneled_url}"
51
+ shell('echo adbtest', {serial: "#{remote_connect_tunneled_url}"}, 30)
52
+ raise ADBError, "Could not execute shell test" unless stdout_contains "adbtest"
53
+ when "iOS"
54
+ DI[:connect_ios].connect(remote_connect_tunneled_url)
55
+ else
56
+ logger.error "Unrecognized device platform"
57
+ end
51
58
 
52
59
  return true
53
60
 
@@ -73,4 +80,4 @@ module Stf
73
80
  s.gsub(/["]/, '\"').gsub(/[ ]/, '\ ').gsub(/[=]/, '\=').gsub(/[,]/, '\,')
74
81
  end
75
82
  end
76
- end
83
+ end
@@ -5,6 +5,7 @@ require 'stf/client'
5
5
  require 'stf/log/log'
6
6
  require 'stf/interactor/stop_debug_session_interactor'
7
7
  require 'stf/model/device_list'
8
+ require 'stf/interactor/android_util'
8
9
 
9
10
  module Stf
10
11
  class StopAllDebugSessionsInteractor
@@ -16,12 +17,51 @@ module Stf
16
17
  DI[:demonizer].kill unless options[:nokill]
17
18
 
18
19
  stf_devices = DeviceList.new(DI[:stf].get_user_devices)
19
-
20
20
  stf_devices = stf_devices.by_filter options[:byFilter] if options[:byFilter]
21
+ stf_devices.asArray.each {|d| DI[:stop_debug_session_interactor].execute d}
22
+ end
23
+
24
+ def disconnect_unwanted_devices(filter, force_filter, healthcheck)
25
+ DI[:android_util].cleanup_adb_devices
26
+ to_disconnect = [] # array of device serials
27
+ active_user_devices = DeviceList.new(DI[:stf].get_user_devices)
28
+ adb_serials_to_urls = DI[:android_util].map_serials_to_adb_urls
29
+
30
+ if filter && force_filter
31
+ disconnect_because_filter = active_user_devices.except_filter(filter).asArray.map { |d| d.serial }
32
+ unless disconnect_because_filter.empty?
33
+ logger.info 'will be disconnected by filter: ' + disconnect_because_filter.join(',')
34
+ to_disconnect += disconnect_because_filter
35
+ end
36
+ end
21
37
 
22
- pending_disconnect = stf_devices.as_connect_url_list
38
+ if healthcheck
39
+ disconnect_by_health = active_user_devices.select_not_healthy(healthcheck).asArray.map { |d| d.serial }
40
+ unless disconnect_by_health.empty?
41
+ logger.info 'will be disconnected by health check: ' + disconnect_by_health.join(',')
42
+ to_disconnect += disconnect_by_health
43
+ end
44
+ end
23
45
 
24
- pending_disconnect.each {|d| DI[:stop_debug_session_interactor].execute d}
46
+ dead_persons = active_user_devices.asArray.map { |d| d.serial } - (adb_serials_to_urls.keys + DI[:connect_ios].ios_serials_to_urls.keys)
47
+ unless dead_persons.empty?
48
+ logger.info 'will be disconnected because not present locally: ' + dead_persons.join(',')
49
+ to_disconnect += dead_persons
50
+ end
51
+
52
+ without_active_session = (adb_serials_to_urls.keys + DI[:connect_ios].ios_serials_to_urls.keys) - active_user_devices.asArray.map{ |d| d.serial }
53
+ unless without_active_session.empty?
54
+ logger.info 'will be disconnected because session is not active in SmartDust Lab: ' + without_active_session.join(',')
55
+ to_disconnect += without_active_session
56
+ end
57
+
58
+ DeviceList.new(DI[:stf].get_devices).asArray.filter {|device|
59
+ to_disconnect.include? device.serial
60
+ }.each do |device|
61
+ logger.info 'Cleanup the device ' + device.serial
62
+ DI[:stop_debug_session_interactor].execute(device)
63
+ end
25
64
  end
65
+
26
66
  end
27
67
  end
@@ -9,46 +9,44 @@ module Stf
9
9
  include Log
10
10
  include ADB
11
11
 
12
- def execute(remote_connect_url)
13
- remote_devices = DI[:stf].get_user_devices
14
- device = remote_devices.find {|d| d.remoteConnect == true && DI[:device_enhancer].get_tunneled_remote_connect_url(d).eql?(remote_connect_url)}
12
+ def execute(device)
15
13
 
16
- # try to disconnect anyway
17
- execute_adb_with 30, "disconnect #{remote_connect_url}"
18
-
19
- if device.nil?
20
- logger.error "Device #{remote_connect_url} is not available"
21
- return false
14
+ if DI[:connect_ios].ios_serials_to_urls.keys.include? device.serial
15
+ DI[:connect_ios].disconnect(DI[:connect_ios].ios_serials_to_urls[device.serial])
16
+ elsif devices.include? device.serial
17
+ execute_adb_with 30, "disconnect #{remote_connect_url}"
22
18
  end
23
19
 
24
- success = false
25
-
26
- 1..10.times do
27
- begin
28
- success = DI[:stf].stop_debug(device.serial)
29
- break if success
30
- rescue
20
+ if DeviceList.new(DI[:stf].get_user_devices).asArray.map {|d| d.serial}.include? device.serial
21
+ success = false
22
+ 1..10.times do
23
+ begin
24
+ success = DI[:stf].stop_debug(device.serial)
25
+ break if success
26
+ rescue
27
+ end
28
+
29
+ logger.error 'Can\'t stop debug session. Retrying'
30
+ end
31
+
32
+ 1..10.times do
33
+ begin
34
+ success = DI[:stf].remove_device(device.serial)
35
+ break if success
36
+ rescue
37
+ end
38
+ logger.error 'Can\'t remove device from user devices. Retrying'
31
39
  end
32
40
 
33
- logger.error 'Can\'t stop debug session. Retrying'
34
- end
35
-
36
- 1..10.times do
37
- begin
38
- success = DI[:stf].remove_device(device.serial)
39
- break if success
40
- rescue
41
+ if success
42
+ logger.info "Successfully removed #{device.serial}"
43
+ else
44
+ logger.error "Error removing #{device.serial}"
41
45
  end
42
- logger.error 'Can\'t remove device from user devices. Retrying'
43
- end
44
-
45
- if success
46
- logger.info "Successfully removed #{remote_connect_url}"
47
- else
48
- logger.error "Error removing #{remote_connect_url}"
49
46
  end
50
47
 
51
48
  success
52
49
  end
53
50
  end
51
+
54
52
  end
@@ -52,11 +52,6 @@ module Stf
52
52
  }
53
53
  end
54
54
 
55
- def as_connect_url_list
56
- @devices.reject { |d| d.remoteConnectUrl.nil? || d.remoteConnectUrl.empty? }
57
- .map{|d| DI[:device_enhancer].get_tunneled_remote_connect_url(d)}
58
- end
59
-
60
55
  def select
61
56
  DeviceList.new(@devices.select {|d| yield(d)})
62
57
  end
data/lib/stf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Stf
2
- VERSION = '1.1.0'
2
+ VERSION = '1.3.1'
3
3
  end
data/lib/stf/view/cli.rb CHANGED
@@ -2,8 +2,10 @@ module Stf
2
2
  module CLI
3
3
  require 'di'
4
4
  require 'gli'
5
+ require 'stf/log/log'
5
6
 
6
7
  include GLI::App
8
+ include Log
7
9
 
8
10
  extend self
9
11
 
@@ -105,8 +107,7 @@ module Stf
105
107
  desc 'Add adb public key into Smartdust Lab'
106
108
  command :trustme do |c|
107
109
  c.desc 'Location of adb public key'
108
- c.flag [:k, :adb_public_key_location]
109
- c.default_value '~/.android/adbkey.pub'
110
+ c.flag [:k, :adb_public_key_location], :default_value => '~/.android/adbkey.pub'
110
111
 
111
112
  c.action do |_, options, _|
112
113
  filename = File.expand_path(options[:adb_public_key_location])
@@ -117,5 +118,4 @@ module Stf
117
118
 
118
119
  exit run(ARGV)
119
120
  end
120
- end
121
-
121
+ end
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Smartdust']
10
10
  spec.email = ['jordan@smartdust.me']
11
11
  spec.summary = %q{Connect to devices from Smartdust Lab via adb from cli}
12
- spec.homepage = 'https://github.com/jordus100/stf-client'
12
+ spec.homepage = 'https://docs.smartdust.me/docs/cli-client'
13
13
  spec.license = 'MIT'
14
14
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
15
  spec.require_paths = ['lib']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartdust-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Smartdust
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-31 00:00:00.000000000 Z
11
+ date: 2025-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli
@@ -229,6 +229,8 @@ files:
229
229
  - lib/stf.rb
230
230
  - lib/stf/client.rb
231
231
  - lib/stf/interactor/add_adb_public_key.rb
232
+ - lib/stf/interactor/android_util.rb
233
+ - lib/stf/interactor/connect_ios_interactor.rb
232
234
  - lib/stf/interactor/get_keys_interactor.rb
233
235
  - lib/stf/interactor/get_values_interactor.rb
234
236
  - lib/stf/interactor/remove_all_user_devices_interactor.rb
@@ -238,7 +240,6 @@ files:
238
240
  - lib/stf/interactor/stop_debug_session_interactor.rb
239
241
  - lib/stf/log/log.rb
240
242
  - lib/stf/model/device.rb
241
- - lib/stf/model/device_enhancer.rb
242
243
  - lib/stf/model/device_list.rb
243
244
  - lib/stf/system/demonizer.rb
244
245
  - lib/stf/validate/uri_validator.rb
@@ -246,7 +247,7 @@ files:
246
247
  - lib/stf/view/cli.rb
247
248
  - smartdust-client.gemspec
248
249
  - smartdust-logo-text-2021.png
249
- homepage: https://github.com/jordus100/stf-client
250
+ homepage: https://docs.smartdust.me/docs/cli-client
250
251
  licenses:
251
252
  - MIT
252
253
  metadata: {}
@@ -1,17 +0,0 @@
1
- module Stf
2
- class DeviceEnhancer
3
- def get_tunneled_remote_connect_url(device)
4
- provider = device.provider
5
- provider_ip = provider["ip"]
6
- result = DI[:stf].start_debug device.serial
7
- remote_connect_url_split = result.remoteConnectUrl.split ":"
8
- remote_connect_port = remote_connect_url_split[1]
9
- result = DI[:stf].check_tunnel provider_ip, remote_connect_port
10
- if result.success
11
- remote_connect_hostname = remote_connect_url_split[0]
12
- remote_connect_hostname + ":" + result.port.to_s
13
- else nil
14
- end
15
- end
16
- end
17
- end