lerna 0.1.0 → 0.1.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
  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