lerna 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7d1d9ed67341c040754c33479daf18d66bd4fc7
4
- data.tar.gz: fc89547a2e6c6e55f437a82ad08bbdfa6589db80
3
+ metadata.gz: 1bed2261a5c6fe13da1642a415bf00be782cb2c0
4
+ data.tar.gz: 7519c43ab8c1864464ef4f87f6b5bf327d52d88f
5
5
  SHA512:
6
- metadata.gz: f8a4dd8509a4dd6771765971b1cfc2d6da6a877eb7f53f1a5641cb86631d0f4a06bf75570c8c796aa5c97a5c760457968b1ffe4f3c3900e78f040de6ca91e693
7
- data.tar.gz: a54b275de9b370169e08117af82271f44b7c7f0227a589243dfa726b8604d490dadf6dce116c25cfbc20a3834240857c7b3eae276a6eb0e2f8cde19cdc7c28c4
6
+ metadata.gz: 35c9bd3b9c74caace613f476f53558764244d85695ee2c6ff9cab9b1281232c72e88190621291248e5b0e77efb9906702ff4e4f741b3107cc89d7fb95f004190
7
+ data.tar.gz: 60e17fcf3419825ea7972290119afdeb11f99244ddb9d72b7d31664233559f21a49e565052d108e22b8875fc785641d00cee93dfe711a4aba1c2beae285a3047
data/bin/lerna CHANGED
@@ -1,17 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'logger'
3
4
  require 'optparse'
4
5
  require 'lerna/runner'
5
6
  require 'lerna/strategy'
6
7
 
7
- LOGGER = lambda { |str|
8
- time = Time.now.utc
9
- timestamp = time.strftime('%Y-%m-%dT%H:%M:%S.') << '%06dZ' % time.usec
10
- puts '[%s #%d] %s' % [timestamp, Process.pid, str]
11
- }
8
+ logger = Logger.new(STDOUT)
9
+ logger.level = Logger::INFO
12
10
 
13
11
  options = {
14
- strategies: %w[ dual-external external-digital-only internal-only ],
12
+ strategies: %w[ wall external-only internal-only ],
15
13
  system: method(:system)
16
14
  }
17
15
 
@@ -20,7 +18,7 @@ executable = File.basename(__FILE__)
20
18
  parser = OptionParser.new { |opts|
21
19
  opts.banner = "Usage: #{executable} [options]"
22
20
  opts.on(
23
- '-s', '--strategies', String,
21
+ '-s', '--strategies STRATEGIES', String,
24
22
  'Strategies in order of precedence, separated by commas',
25
23
  "Default is #{options[:strategies].join(',')}",
26
24
  "Available: #{Lerna::Strategy.registry.keys.join(' ')}"
@@ -34,8 +32,14 @@ parser = OptionParser.new { |opts|
34
32
  options[:system] = ->(*args) { LOGGER.call(args.join(' ')) }
35
33
  end
36
34
  opts.on(
37
- "-h", "--help",
38
- "Display this help message and exit"
35
+ '-v', '--verbose',
36
+ 'Log debugging information'
37
+ ) do
38
+ logger.level = Logger::DEBUG
39
+ end
40
+ opts.on(
41
+ '-h', '--help',
42
+ 'Display this help message and exit'
39
43
  ) do
40
44
  puts opts
41
45
  exit
@@ -44,13 +48,13 @@ parser = OptionParser.new { |opts|
44
48
  parser.parse!
45
49
 
46
50
  runner = Lerna::Runner.new(
47
- logger: LOGGER,
51
+ logger: logger,
48
52
  strategies: options[:strategies],
49
53
  system: options[:system]
50
54
  )
51
55
 
52
56
  trap('TERM') {
53
- LOGGER.call('Exiting')
57
+ logger.info('Exiting')
54
58
  exit
55
59
  }
56
60
 
@@ -16,23 +16,19 @@ module Lerna
16
16
  state.scan!
17
17
  return unless state.changed?
18
18
 
19
- log state_summary
19
+ logger.debug state_summary
20
20
  strategy = find_strategy
21
21
  if strategy
22
- log "Using #{strategy.class}"
22
+ logger.info "Using #{strategy.class}"
23
23
  apply_strategy strategy
24
24
  else
25
- log 'No applicable strategy found'
25
+ logger.warn 'No applicable strategy found'
26
26
  end
27
27
  end
28
28
 
29
29
  private
30
30
 
31
- attr_reader :state, :strategy_selector, :strategies
32
-
33
- def log(s)
34
- @logger.call(s)
35
- end
31
+ attr_reader :state, :strategy_selector, :strategies, :logger
36
32
 
37
33
  def state_summary
38
34
  state.displays.
@@ -45,11 +41,13 @@ module Lerna
45
41
  end
46
42
 
47
43
  def apply_strategy(strategy)
48
- system 'xrandr', *strategy.configuration
44
+ system 'xrandr', *strategy.preconfigure
45
+ system 'xrandr', *strategy.configure
49
46
  system 'xset dpms force on'
50
47
  end
51
48
 
52
49
  def system(*args)
50
+ logger.debug args.join(' ')
53
51
  @system.call(*args)
54
52
  end
55
53
  end
@@ -1,4 +1,12 @@
1
- Dir[File.expand_path('../strategies/*.rb', __FILE__)].each do |path|
2
- name = File.basename(path, '.rb')
3
- require "lerna/strategies/#{name}"
4
- end
1
+ require 'lerna/strategy'
2
+ require 'lerna/strategies/external_digital_only'
3
+ require 'lerna/strategies/internal_only'
4
+ require 'lerna/strategies/portrait_wall'
5
+ require 'lerna/strategies/wall'
6
+
7
+ Lerna::Strategy.register(
8
+ 'external-only' => Lerna::Strategies::ExternalDigitalOnly,
9
+ 'internal-only' => Lerna::Strategies::InternalOnly,
10
+ 'portrait-wall' => Lerna::Strategies::PortraitWall,
11
+ 'wall' => Lerna::Strategies::Wall
12
+ )
@@ -7,14 +7,13 @@ module Lerna
7
7
  winner
8
8
  end
9
9
 
10
- def configuration
11
- [].tap { |conf|
12
- disconnected = displays - [winner]
13
- disconnected.each do |d|
14
- conf << '--output' << d.name << '--off'
15
- end
16
- conf << '--output' << winner.name << '--auto'
17
- }
10
+ def preconfigure
11
+ disconnected = displays - [winner]
12
+ disconnected.flat_map { |d| ['--output', d.name, '--off'] }
13
+ end
14
+
15
+ def configure
16
+ ['--output', winner.name, '--auto']
18
17
  end
19
18
 
20
19
  private
@@ -7,14 +7,15 @@ module Lerna
7
7
  displays.select(&:connected?).all?(&:internal?)
8
8
  end
9
9
 
10
- def configuration
11
- [].tap { |conf|
12
- displays.reject(&:connected?).each do |d|
13
- conf << '--output' << d.name << '--off'
14
- end
15
- displays.select(&:connected?).each do |d|
16
- conf << '--output' << d.name << '--auto'
17
- end
10
+ def preconfigure
11
+ displays.reject(&:connected?).flat_map { |d|
12
+ ['--output', d.name, '--off']
13
+ }
14
+ end
15
+
16
+ def configure
17
+ displays.select(&:connected?).flat_map { |d|
18
+ ['--output', d.name, '--auto']
18
19
  }
19
20
  end
20
21
  end
@@ -0,0 +1,13 @@
1
+ require 'lerna/strategies/wall'
2
+
3
+ module Lerna
4
+ module Strategies
5
+ class PortraitWall < Wall
6
+ private
7
+
8
+ def configure_one(name)
9
+ ['--output', name, '--auto', '--rotate', 'left']
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ require 'lerna/strategy'
2
+
3
+ module Lerna
4
+ module Strategies
5
+ class Wall < Strategy
6
+ def applicable?
7
+ wanted_displays.length >= 2
8
+ end
9
+
10
+ def preconfigure
11
+ disconnected = displays - wanted_displays
12
+ disconnected.flat_map { |d|
13
+ ['--output', d.name, '--off']
14
+ }
15
+ end
16
+
17
+ def configure
18
+ names = wanted_displays.map(&:name)
19
+ leftmost = configure_one(names.first)
20
+ names.each_cons(2).inject(leftmost) { |a, (l, r)|
21
+ a + configure_one(r) + ['--right-of', l]
22
+ }
23
+ end
24
+
25
+ private
26
+
27
+ def wanted_displays
28
+ displays.
29
+ select(&:connected?).
30
+ select { |d| d.external? && d.digital? }.
31
+ sort_by(&:name)
32
+ end
33
+
34
+ def configure_one(name)
35
+ ['--output', name, '--auto', '--rotate', 'normal']
36
+ end
37
+ end
38
+ end
39
+ end
@@ -4,10 +4,8 @@ module Lerna
4
4
  @registry ||= {}
5
5
  end
6
6
 
7
- def self.inherited(subclass)
8
- name = subclass.to_s.split(/::/).last
9
- hyphenated = name.scan(/[A-Z][a-z_0-9]+/).map(&:downcase).join('-')
10
- registry[hyphenated] = subclass
7
+ def self.register(names_and_classes)
8
+ registry.merge!(names_and_classes)
11
9
  end
12
10
 
13
11
  def initialize(displays)
@@ -1,3 +1,3 @@
1
1
  module Lerna
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -22,11 +22,16 @@ RSpec.describe Lerna::Strategies::ExternalDigitalOnly do
22
22
  it { is_expected.to be_applicable }
23
23
 
24
24
  it 'configures the connected external display' do
25
- expect(subject.configuration).to eq(%w[
25
+ expect(subject.configure).to eq(%w[
26
+ --output DP1 --auto
27
+ ])
28
+ end
29
+
30
+ it 'disables all other displays' do
31
+ expect(subject.preconfigure).to eq(%w[
26
32
  --output LVDS1 --off
27
33
  --output DP2 --off
28
34
  --output VGA1 --off
29
- --output DP1 --auto
30
35
  ])
31
36
  end
32
37
  end
@@ -16,11 +16,16 @@ RSpec.describe Lerna::Strategies::InternalOnly do
16
16
  it { is_expected.to be_applicable }
17
17
 
18
18
  it 'configures the internal display' do
19
- expect(subject.configuration).to eq(%w[
20
- --output DP1 --off
19
+ expect(subject.configure).to eq(%w[
21
20
  --output LVDS1 --auto
22
21
  ])
23
22
  end
23
+
24
+ it 'disables all other displays' do
25
+ expect(subject.preconfigure).to eq(%w[
26
+ --output DP1 --off
27
+ ])
28
+ end
24
29
  end
25
30
 
26
31
  context 'when an internal and an external display are connected' do
@@ -0,0 +1,89 @@
1
+ require 'lerna/strategies/portrait_wall'
2
+
3
+ RSpec.describe Lerna::Strategies::PortraitWall do
4
+ subject {
5
+ described_class.new(displays)
6
+ }
7
+
8
+ context 'when fewer than two external digital displays are connected' do
9
+ let(:displays) {
10
+ [
11
+ double(name: 'LVDS1', external?: false,
12
+ connected?: true, digital?: true),
13
+ double(name: 'DP1', external?: true,
14
+ connected?: true, digital?: true),
15
+ double(name: 'DP2', external?: true,
16
+ connected?: false, digital?: true),
17
+ double(name: 'VGA1', external?: true,
18
+ connected?: false, digital?: false)
19
+ ]
20
+ }
21
+
22
+ it { is_expected.not_to be_applicable }
23
+ end
24
+
25
+ context 'when two external digital displays are connected' do
26
+ let(:displays) {
27
+ [
28
+ double(name: 'LVDS1', external?: false,
29
+ connected?: true, digital?: true),
30
+ double(name: 'DP1', external?: true,
31
+ connected?: true, digital?: true),
32
+ double(name: 'DP2', external?: true,
33
+ connected?: true, digital?: true),
34
+ double(name: 'VGA1', external?: true,
35
+ connected?: false, digital?: false)
36
+ ]
37
+ }
38
+
39
+ it { is_expected.to be_applicable }
40
+
41
+ it 'configures the connected external displays in alphanumeric order' do
42
+ expect(subject.configure).to eq(%w[
43
+ --output DP1 --auto --rotate left
44
+ --output DP2 --auto --rotate left --right-of DP1
45
+ ])
46
+ end
47
+
48
+ it 'disables all other displays' do
49
+ expect(subject.preconfigure).to eq(%w[
50
+ --output LVDS1 --off
51
+ --output VGA1 --off
52
+ ])
53
+ end
54
+ end
55
+
56
+ context 'when three external digital displays are connected' do
57
+ let(:displays) {
58
+ [
59
+ double(name: 'LVDS1', external?: false,
60
+ connected?: true, digital?: true),
61
+ double(name: 'HDMI1', external?: true,
62
+ connected?: true, digital?: true),
63
+ double(name: 'DP1', external?: true,
64
+ connected?: true, digital?: true),
65
+ double(name: 'DP2', external?: true,
66
+ connected?: true, digital?: true),
67
+ double(name: 'VGA1', external?: true,
68
+ connected?: false, digital?: false)
69
+ ]
70
+ }
71
+
72
+ it { is_expected.to be_applicable }
73
+
74
+ it 'configures the connected external displays in alphanumeric order' do
75
+ expect(subject.configure).to eq(%w[
76
+ --output DP1 --auto --rotate left
77
+ --output DP2 --auto --rotate left --right-of DP1
78
+ --output HDMI1 --auto --rotate left --right-of DP2
79
+ ])
80
+ end
81
+
82
+ it 'disables all other displays' do
83
+ expect(subject.preconfigure).to eq(%w[
84
+ --output LVDS1 --off
85
+ --output VGA1 --off
86
+ ])
87
+ end
88
+ end
89
+ end
@@ -10,7 +10,7 @@ RSpec.describe Lerna::Runner do
10
10
  strategy_selector: strategy_selector
11
11
  )
12
12
  }
13
- let(:logger) { double('logger', call: nil) }
13
+ let(:logger) { double('logger', debug: nil, info: nil, warn: nil) }
14
14
  let(:system) { double('system', call: nil) }
15
15
  let(:strategies) { double('strategies') }
16
16
  let(:strategy_selector) { double('strategy_selector', call: nil) }
@@ -51,12 +51,21 @@ RSpec.describe Lerna::Runner do
51
51
 
52
52
  context 'when a strategy is found' do
53
53
  let(:strategy) {
54
- double('strategy', configuration: %w[ --option --another ])
54
+ double(
55
+ 'strategy',
56
+ configure: %w[ --option --another ],
57
+ preconfigure: %w[ --off1 --off2 ]
58
+ )
55
59
  }
56
60
  let(:strategy_selector) {
57
61
  double('strategy_selector', call: strategy)
58
62
  }
59
63
 
64
+ it 'calls xrandr with the strategy preconfiguration' do
65
+ expect(system).to receive(:call).
66
+ with('xrandr', '--off1', '--off2')
67
+ end
68
+
60
69
  it 'calls xrandr with the strategy configuration' do
61
70
  expect(system).to receive(:call).
62
71
  with('xrandr', '--option', '--another')
@@ -3,7 +3,7 @@ require 'lerna/strategies/external_digital_only'
3
3
 
4
4
  RSpec.describe Lerna::Strategy do
5
5
  it 'registers subclasses' do
6
- expect(described_class.registry.fetch('external-digital-only')).
6
+ expect(described_class.registry.fetch('external-only')).
7
7
  to eq(Lerna::Strategies::ExternalDigitalOnly)
8
8
  end
9
9
  end
@@ -0,0 +1,89 @@
1
+ require 'lerna/strategies/wall'
2
+
3
+ RSpec.describe Lerna::Strategies::Wall do
4
+ subject {
5
+ described_class.new(displays)
6
+ }
7
+
8
+ context 'when fewer than two external digital displays are connected' do
9
+ let(:displays) {
10
+ [
11
+ double(name: 'LVDS1', external?: false,
12
+ connected?: true, digital?: true),
13
+ double(name: 'DP1', external?: true,
14
+ connected?: true, digital?: true),
15
+ double(name: 'DP2', external?: true,
16
+ connected?: false, digital?: true),
17
+ double(name: 'VGA1', external?: true,
18
+ connected?: false, digital?: false)
19
+ ]
20
+ }
21
+
22
+ it { is_expected.not_to be_applicable }
23
+ end
24
+
25
+ context 'when two external digital displays are connected' do
26
+ let(:displays) {
27
+ [
28
+ double(name: 'LVDS1', external?: false,
29
+ connected?: true, digital?: true),
30
+ double(name: 'DP1', external?: true,
31
+ connected?: true, digital?: true),
32
+ double(name: 'DP2', external?: true,
33
+ connected?: true, digital?: true),
34
+ double(name: 'VGA1', external?: true,
35
+ connected?: false, digital?: false)
36
+ ]
37
+ }
38
+
39
+ it { is_expected.to be_applicable }
40
+
41
+ it 'configures the connected external displays in alphanumeric order' do
42
+ expect(subject.configure).to eq(%w[
43
+ --output DP1 --auto --rotate normal
44
+ --output DP2 --auto --rotate normal --right-of DP1
45
+ ])
46
+ end
47
+
48
+ it 'disables all other displays' do
49
+ expect(subject.preconfigure).to eq(%w[
50
+ --output LVDS1 --off
51
+ --output VGA1 --off
52
+ ])
53
+ end
54
+ end
55
+
56
+ context 'when three external digital displays are connected' do
57
+ let(:displays) {
58
+ [
59
+ double(name: 'LVDS1', external?: false,
60
+ connected?: true, digital?: true),
61
+ double(name: 'HDMI1', external?: true,
62
+ connected?: true, digital?: true),
63
+ double(name: 'DP1', external?: true,
64
+ connected?: true, digital?: true),
65
+ double(name: 'DP2', external?: true,
66
+ connected?: true, digital?: true),
67
+ double(name: 'VGA1', external?: true,
68
+ connected?: false, digital?: false)
69
+ ]
70
+ }
71
+
72
+ it { is_expected.to be_applicable }
73
+
74
+ it 'configures the connected external displays in alphanumeric order' do
75
+ expect(subject.configure).to eq(%w[
76
+ --output DP1 --auto --rotate normal
77
+ --output DP2 --auto --rotate normal --right-of DP1
78
+ --output HDMI1 --auto --rotate normal --right-of DP2
79
+ ])
80
+ end
81
+
82
+ it 'disables all other displays' do
83
+ expect(subject.preconfigure).to eq(%w[
84
+ --output LVDS1 --off
85
+ --output VGA1 --off
86
+ ])
87
+ end
88
+ end
89
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lerna
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Battley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-12 00:00:00.000000000 Z
11
+ date: 2015-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -67,21 +67,23 @@ files:
67
67
  - lib/lerna/runner.rb
68
68
  - lib/lerna/state.rb
69
69
  - lib/lerna/strategies.rb
70
- - lib/lerna/strategies/dual_external.rb
71
70
  - lib/lerna/strategies/external_digital_only.rb
72
71
  - lib/lerna/strategies/internal_only.rb
72
+ - lib/lerna/strategies/portrait_wall.rb
73
+ - lib/lerna/strategies/wall.rb
73
74
  - lib/lerna/strategy.rb
74
75
  - lib/lerna/strategy_selector.rb
75
76
  - lib/lerna/version.rb
76
77
  - spec/display_enumerator_spec.rb
77
78
  - spec/display_spec.rb
78
- - spec/dual_external_strategy_spec.rb
79
79
  - spec/external_digital_only_strategy_spec.rb
80
80
  - spec/internal_only_strategy_spec.rb
81
+ - spec/portrait_wall_strategy_spec.rb
81
82
  - spec/runner_spec.rb
82
83
  - spec/state_spec.rb
83
84
  - spec/strategy_selector_spec.rb
84
85
  - spec/strategy_spec.rb
86
+ - spec/wall_strategy_spec.rb
85
87
  - support/lerna.conf
86
88
  homepage: http://github.com/threedaymonk/lerna
87
89
  licenses:
@@ -1,32 +0,0 @@
1
- require 'lerna/strategy'
2
-
3
- module Lerna
4
- module Strategies
5
- class DualExternal < Strategy
6
- def applicable?
7
- wanted_displays.length == 2
8
- end
9
-
10
- def configuration
11
- [].tap { |conf|
12
- disconnected = displays - wanted_displays
13
- disconnected.each do |d|
14
- conf << '--output' << d.name << '--off'
15
- end
16
- conf << '--output' << wanted_displays[0].name << '--auto'
17
- conf << '--output' << wanted_displays[1].name << '--auto' <<
18
- '--right-of' << wanted_displays[0].name
19
- }
20
- end
21
-
22
- private
23
-
24
- def wanted_displays
25
- displays.
26
- select(&:connected?).
27
- select { |d| d.external? && d.digital? }.
28
- sort_by(&:name)
29
- end
30
- end
31
- end
32
- end
@@ -1,50 +0,0 @@
1
- require 'lerna/strategies/dual_external'
2
-
3
- RSpec.describe Lerna::Strategies::DualExternal do
4
- subject {
5
- described_class.new(displays)
6
- }
7
-
8
- context 'when fewer than two external digital displays are connected' do
9
- let(:displays) {
10
- [
11
- double(name: 'LVDS1', external?: false,
12
- connected?: true, digital?: true),
13
- double(name: 'DP1', external?: true,
14
- connected?: true, digital?: true),
15
- double(name: 'DP2', external?: true,
16
- connected?: false, digital?: true),
17
- double(name: 'VGA1', external?: true,
18
- connected?: false, digital?: false)
19
- ]
20
- }
21
-
22
- it { is_expected.not_to be_applicable }
23
- end
24
-
25
- context 'when two external digital displays are connected' do
26
- let(:displays) {
27
- [
28
- double(name: 'LVDS1', external?: false,
29
- connected?: true, digital?: true),
30
- double(name: 'DP1', external?: true,
31
- connected?: true, digital?: true),
32
- double(name: 'DP2', external?: true,
33
- connected?: true, digital?: true),
34
- double(name: 'VGA1', external?: true,
35
- connected?: false, digital?: false)
36
- ]
37
- }
38
-
39
- it { is_expected.to be_applicable }
40
-
41
- it 'configures the connected external display' do
42
- expect(subject.configuration).to eq(%w[
43
- --output LVDS1 --off
44
- --output VGA1 --off
45
- --output DP1 --auto
46
- --output DP2 --auto --right-of DP1
47
- ])
48
- end
49
- end
50
- end