wrkflo 0.0.6 → 0.1.0

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: d70b824f5d4eb229c5134ea2c72332395c46571f
4
- data.tar.gz: b082c49cdb7b670d9540aac2489be8a6648ac6fe
3
+ metadata.gz: 92d4805587cc03e7998552a6259cf57a571e864c
4
+ data.tar.gz: 41f6e3f8d01d326612f876f683880ff1f633f819
5
5
  SHA512:
6
- metadata.gz: eac20bcd6aa3b7da6190a5cfe318e9c78bfa748829b0e58b441be4c52659850404e33e3e6bb03437fe271b4d7b14064fd21dc97f9353b6bf990fe0b5d470e9d2
7
- data.tar.gz: ea1455f2474a28cdfc8093a29f7d9eba445e571e1d9164dfafea8fab6a64fb2bce73c52fdeb6bf38f853f6fe25c10a629731c75a38a05fbf8528b2d2d4c32a7b
6
+ metadata.gz: 85726e95f9f54eefcd9b6763d33cd2646eff4c5fe8e0744e08d3f351ff75273eb1cb481aaed82b148488d5d8e889dfa07d706679146cfac93d6053d0813f35c7
7
+ data.tar.gz: 315f2af6027850d4c135cd409890cd2d4b45c66bb0cb1cc7004a2a7c1a571b589fd830af93dbe66e2c55b013048eed80228d7db90d31f537c9830ba1caab6fe2
data/bin/wrkflo CHANGED
@@ -17,13 +17,13 @@ end
17
17
 
18
18
  options = {
19
19
  backward: false,
20
- profile: ENV['HOME'] + '/.wrkflorc',
20
+ profile: ENV['HOME'] + '/.wrkflo/config',
21
21
  project: nil
22
22
  }
23
23
  OptionParser.new do |opts|
24
24
  opts.banner = "Usage: wrkflo [options] <project>"
25
25
  opts.separator "Start working on things faster with predefined workflows"
26
- opts.version = "0.0.2"
26
+ opts.version = Wrkflo::VERSION
27
27
 
28
28
  opts.on("-b", "--backward", "Reverse step order and undo compatible steps") do |b|
29
29
  options[:backward] = b
@@ -31,7 +31,7 @@ OptionParser.new do |opts|
31
31
 
32
32
  opts.on("-f [FILE]", "--file [FILE]",
33
33
  "The file to interpret as the wrkflo profile.",
34
- "Defaults to \"~/.wrkflorc\"") do |file|
34
+ "Defaults to \"~/.wrkflo/config\"") do |file|
35
35
  options[:profile] = file
36
36
  end
37
37
 
@@ -0,0 +1,24 @@
1
+ module Configurable
2
+ class Property
3
+ # The name of the property as it should appear in the configuration
4
+ attr_accessor :name
5
+ # Whether the property is required to be provided by the user
6
+ attr_accessor :required
7
+ alias_method :required?, :required
8
+ # The default value to be given to this property if one is not provided
9
+ attr_accessor :default
10
+
11
+
12
+ def initialize name, is_required, default_value
13
+ @name = name
14
+ @required = is_required
15
+ @default = default_value
16
+ end
17
+
18
+
19
+ # Assign a value to this property
20
+ def resolve_value value
21
+ value.nil? ? @default : value
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ require 'wrkflo/configurable/property'
2
+
3
+ module Configurable
4
+ module ClassMethods
5
+ # A list of properties defined by the owner
6
+ def properties
7
+ @properties ||= {}
8
+ end
9
+
10
+ # Define a new property for the owning object
11
+ def property name, required: false, default: nil
12
+ properties[name] = Property.new(name, required, default)
13
+ end
14
+ end
15
+
16
+ def self.included base
17
+ base.extend ClassMethods
18
+ end
19
+
20
+
21
+ def apply_configuration raw_config
22
+ final_config = self.class.properties.each.with_object({}) do |(name, prop), h|
23
+ provided_value = raw_config[name.to_s]
24
+ # Determine the real value based on the property's definition
25
+ real_value = prop.resolve_value(provided_value)
26
+ # Remember the real value in the actual configuration
27
+ h[name.to_sym] = real_value
28
+ end
29
+
30
+ # Create a struct from the configuration hash to enable dot-access.
31
+ @configuration = Struct.new(*final_config.keys).new(*final_config.values)
32
+ end
33
+
34
+ def config
35
+ @configuration
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ class Profile
2
+ def self.load source
3
+ @projects = YAML.load_file(source)
4
+ @options = @projects.delete("options")
5
+ rescue
6
+ $stderr.puts "Could not load configuration at '#{source}'."
7
+ $stderr.puts "Make sure the file exists before running `wrkflo`."
8
+ exit 1
9
+ end
10
+
11
+ def self.projects; @projects; end
12
+ def self.options; @options; end
13
+ end
@@ -3,11 +3,13 @@ require 'wrkflo/step'
3
3
  class Project
4
4
  attr_accessor :name, :steps
5
5
 
6
- def initialize name, steps
6
+ def initialize name
7
7
  # The name of this project workflow
8
- @name = name
8
+ @name = name
9
+ # The raw configuration used by this project
10
+ @config = Profile.projects[@name]
9
11
  # The steps that make up this workflow
10
- @steps = steps.map{ |name, config| Step.create(name, config, self) }
12
+ @steps = @config.map{ |name, conf| Step.create(name, conf, self) }
11
13
  # The step currently being executed
12
14
  @current_step = 0
13
15
  end
@@ -24,6 +26,7 @@ class Project
24
26
  # Increment the current step so that the first step is 1
25
27
  @current_step_num += 1
26
28
  # Run the step
29
+ @current_step.setup
27
30
  @current_step.run
28
31
  end
29
32
 
@@ -40,6 +43,7 @@ class Project
40
43
  # Track the step being run
41
44
  @current_step = step
42
45
  # Run the step
46
+ @current_step.setup
43
47
  @current_step.unrun
44
48
  # Decrement the current step so that the last step is 1
45
49
  @current_step_num -= 1
data/lib/wrkflo/step.rb CHANGED
@@ -1,5 +1,8 @@
1
+ require 'os'
2
+ require 'wrkflo/configurable'
3
+
1
4
  class Step
2
- attr_accessor :name, :config, :project
5
+ attr_accessor :name, :raw_config, :project
3
6
 
4
7
  # A hash of step aliases to their respective classes. This map determines
5
8
  # the class that a given step in a project will be transformed into.
@@ -15,17 +18,25 @@ class Step
15
18
  # Create a new instance of a Step based on the step map entry. If none
16
19
  # exists, a generic Step is created.
17
20
  def create name='', config={}, project=nil
18
- @@step_map[name.to_sym].new(name, config, project) or Step.new(name, config, project)
21
+ @@step_map[name.to_sym].new(name, config, project) || Step.new(name, config, project)
19
22
  end
20
23
  end
21
24
 
22
- def initialize name, config, project=nil
25
+
26
+ include Configurable
27
+
28
+
29
+ def initialize name, raw_config, project=nil
23
30
  # The name for this step
24
31
  @name = name
25
32
  # The options that define this step
26
- @config = config
27
- # The project that this step belongs to
33
+ @raw_config = raw_config
34
+ # The project to which this step belongs
28
35
  @project = project
36
+ # Generate the finalized step configuration
37
+ apply_configuration(@raw_config)
38
+ # Run step-specific initialization
39
+ init
29
40
  end
30
41
 
31
42
  # A pass through to this step's project's log. If this step has no project,
@@ -34,11 +45,16 @@ class Step
34
45
  @project ? @project.log(message) : puts(message)
35
46
  end
36
47
 
48
+
37
49
  # STEP METHODS
38
50
  #
39
51
  # These methods should be defined by all Step subclasses as given by their
40
52
  # descriptions.
41
53
 
54
+ # Work done immediately after initializing this step
55
+ def init; end
56
+ # Common work done before running and unrunning.
57
+ def setup; end
42
58
  # The code to run when running this step normally
43
59
  def run
44
60
  log "Nothing to do."
@@ -47,7 +63,17 @@ class Step
47
63
  def unrun
48
64
  log "Nothing to do."
49
65
  end
50
- end
51
66
 
52
- # Require all step definitions
53
- Dir[File.join(__dir__, 'steps', '*')].each{ |step_file| require step_file }
67
+
68
+ protected
69
+
70
+ # Return true if being run on the given platform. If a block is given, run
71
+ # the block only if being run on the given platform and return the result.
72
+ def on platform
73
+ if block_given?
74
+ yield if OS.send("#{platform}?")
75
+ else
76
+ return OS.send("#{platform}?")
77
+ end
78
+ end
79
+ end
@@ -1,8 +1,10 @@
1
1
  class AtomStep < Step
2
2
  add_alias :atom
3
3
 
4
+ property :path, required: true
5
+
4
6
  def run
5
- log "Opening an Atom Window at #{config}"
6
- `atom #{config}`
7
+ log "Opening an Atom Window at #{config.path}"
8
+ `atom #{config.path}`
7
9
  end
8
10
  end
@@ -0,0 +1,15 @@
1
+ class Editor < Step
2
+ add_alias :editor
3
+
4
+ property :which, required: false, default: Profile.options['editor']
5
+ property :path, required: true
6
+
7
+ def init
8
+ @editor = config.which
9
+ @step = Step.create(@editor.to_sym, @raw_config, project)
10
+ @name = "editor[#{@step.name}]"
11
+ end
12
+
13
+ def run; @step.run; end
14
+ def unrun; @step.unrun; end
15
+ end
@@ -1,8 +1,10 @@
1
1
  class EmacsStep < Step
2
2
  add_alias :emacs
3
3
 
4
+ property :path, required: true
5
+
4
6
  def run
5
- log "Opening an Emacs frame at #{config}"
6
- `emacsclient -c -a "" -n #{config}`
7
+ log "Opening an Emacs frame at #{config.path}"
8
+ `emacsclient -c -a "" -n #{config.path}`
7
9
  end
8
10
  end
@@ -0,0 +1,18 @@
1
+ class FileSystem < Step
2
+ add_alias :filesystem
3
+ add_alias :fs
4
+
5
+ property :which, required: false, default: Profile.options['filesystem']
6
+ property :host, required: true
7
+ property :remote_path, required: true
8
+ property :local_path, required: true
9
+
10
+ def init
11
+ @filesystem = config.which
12
+ @step = Step.create(@filesystem.to_sym, @raw_config, project)
13
+ @name = "filesystem[#{@step.name}]"
14
+ end
15
+
16
+ def run; @step.run; end
17
+ def unrun; @step.unrun; end
18
+ end
@@ -1,10 +1,13 @@
1
1
  class SSHStep < Step
2
2
  add_alias :ssh
3
3
 
4
+ property :host, required: true
5
+ property :directory, required: true
6
+
4
7
  def run
5
- log "SSHing into #{config['host']} at #{config['directory']}"
8
+ log "SSHing into #{config.host} at #{config.directory}"
6
9
 
7
- ssh_command = "ssh -t #{config['host']} \\\"#{config['directory']}; bash --login\\\""
8
- `osascript -e 'tell application "Terminal" to activate' -e 'tell application "Terminal" to set ssh_window to do script "#{ssh_command}"'`
10
+ ssh_command = "ssh -t #{config.host} \\\"#{config.directory}; bash --login\\\""
11
+ `osascript -e 'tell application "Terminal" to activate' -e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' -e 'tell application "Terminal" to do script "#{ssh_command}" in selected tab of the front window'`
9
12
  end
10
13
  end
@@ -1,13 +1,17 @@
1
1
  class SSHFSStep < Step
2
2
  add_alias :sshfs
3
3
 
4
+ property :host, required: true
5
+ property :remote_path, required: true
6
+ property :local_path, required: true
7
+
4
8
  def run
5
- log "Mounting #{config['host']}:#{config['remote_path']} at #{config['local_path']}"
6
- `sshfs #{config['host']}:#{config['remote_path']} #{config['local_path']}`
9
+ log "Mounting #{config.host}:#{config.remote_path} at #{config.local_path}"
10
+ `sshfs #{config.host}:#{config.remote_path} #{config.local_path}`
7
11
  end
8
12
 
9
13
  def unrun
10
- log "Unmounting #{config['host']}:#{config['remote_path']} from #{config['local_path']}"
11
- `umount #{config['local_path']}`
14
+ log "Unmounting #{config.host}:#{config.remote_path} from #{config.local_path}"
15
+ `umount #{config.local_path}`
12
16
  end
13
17
  end
@@ -2,8 +2,10 @@ class SublimeStep < Step
2
2
  add_alias :sublime
3
3
  add_alias :subl
4
4
 
5
+ property :path, required: true
6
+
5
7
  def run
6
- log "Opening a Sublime Window at #{config}"
7
- `subl -n #{config}`
8
+ log "Opening a Sublime Window at #{config.path}"
9
+ `subl -n #{config.path}`
8
10
  end
9
11
  end
@@ -0,0 +1,3 @@
1
+ module Wrkflo
2
+ VERSION = '0.1.0'
3
+ end
data/lib/wrkflo/wrkflo.rb CHANGED
@@ -1,19 +1,51 @@
1
+ require 'wrkflo/version'
2
+ require 'wrkflo/profile'
1
3
  require 'wrkflo/project'
2
4
 
3
5
  class WrkFlo
4
6
  attr_accessor :direction, :profile, :profile_source
5
7
 
8
+ DEFAULT_STEP_PATHS = [
9
+ File.join(__dir__, 'steps'),
10
+ File.join(ENV['HOME'], '.wrkflo', 'steps'),
11
+ File.join('.', '.wrkflo', 'steps')
12
+ ]
13
+
6
14
  def initialize options
7
- @profile = YAML.load(File.open(options[:profile]))
8
15
  @profile_source = options[:profile]
16
+ Profile.load(@profile_source)
17
+ load_step_definitions
9
18
  @direction = options[:backward] ? :backward : :forward
10
19
  end
11
20
 
21
+ # Load all step definitions from various default and configured paths.
22
+ def load_step_definitions
23
+ # For the default directories, try to scan them if they exist.
24
+ DEFAULT_STEP_PATHS.each do |path|
25
+ if Dir.exists?(path)
26
+ Dir[File.join(path, '*')].each{ |step_file| require step_file }
27
+ end
28
+ end
29
+
30
+ # For configured paths, try to require each entry and error out if one is
31
+ # not available.
32
+ configured_step_paths.each do |path|
33
+ if Dir.exists?(path)
34
+ Dir[File.join(path, '*')].each{ |step_file| require step_file }
35
+ else
36
+ require path
37
+ end
38
+ end
39
+ end
40
+
12
41
  # Get a specific project out of the profile. If the profile does not define
13
42
  # the given project, return nil.
14
43
  def [] project
15
- if @profile.has_key?(project)
16
- Project.new(project, @profile[project])
17
- end
44
+ Project.new(project) if Profile.projects[project]
18
45
  end
46
+
47
+ private
48
+ def configured_step_paths
49
+ Profile.options['step_definitions'] || []
50
+ end
19
51
  end
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wrkflo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Egeland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-22 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2017-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: os
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
13
55
  description:
14
56
  email: jonegeland@gmail.com
15
57
  executables:
@@ -18,13 +60,19 @@ extensions: []
18
60
  extra_rdoc_files: []
19
61
  files:
20
62
  - bin/wrkflo
63
+ - lib/wrkflo/configurable.rb
64
+ - lib/wrkflo/configurable/property.rb
65
+ - lib/wrkflo/profile.rb
21
66
  - lib/wrkflo/project.rb
22
67
  - lib/wrkflo/step.rb
23
68
  - lib/wrkflo/steps/atom.rb
69
+ - lib/wrkflo/steps/editor.rb
24
70
  - lib/wrkflo/steps/emacs.rb
71
+ - lib/wrkflo/steps/filesystem.rb
25
72
  - lib/wrkflo/steps/ssh.rb
26
73
  - lib/wrkflo/steps/sshfs.rb
27
74
  - lib/wrkflo/steps/sublime.rb
75
+ - lib/wrkflo/version.rb
28
76
  - lib/wrkflo/wrkflo.rb
29
77
  homepage: http://github.com/faultyserver/wrkflo
30
78
  licenses:
@@ -34,6 +82,7 @@ post_install_message:
34
82
  rdoc_options: []
35
83
  require_paths:
36
84
  - lib
85
+ - lib/wrkflo
37
86
  required_ruby_version: !ruby/object:Gem::Requirement
38
87
  requirements:
39
88
  - - ">="