wrkflo 0.0.6 → 0.1.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.
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
  - - ">="