├── var ├── name ├── title ├── version ├── source ├── organization ├── summary ├── requirements ├── authors ├── copyrights ├── description ├── repositories └── resources ├── bin └── cdexec ├── .yardopts ├── .gitignore ├── MANIFEST ├── HISTORY.rdoc ├── Assembly ├── main.reap ├── .ruby ├── README.rdoc ├── lib └── cdexec.rb ├── man └── cdexec.1.ronn ├── COPYING.rdoc └── .gemspec /var/name: -------------------------------------------------------------------------------- 1 | cdexec -------------------------------------------------------------------------------- /var/title: -------------------------------------------------------------------------------- 1 | cdexec -------------------------------------------------------------------------------- /var/version: -------------------------------------------------------------------------------- 1 | 0.2.1 -------------------------------------------------------------------------------- /var/source: -------------------------------------------------------------------------------- 1 | ruby.yaml -------------------------------------------------------------------------------- /var/organization: -------------------------------------------------------------------------------- 1 | Rubyworks 2 | -------------------------------------------------------------------------------- /var/summary: -------------------------------------------------------------------------------- 1 | Multi-execute over directories -------------------------------------------------------------------------------- /var/requirements: -------------------------------------------------------------------------------- 1 | --- 2 | - detroit (build) 3 | -------------------------------------------------------------------------------- /var/authors: -------------------------------------------------------------------------------- 1 | --- 2 | - Thomas Sawyer 3 | -------------------------------------------------------------------------------- /var/copyrights: -------------------------------------------------------------------------------- 1 | --- 2 | - (c) 2011 Rubyworks (BSD-2-Clause) 3 | -------------------------------------------------------------------------------- /var/description: -------------------------------------------------------------------------------- 1 | Execute shell commands in multiple-subdirectories. -------------------------------------------------------------------------------- /var/repositories: -------------------------------------------------------------------------------- 1 | --- 2 | upstream: git://github.com/rubyworks/cdexec.git 3 | -------------------------------------------------------------------------------- /bin/cdexec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'cdexec' 3 | CdExec.cli(*ARGV) 4 | 5 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --title "CdExec" 2 | --readme README.rdoc 3 | --private 4 | lib/**/*.rb - 5 | [A-Z]*.* 6 | -------------------------------------------------------------------------------- /var/resources: -------------------------------------------------------------------------------- 1 | --- 2 | home: http://rubyworks.github.com/cdexec 3 | code: http://github.com/rubyworks/cdexec 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .reap/digest 2 | .yardoc 3 | .rdoc 4 | doc 5 | log 6 | pkg 7 | tmp 8 | site/docs 9 | work/sandbox 10 | man/*.html 11 | man/*.1 12 | man/*.5 13 | man/*.7 14 | 15 | web -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | #!mast .yardopts .ruby bin lib man [A-Z]*.* 2 | .yardopts 3 | .ruby 4 | bin/cdexec 5 | lib/cdexec.rb 6 | man/cdexec.1 7 | man/cdexec.1.html 8 | man/cdexec.1.ronn 9 | HISTORY.rdoc 10 | README.rdoc 11 | COPYING.rdoc 12 | -------------------------------------------------------------------------------- /HISTORY.rdoc: -------------------------------------------------------------------------------- 1 | = RELEASE HISTORY 2 | 3 | == 0.2.1 / 2011-10-20 4 | 5 | Fixed type of man-page name. That's it. 6 | 7 | Changes: 8 | 9 | * Fixed name of man-page. 10 | 11 | 12 | == 0.2.0 / 2011-10-19 13 | 14 | The release fixes glob exapansion in the command portion 15 | of a cdexec call. 16 | 17 | Changes: 18 | 19 | * Fix glob expansion of command. 20 | * Better handling of arguments that contain spaces. 21 | 22 | 23 | == 0.1.0 / 2011-08-27 24 | 25 | Initial release of CdExec. Have fun! 26 | 27 | Changes: 28 | 29 | * It's your Birthday! 30 | 31 | -------------------------------------------------------------------------------- /Assembly: -------------------------------------------------------------------------------- 1 | --- 2 | gem: 3 | active: true 4 | 5 | github: 6 | gh_pages: web 7 | 8 | yard: 9 | yardopts: true 10 | priority: 2 11 | active: false 12 | 13 | dnote: 14 | title: Developer's Notes 15 | labels: ~ 16 | output: log/DNOTE.rdoc 17 | 18 | #locat: 19 | # title : ~ 20 | # loadpath : ~ 21 | # exclude : ~ 22 | # output : log/LOCat.html 23 | # active : true 24 | 25 | vclog: 26 | output: 27 | - log/changes.html 28 | - log/history.html 29 | 30 | email: 31 | mailto: 32 | - ruby-talk@ruby-lang.org 33 | - rubyworks-mailinglist@googlegroups.com 34 | 35 | 36 | -------------------------------------------------------------------------------- /main.reap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # TODO: Do things in ruby instead of shelling out! 4 | 5 | ignore 'pkg', 'site' 6 | 7 | desc "Release package." 8 | task 'release' do 9 | exit -1 if !system('detroit release') # `detroit release` 10 | system "pom news | git tag -a -F - #{version}" 11 | end 12 | 13 | file 'ruby.yml' do 14 | system "dotruby" 15 | end 16 | 17 | file 'MANIFEST' do 18 | update_manifest 19 | end 20 | 21 | file 'lib/**/*' do 22 | exit -1 if !system('detroit test') 23 | update_manifest 24 | end 25 | 26 | # Could we incorporate detroit phases? 27 | # detroit :post_release do 28 | # ... 29 | # end 30 | 31 | def update_manifest 32 | @manifest_updated ||= system "mast -u" 33 | end 34 | 35 | -------------------------------------------------------------------------------- /.ruby: -------------------------------------------------------------------------------- 1 | --- 2 | source: 3 | - ruby.yaml 4 | - var 5 | authors: 6 | - name: Thomas Sawyer 7 | email: transfire@gmail.com 8 | copyrights: 9 | - holder: Rubyworks 10 | year: '2011' 11 | license: BSD-2-Clause 12 | replacements: [] 13 | alternatives: [] 14 | requirements: 15 | - name: detroit 16 | groups: 17 | - build 18 | development: true 19 | dependencies: [] 20 | conflicts: [] 21 | repositories: 22 | - uri: git://github.com/rubyworks/cdexec.git 23 | scm: git 24 | name: upstream 25 | resources: 26 | home: http://rubyworks.github.com/cdexec 27 | code: http://github.com/rubyworks/cdexec 28 | extra: {} 29 | load_path: 30 | - lib 31 | revision: 0 32 | summary: Multi-execute over directories 33 | title: cdexec 34 | version: 0.2.1 35 | name: cdexec 36 | description: Execute shell commands in multiple-subdirectories. 37 | organization: Rubyworks 38 | date: '2011-11-11' 39 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = CdExec 2 | 3 | {Homepage}[http://rubyworks.github.com/cdexec] | 4 | {Development}[http://github.com/rubyworks/cdexec] | 5 | {Support}[http://github.com/rubyworks/cdexec/issues] 6 | 7 | 8 | == Description 9 | 10 | Execute command from within a selection of directories. 11 | 12 | 13 | == Usage 14 | 15 | A dash (`-`) is used to separate the directory selection 16 | from the command to be executed. 17 | 18 | For example, to list all files in all subdirectories: 19 | 20 | $ cdexec * - ls -1 21 | 22 | The `*` selects all the subdirectories. The `ls -1` command following the `-` 23 | is run within each directory, resulting in a complete list of files. 24 | 25 | More interesting result when used with source control systems, e.g. 26 | 27 | $ cdexec * - reap 28 | 29 | 30 | == Copying 31 | 32 | (BSD-2-Clause) 33 | 34 | Copyright (c) 2011 Thomas Sawyer, Rubyworks 35 | 36 | See COPYING.rdoc for details. 37 | -------------------------------------------------------------------------------- /lib/cdexec.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | module CdExec 4 | 5 | # Command line interface. 6 | def self.cli(*argv) 7 | case i = argv.index('-') 8 | when nil 9 | dirs, args = argv, Dir['*'] 10 | else 11 | dirs, args = argv[0...i], argv[i+1..-1] 12 | end 13 | 14 | help = dirs.delete('-h') || dirs.delete('--help') 15 | trace = dirs.delete('-t') || dirs.delete('--trace') 16 | 17 | display_help if help 18 | 19 | dirs = dirs.select{ |dir| File.directory?(dir) } 20 | 21 | dirs.each_with_index do |dir, idx| 22 | puts "\n#{idx+1}. #{dir}" if trace 23 | Dir.chdir dir do 24 | system command_line(*args) 25 | end 26 | end 27 | end 28 | 29 | # Glue the command line together, adding double quotes if argument 30 | # contains spaces. 31 | def self.command_line(*args) 32 | args.map do |a| 33 | case a 34 | when /\s/ 35 | %{"#{a}"} 36 | else 37 | a 38 | end 39 | end.join(' ') 40 | end 41 | 42 | # Display help message and exit. 43 | def self.display_help 44 | system "man #{man_file}" || puts(File.read(ronn_file)) 45 | exit 0 46 | end 47 | 48 | # Path to roff man-page file. 49 | def self.man_file 50 | File.dirname(__FILE__) + '/../man/cdexe.1' 51 | end 52 | 53 | # Path to ronn man-page file. 54 | def self.ronn_file 55 | File.dirname(__FILE__) + '/../man/cdexe.1.ronn' 56 | end 57 | 58 | end 59 | -------------------------------------------------------------------------------- /man/cdexec.1.ronn: -------------------------------------------------------------------------------- 1 | cdexec(1) - Iterate command execution over multiple directories 2 | =============================================================== 3 | 4 | ## DESCRIPTION 5 | 6 | The `cdexec` command allows shell commands to be executed over a selection 7 | of file directories. This is convenient for working with mutliple projects 8 | in bulk. 9 | 10 | 11 | ## OPTIONS 12 | 13 | The `cdexec` command is quite simple to use and there are only a few options: 14 | 15 | * `-t`/`--trace` 16 | Display the name of each directory as it is changed into. 17 | 18 | * `-h`/`--help` 19 | Show this help message. 20 | 21 | 22 | ## EXAMPLES 23 | 24 | There are plenty of uses for gitexec. Here are examples of a few that 25 | have proven handy to the developers of cdexec. 26 | 27 | Check the git status of a set of projects. 28 | 29 | $ cdexec */ - git status 30 | 31 | Running spellcheck on multiple project READMEs. 32 | 33 | $ cdexec */ - aspell check README.rdoc 34 | $ cdexec */ - rm README.rdoc.bak 35 | 36 | Running tests on multiple projects. 37 | 38 | $ cdexec */ - rake test 39 | 40 | All of these example relate to software development. No doubt there 41 | are many other application. 42 | 43 | 44 | ## RESOURCES 45 | 46 | * [API Documentation](http://rubydoc.info/gems/cdexec/frames) 47 | * [Issue Tracker](http://github.com/rubyworks/cdexec/issues) 48 | * [Source Code](http://github.com/rubyworks/cdexec) 49 | 50 | 51 | ## COPYING 52 | 53 | Copyright (c) 2011 Thomas Sawyer, Rubyworks 54 | 55 | This program is distributable in accordance with the terms of the 56 | *FreeBSD* license. 57 | 58 | -------------------------------------------------------------------------------- /COPYING.rdoc: -------------------------------------------------------------------------------- 1 | = COPYRIGHT NOTICES 2 | 3 | == CdExec 4 | 5 | Copyright:: (c)2009 Thomas Sawyer 6 | License:: BSD-2-Clause 7 | Website:: http://rubyworks.github.com/cdexec 8 | 9 | Copyright 2009 Thomas Sawyer. All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, are 12 | permitted provided that the following conditions are met: 13 | 14 | 1. Redistributions of source code must retain the above copyright notice, this list of 15 | conditions and the following disclaimer. 16 | 17 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 18 | of conditions and the following disclaimer in the documentation and/or other materials 19 | provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY Thomas Sawyer ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 23 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Thomas Sawyer OR 24 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | The views and conclusions contained in the software and documentation are those of the 32 | authors and should not be interpreted as representing official policies, either expressed 33 | or implied, of Thomas Sawyer. 34 | -------------------------------------------------------------------------------- /.gemspec: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'yaml' 4 | 5 | Gem::Specification.new do |gemspec| 6 | 7 | manifest = Dir.glob('manifest{,.txt)', File::FNM_CASEFOLD).first 8 | 9 | scm = case 10 | when File.directory?('.git') 11 | :git 12 | end 13 | 14 | files = case 15 | when manifest 16 | File.readlines(manifest). 17 | map{ |line| line.srtip }. 18 | reject{ |line| line.empty? || line[0,1] == '#' } 19 | when scm == :git 20 | `git ls-files -z`.split("\0") 21 | else 22 | Dir.glob('{**/}{.*,*}') # TODO: be more specific using standard locations ? 23 | end.select{ |path| File.file?(path) } 24 | 25 | patterns = { 26 | :bin_files => 'bin/*', 27 | :lib_files => 'lib/{**/}*.rb', 28 | :ext_files => 'ext/{**/}extconf.rb', 29 | :doc_files => '*.{txt,rdoc,md,markdown,tt,textile}', 30 | :test_files => '{test/{**/}*_test.rb,spec/{**/}*_spec.rb}' 31 | } 32 | 33 | glob_files = lambda { |pattern| 34 | Dir.glob(pattern).select { |path| 35 | File.file?(path) && files.include?(path) 36 | } 37 | } 38 | 39 | #files = glob_files[patterns[:files]] 40 | 41 | executables = glob_files[patterns[:bin_files]].map do |path| 42 | File.basename(path) 43 | end 44 | 45 | extensions = glob_files[patterns[:ext_files]].map do |path| 46 | File.basename(path) 47 | end 48 | 49 | metadata = YAML.load_file('.ruby') 50 | 51 | # build-out the gemspec 52 | 53 | case metadata['revision'] 54 | when 0 55 | gemspec.name = metadata['name'] 56 | gemspec.version = metadata['version'] 57 | gemspec.summary = metadata['summary'] 58 | gemspec.description = metadata['description'] 59 | 60 | metadata['authors'].each do |author| 61 | gemspec.authors << author['name'] 62 | 63 | if author.has_key?('email') 64 | if gemspec.email 65 | gemspec.email << author['email'] 66 | else 67 | gemspec.email = [author['email']] 68 | end 69 | end 70 | end 71 | 72 | gemspec.licenses = metadata['licenses'] 73 | 74 | metadata['requirements'].each do |req| 75 | name = req['name'] 76 | version = req['version'] 77 | groups = req['groups'] || [] 78 | 79 | if md = /^(.*?)([+-~])$/.match(version) 80 | version = case md[2] 81 | when '+' then ">= #{$1}" 82 | when '-' then "< #{$1}" 83 | when '~' then "~> #{$1}" 84 | else version 85 | end 86 | end 87 | 88 | #development = req['development'] 89 | #if development 90 | # # populate development dependencies 91 | # if gemspec.respond_to?(:add_development_dependency) 92 | # gemspec.add_development_dependency(name,*version) 93 | # else 94 | # gemspec.add_dependency(name,*version) 95 | # end 96 | #else 97 | # # populate runtime dependencies 98 | # if gemspec.respond_to?(:add_runtime_dependency) 99 | # gemspec.add_runtime_dependency(name,*version) 100 | # else 101 | # gemspec.add_dependency(name,*version) 102 | # end 103 | #end 104 | 105 | if groups.empty? or groups.include?('runtime') 106 | # populate runtime dependencies 107 | if gemspec.respond_to?(:add_runtime_dependency) 108 | gemspec.add_runtime_dependency(name,*version) 109 | else 110 | gemspec.add_dependency(name,*version) 111 | end 112 | else 113 | # populate development dependencies 114 | if gemspec.respond_to?(:add_development_dependency) 115 | gemspec.add_development_dependency(name,*version) 116 | else 117 | gemspec.add_dependency(name,*version) 118 | end 119 | end 120 | end 121 | 122 | # convert external dependencies into a requirements 123 | if metadata['external_dependencies'] 124 | ##gemspec.requirements = [] unless metadata['external_dependencies'].empty? 125 | metadata['external_dependencies'].each do |req| 126 | gemspec.requirements << req.to_s 127 | end 128 | end 129 | 130 | # determine homepage from resources 131 | homepage = metadata['resources'].find{ |key, url| key =~ /^home/ } 132 | gemspec.homepage = homepage.last if homepage 133 | 134 | gemspec.require_paths = metadata['load_path'] || ['lib'] 135 | gemspec.post_install_message = metadata['install_message'] 136 | 137 | # RubyGems specific metadata 138 | gemspec.files = files 139 | gemspec.extensions = extensions 140 | gemspec.executables = executables 141 | 142 | if Gem::VERSION < '1.7.' 143 | gemspec.default_executable = gemspec.executables.first 144 | end 145 | 146 | gemspec.test_files = glob_files[patterns[:test_files]] 147 | 148 | unless gemspec.files.include?('.document') 149 | gemspec.extra_rdoc_files = glob_files[patterns[:doc_files]] 150 | end 151 | end 152 | end 153 | --------------------------------------------------------------------------------