shell_helpers 0.1.0 → 0.6.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
- SHA1:
3
- metadata.gz: e423354674b7162de244672ab417617837d4667f
4
- data.tar.gz: 36527735c314d40be7389de683688e4446c24961
2
+ SHA256:
3
+ metadata.gz: 6049045c2830e61e0ea865aeb4905e0f4464cdd4b837ee0e7923667e8aae7900
4
+ data.tar.gz: 2ca9a6fceac250538239f8ff3b075d4d2813b02892f7dad411dfad0a8dbfd1e7
5
5
  SHA512:
6
- metadata.gz: 743a7bbaec3fa0511cbba321b847db43233a3c964bc4a03cbd07577c5ef2ae4e5357d98a9906532c5536842f92f10ecddf815904f2e776035533763a3a9b8fb4
7
- data.tar.gz: 023a3e4ce0a45b3cde0c94906ae05ab1d15687531f9425eb93b60fd59d1fd17c3fd6939b629617d92f0520d6083f06b729a3e54e1ae2f3a317ce58c6b80bf03f
6
+ metadata.gz: 809023e14ecf8fc382ce25f107eeeba053573e190fac4030641a496e74306d3f480ef6b4555f5ffb71b9e412bf4f95778c78ab7bdf27efa7a517f92c1239c69c
7
+ data.tar.gz: 6db15aa50cb2ee5d60ee85404a109b00f8106aad9491b993c6aed289f2f23fd838d65124501a617672cf3e9fa06360aef525177199fedaa1b47362622b6a673c
data/.gitignore CHANGED
@@ -1,2 +1,6 @@
1
- doc/
2
- pkg/
1
+ /.bundle
2
+ /.yardoc/
3
+ /Gemfile.lock
4
+ /doc/
5
+ /pkg/
6
+ /vendor/cache/*.gem
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ ---
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.0
5
+ - 2.3.3
6
+ - 2.2.6
7
+ - 2.1.10
8
+ #- ruby-head
9
+ #- ruby-head-clang
10
+ script: bundle exec rake test
data/.yardopts CHANGED
@@ -1 +1,6 @@
1
- --markup markdown -M kramdown --title "shell_helpers Documentation" --protected
1
+ --markup markdown
2
+ --title "shell_helpers Documentation"
3
+ --protected
4
+ -
5
+ ChangeLog.md
6
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+ gem 'drain', :github => 'DamienRobert/drain'
5
+
6
+ group :development do
7
+ gem 'kramdown'
8
+ end
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015 Damien Robert
1
+ Copyright © 2015–2018 Damien Robert
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # shell_helpers
2
2
 
3
3
  * [Homepage](https://github.com/DamienRobert/shell_helpers#readme)
4
- * [Gems]("https://rubygems.org/gems/shell_helpers)
5
4
  * [Issues](https://github.com/DamienRobert/shell_helpers/issues)
6
- * [Documentation](http://rubydoc.info/gems/shell_helpers/frames)
5
+ * [Documentation](http://rubydoc.info/gems/shell_helpers)
7
6
  * [Email](mailto:Damien.Olivier.Robert+gems at gmail.com)
8
7
 
8
+ [![Gem Version](https://img.shields.io/gem/v/shell_helpers.svg)](https://rubygems.org/gems/shell_helpers)
9
+ [![Build Status](https://travis-ci.org/DamienRobert/shell_helpers.svg?branch=master)](https://travis-ci.org/DamienRobert/shell_helpers)
10
+
9
11
  ## Description
10
12
 
11
13
  This gem contains a collection of libraries to ease working with the
@@ -23,13 +25,35 @@
23
25
  this functionality from other command parsers than methadone
24
26
  (like [gli](https://github.com/davetron5000/gli)).
25
27
 
28
+ ## Features
29
+
30
+ One of the main feature is an extension of the class `Pathname` with a
31
+ lots of methods to help in shell related task.
32
+
33
+ ## Examples
34
+
35
+ require 'shell_helpers'
36
+ SH::Pathname.new("foo").cp("bar") #calls FileUtils.cp("foo","bar")
37
+ SH::Pathname.new("foo/").on_cp("bar","baz") #copy 'bar' and 'baz' to 'foo/'
38
+ SH::Pathname.new("foo").on_rm(mode: :dangling_symlink) #remove 'foo' only if it is a dangling symlink
39
+ SH::Pathname.new("foo").squel("bar/baz", action: :on_ln_s) #create a symlink foo/bar/baz -> ../../bar/baz
40
+
41
+ #Symlink all files in a directory into another, while preserving the structure
42
+ SH::Pathname.new("foo").squel_dir("bar',action: :on_ln_s)
43
+ #Remove these symlinks
44
+ SH::Pathname.new("foo").squel_dir("bar") {|o,t| o.on_rm(mode: :symlink)}
45
+
46
+ ## Warning
47
+
48
+ For now the API is experimental and some parts are not ready to use!
49
+
26
50
  ## Install
27
51
 
28
52
  $ gem install shell_helpers
29
53
 
30
54
  ## Copyright
31
55
 
32
- Copyright (c) 2015 Damien Robert
56
+ Copyright © 2015–2018 Damien Robert
33
57
 
34
58
  MIT License. See {file:LICENSE.txt} for details.
35
59
 
data/Rakefile CHANGED
@@ -1,20 +1,16 @@
1
- # encoding: utf-8
2
-
3
- require 'rubygems'
4
1
  require 'rake'
5
2
 
6
3
  begin
7
- gem 'rubygems-tasks', '~> 0.2'
8
4
  require 'rubygems/tasks'
9
-
10
- Gem::Tasks.new
5
+ Gem::Tasks.new(sign: {checksum: true, pgp: true},
6
+ scm: {status: true}) do |tasks|
7
+ tasks.console.command = 'pry'
8
+ end
11
9
  rescue LoadError => e
12
10
  warn e.message
13
- warn "Run `gem install rubygems-tasks` to install Gem::Tasks."
14
11
  end
15
12
 
16
13
  require 'rake/testtask'
17
-
18
14
  Rake::TestTask.new do |test|
19
15
  test.libs << 'test'
20
16
  test.pattern = 'test/**/test_*.rb'
@@ -22,13 +18,12 @@ Rake::TestTask.new do |test|
22
18
  end
23
19
 
24
20
  begin
25
- gem 'yard', '~> 0.8'
26
21
  require 'yard'
27
-
28
- YARD::Rake::YardocTask.new
22
+ YARD::Rake::YardocTask.new
29
23
  rescue LoadError => e
30
24
  task :yard do
31
- abort "Please run `gem install yard` to install YARD."
25
+ warn e.message
32
26
  end
33
27
  end
34
28
  task :doc => :yard
29
+
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ Integrate ptools?
2
+ https://github.com/djberg96/ptools
data/bin/abs_to_rel.rb ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'shell_helpers/pathname'
4
+ require 'shell_helpers/options'
5
+
6
+ opts = Slop.parse(ARGV) do |o|
7
+ o.bool "-v", "--verbose", "verbose"
8
+ o.bool "-t", "--test", "test"
9
+ o.symbol "-m", "--mode", "Conversion mode", default: :rel
10
+ o.string "-b", "--base", "Assume symlinks are relative to this base"
11
+ o.symbol "--base-mode", "Base conversion mode", default: :abs_realdir
12
+ o.on '--help' do
13
+ puts o
14
+ exit
15
+ end
16
+ end
17
+
18
+ pathname=ShellHelpers::Pathname
19
+ if opts[:verbose] and opts[:test]
20
+ pathname=ShellHelpers::Pathname::DryRun
21
+ elsif opts[:verbose] and !opts[:test]
22
+ pathname=ShellHelpers::Pathname::Verbose
23
+ elsif opts[:test]
24
+ pathname=ShellHelpers::Pathname::NoWrite
25
+ end
26
+
27
+ opts.args.each do |l|
28
+ l=pathname.new(l)
29
+ if l.symlink?
30
+ base=(opts[:base]||l.dirname).convert_path(mode: opts[:'base-mode'])
31
+ oldpath=l.readlink
32
+ newpath=l.rel_path_to(oldpath, base: base, mode: opts[:mode])
33
+ if oldpath != newpath
34
+ puts "#{l}: #{oldpath} -> #{newpath}" if opts[:verbose]
35
+ l.on_ln_sf(newpath, dereference: :none)
36
+ else
37
+ puts "#{l}: #{newpath}" if opts[:verbose]
38
+ end
39
+ else
40
+ puts "! #{l} is not a symlink" if opts[:verbose]
41
+ end
42
+ end
data/bin/mv_and_ln.rb ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'shell_helpers/pathname'
4
+ require 'shell_helpers/options'
5
+
6
+ opts = Slop.parse(ARGV) do |o|
7
+ o.bool "-v", "--verbose", "verbose"
8
+ o.int "--verbose-level", "verbose level"
9
+ o.bool "-t", "--test", "test"
10
+ o.symbol "-m", "--mode", "Conversion mode", default: :rel
11
+ o.symbol "--rm", "rm options", default: :noclobber
12
+ o.symbol "--dereference-mode", "dereference mode for dest"
13
+ o.bool "-L", "--dereference", "dereference dest"
14
+ o.bool "-f", "--force", "force remove"
15
+ o.on '--help' do
16
+ puts o
17
+ exit
18
+ end
19
+ end
20
+
21
+ if opts[:force]
22
+ opts[:rm] ||= :all
23
+ else
24
+ opts[:rm] ||= :noclobber
25
+ end
26
+ #dereference-mode can also take the values 'simple' and 'none'
27
+ opts[:"dereference-mode"] ||= opts[:dereference]
28
+
29
+ pathname=ShellHelpers::Pathname
30
+ if opts[:verbose] and opts[:test]
31
+ pathname=ShellHelpers::Pathname::DryRun
32
+ elsif opts[:verbose] and !opts[:test]
33
+ pathname=ShellHelpers::Pathname::Verbose
34
+ elsif opts[:test]
35
+ pathname=ShellHelpers::Pathname::NoWrite
36
+ end
37
+
38
+ *args,dest=opts.args
39
+ dest=pathname.new(dest)
40
+ if args.empty?
41
+ warn "You should specify at least two arguments"
42
+ exit 1
43
+ end
44
+ if args.length > 1 and !dest.directory?
45
+ warn "When specifying more than one target, dest should be a directory"
46
+ exit 1
47
+ end
48
+ args.each do |f|
49
+ f=pathname.new(f)
50
+ t=dest.directory? ? dest+f.basename : dest
51
+ t=f.rel_path_to(t, mode: opts[:mode])
52
+ puts "#{f} -> #{t}" if opts[:verbose]
53
+ dest.on_mv(f, mode: opts[:rm], verbose: opts[:verbose], dereference: opts[:"dereference-mode"]) and f.on_ln_s(t, verbose: opts[:verbose])
54
+ end
data/gemspec.yml CHANGED
@@ -8,8 +8,9 @@ email: Damien.Olivier.Robert+gems@gmail.com
8
8
  homepage: https://github.com/DamienRobert/shell_helpers#readme
9
9
 
10
10
  dependencies:
11
- drain: ~> 0.1
11
+ drain: ~> 0.2
12
12
  development_dependencies:
13
- minitest: ~> 5.0
14
- rubygems-tasks: ~> 0.2
15
- yard: ~> 0.8
13
+ minitest: "~> 5.0"
14
+ rake: "~> 10"
15
+ rubygems-tasks: "~> 0.2"
16
+ yard: "~> 0.8"
data/lib/shell_helpers.rb CHANGED
@@ -1,20 +1,28 @@
1
1
  require 'shell_helpers/version'
2
2
 
3
- require 'shellwords'; require 'pathname'; require 'fileutils'
4
- require 'dr/ruby_ext/core_ext'; require 'dr/ruby_ext/pathname_ext'
3
+ require 'fileutils'
4
+ #require 'dr/ruby_ext/core_ext'
5
5
  #load everything in shell_helpers/*.rb
6
- dir=File.expand_path(File.basename(__FILE__).chomp('.rb'), File.dirname(__FILE__))
7
- Dir.glob(File.expand_path('*.rb',dir)) do |file|
8
- require file
9
- end
6
+ #dir=File.expand_path(File.basename(__FILE__).chomp('.rb'), File.dirname(__FILE__))
7
+ #Dir.glob(File.expand_path('*.rb',dir)) do |file|
8
+ # require file
9
+ #end
10
+ require 'shell_helpers/logger'
11
+ require 'shell_helpers/run'
12
+ require 'shell_helpers/sh'
13
+ require 'shell_helpers/utils'
14
+ require 'shell_helpers/sysutils'
15
+ require 'shell_helpers/export'
16
+ require 'shell_helpers/pathname'
10
17
 
11
- module SH
18
+ module ShellHelpers
12
19
  include Run #run_command, run_output, run_status, run
13
20
  include CLILogging #logger.{debug info warn error fatal}, log_and_do
14
21
  include ExitNow #exit_now!
15
22
  include Sh #sh, sh!
16
- include ShellExport #export
17
- include ShellUtils #find, run_pager
23
+ include Export #export
24
+ include Utils #find, run_pager, rsync...
25
+ include SysUtils #mount, find_devices...
18
26
  extend self
19
27
  #activates debug mode
20
28
  def self.debug(level=Logger::DEBUG)
@@ -22,11 +30,30 @@ module SH
22
30
  Pathname.send(:include, CLILogging)
23
31
  logger.level=(level)
24
32
  end
25
- #including SH::FU to add FileUtils
33
+ #include SH::FU to add FileUtils
26
34
  module FU
27
35
  include ::FileUtils
28
- include ::SH
36
+ include ::ShellHelpers
29
37
  extend self
30
38
  end
39
+
40
+ # #include LogHelper to set up CLILogging with some convenience facilities
41
+ # module LogHelper
42
+ # include CLILogging
43
+ # CLILogging.logger.progname||=$0
44
+ # # #Activates Sh.sh in klass
45
+ # # def self.included(klass)
46
+ # # klass.const_set(:Sh,ShellHelpers::Sh)
47
+ # # end
48
+ # end
31
49
  end
32
50
 
51
+ #for the lazy
52
+ SH=ShellHelpers
53
+
54
+ ## # SHLog.sh to get logging
55
+ ## module SHLog
56
+ ## include ShellHelpers
57
+ ## include ShellHelpers::ShLog
58
+ ## end
59
+
@@ -0,0 +1,169 @@
1
+ require 'dr/ruby_ext/core_ext' #for Hash#keyed_value
2
+ require 'dr/parse/simple_parser'
3
+
4
+ module ShellHelpers
5
+ module Export
6
+ extend self
7
+ ImportError=Class.new(StandardError)
8
+ ExportError=Class.new(StandardError)
9
+
10
+ #export a value for SHELL consumption
11
+ def export_value(v)
12
+ case v
13
+ when String
14
+ return v.shellescape
15
+ when Array
16
+ return "(#{v.map {|i| i.to_s.shellescape}.join(' ')})"
17
+ when Hash
18
+ return "(#{v.map {|k,v| k.to_s.shellescape+" "+v.to_s.shellescape}.join(' ')})"
19
+ when nil
20
+ return ""
21
+ when ->(x){x.respond_to?(:to_a)}
22
+ return export_value(v.to_a)
23
+ when ->(x){x.respond_to?(:to_h)}
24
+ return export_value(v.to_h)
25
+ else
26
+ return v.to_s.shellescape
27
+ end
28
+ end
29
+ def import_value(v, type: String, unquote: true)
30
+ #String === String => false
31
+ case type.to_s
32
+ when "String"
33
+ v.gsub!(/\A['"]+|['"]+\Z/, "") if unquote
34
+ v.to_s
35
+ when "Integer"
36
+ v.to_i
37
+ when "Symbol"
38
+ v.to_sym
39
+ when "Array"
40
+ #v is of the form (ploum plam)
41
+ #TODO: handle quotes in the array
42
+ eval "%w#{v}"
43
+ when "Hash"
44
+ import_value(v, type: Array).each_slice(2).to_h
45
+ end
46
+ end
47
+
48
+ def escape_name(name, prefix:"", upcase: true)
49
+ name=name.to_s
50
+ name=name.upcase if upcase
51
+ (prefix+name).gsub('/','_')
52
+ end
53
+
54
+ #export_variable("ploum","plam") yields ploum="plam"
55
+ def export_variable(name, value, local: false, export: false, prefix:"",upcase:true)
56
+ r=""
57
+ name=escape_name(name,prefix:prefix,upcase:upcase)
58
+ r+="local #{name}\n" if local
59
+ r+="typeset -A #{name}\n" if Hash === value
60
+ r+="#{name}=#{export_value(value)}\n"
61
+ r+="export #{name}\n" if export
62
+ return r
63
+ end
64
+
65
+ def import_variable(namevalue, downcase:true, type: :auto)
66
+ namevalue.match(/(local|export)?\s*(\S*)=(.*)$/) do |m|
67
+ _match,_type,name,value=m.to_a
68
+ name=name.downcase if downcase
69
+ if type == :auto
70
+ if value=~/^\(.*\)$/
71
+ value=import_value(value, type: Array)
72
+ else
73
+ value=import_value(value)
74
+ end
75
+ else
76
+ value=import_value(value, type: type)
77
+ end
78
+ return name, value
79
+ end
80
+ end
81
+
82
+ #from {ploum: plim} return something like
83
+ #PLOUM=plim
84
+ #that can be evaluated by the shell
85
+ def export_variables(hash, local: false, export: false, prefix:"",upcase:true)
86
+ names=hash.keys.map {|s| escape_name(s,prefix:prefix,upcase:upcase)}
87
+ r=""
88
+ r+="local #{names.join(" ")}\n" if local
89
+ hash.each do |k,v|
90
+ r+=export_variable(k,v,prefix:prefix,upcase:upcase)
91
+ end
92
+ r+="export #{names.join(" ")}\n" if export
93
+ return r
94
+ end
95
+
96
+ #export_parse(hash,"name:value")
97
+ #will output name=$(hash[value])
98
+ #special cases: when value = '/' we return the full hash
99
+ # when value ends by /, we return the splitted hash (and name serves
100
+ # as a prefix)
101
+ #Ex: Numenor ~ $ ./mine/00COMPUTERS.rb --export=//
102
+ # HOSTNAME=Numenor;
103
+ # HOSTTYPE=perso;
104
+ # HOMEPATH=/home/dams;...
105
+ # Numenor ~ $ ./mine/00COMPUTERS.rb --export=syst/
106
+ # LAPTOP=true;
107
+ # ARCH=i686;...
108
+ #Remark: in name:value, we don't put name in uppercase
109
+ #But in split hash mode, we put the keys in uppercase (to prevent collisions)
110
+ def export_parse(hash,s)
111
+ r=""
112
+ args=DR::SimpleParser.parse_string(s.to_s)
113
+ args[:values].each do |k,v|
114
+ if v
115
+ name=k.to_s
116
+ else
117
+ #no name given
118
+ v=k.to_s
119
+ if v !='/' && v[-1]=='/'
120
+ #in split mode we don't need the name
121
+ name=""
122
+ else
123
+ #else since no name was given we reuse the variable
124
+ name=v
125
+ name="all" if v=="/"
126
+ end
127
+ end
128
+ if v != '/' && v[-1]=='/'
129
+ all=true
130
+ v=v[0...-1]
131
+ end
132
+ value=hash.keyed_value(v)
133
+ opts=args[:opts][k]
134
+ if all
135
+ r+=export_variables(value, prefix: name, **opts)
136
+ else
137
+ r+=export_variable(name,value, **opts)
138
+ end
139
+ end
140
+ return r
141
+ end
142
+
143
+ def import_parse(s, split_on: :auto, var_separator:'/', inline: false)
144
+ r={}
145
+ if split_on == :auto
146
+ split_on=","
147
+ split_on="\n" if s =~ /\n/
148
+ end
149
+ if s.is_a?(Enumerable)
150
+ instructions=s
151
+ else
152
+ instructions=s.split(split_on)
153
+ end
154
+ instructions.each do |namevalue|
155
+ if inline
156
+ name,value=DR::SimpleParser.parse_namevalue(optvalue,sep:'=')
157
+ else
158
+ name,value=import_variable(namevalue)
159
+ end
160
+ if name
161
+ r.set_keyed_value(name,value, sep: var_separator)
162
+ else
163
+ raise ImportError.new("Cannot parse #{s}")
164
+ end
165
+ end
166
+ r
167
+ end
168
+ end
169
+ end