Permalink
Browse files

Initial (and uncomplete) commit

  • Loading branch information...
0 parents commit 54b039694b87aeb982dc91bbd2975e5aeecfe994 @meineerde committed Dec 25, 2011
Showing with 489 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. +4 −0 Gemfile
  3. +72 −0 README.textile
  4. +1 −0 Rakefile
  5. +179 −0 bin/reposman
  6. 0 doc/COPYRIGHT.rdoc
  7. +6 −0 lib/reposman.rb
  8. +116 −0 lib/reposman/application.rb
  9. +74 −0 lib/reposman/options.rb
  10. +7 −0 lib/reposman/project.rb
  11. +3 −0 lib/reposman/version.rb
  12. +23 −0 reposman.gemspec
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in reposman.gemspec
+gemspec
@@ -0,0 +1,72 @@
+h1. Reposman for ChiliProject
+
+<pre>
+Synopsis
+--------
+
+ reposman: Manage and create Repositories for ChiliProject
+
+Usage
+-----
+
+ reposman [OPTIONS] -b [DIR] -h [URL]
+
+ Examples:
+ reposman --repo-base=/var/lib/git --chiliproject=chili.example.net --svm=git
+ reposman -b /var/lib/svn -h chili.example.net -u http://svn.example.net --scm=subversion
+
+Arguments (mandatory)
+---------------------
+
+ -b, --repo-base=DIR Use DIR as base directories for repositories
+ -h, --chiliproject=HOST Assume ChiliProject is hosted at URL. Repositories
+ will be registered there. Examples:
+ -c http://chili.example.net
+ -c https://example.net/chiliproject
+
+ -k, --key=KEY Use KEY as the ChiliProject Repository API key
+
+Options
+-------
+
+ -o, --owner=OWNER Owner of the created repositories. Default: current user
+ -g, --group=GROUP Group of the created repositories. Default: current group
+ -m, --mode=MODE The file mode the repository is created with.
+
+ Owner and Group can only be changed if this script runs as root. Consider
+ in your choices that depending on your setup, the Apache user (e.g. www-data)
+ has to read and write to the repositories while the ChiliProject user
+ (e.g. chiliproject) has to read it.
+
+ --scm=SCM The type of repository to create and register to
+ ChiliProject. Default: Subversion
+ reposman is able to create Git or Subversion
+ repositories. You can use other types known to
+ ChiliProject but have to specify the --command
+ option to create these
+ -c, --command=COMMAND Override the command used to create a repository.
+ If used it will override the default command from
+ the --scm option.
+ -u, --url=URL The base URL ChiliProject will use to access the
+ repositories. If this option is not set, reposman
+ won't register the repositories.
+ Examples:
+ -u https://example.net/svn
+ -u file:///var/lib/svn
+ -u /var/lib/git
+ -f, --force Force repository creation eben if the project
+ repository is already configured in ChiliProject
+ -t, --test Only show what should be done
+ -v, --verbose Show more log information
+ -q, --quiet Don't log anything
+
+ -V, --version Print version and exit
+ --help Show this help and exit
+
+References
+----------
+
+You can find more information on the project's wiki at
+
+ https://www.chiliproject.org/projects/reposman/wiki
+</pre>
@@ -0,0 +1 @@
+require "bundler/gem_tasks"
@@ -0,0 +1,179 @@
+#!/usr/bin/env ruby -wKU
+
+require 'getoptlong'
+require 'etc'
+require 'reposman'
+
+
+
+$usage_text = <<-END_OF_USAGE
+
+Synopsis
+--------
+
+ reposman: Manage and create Repositories for ChiliProject
+
+Usage
+-----
+
+ reposman [OPTIONS] -b [DIR] -h [URL]
+
+ Examples:
+ reposman --repo-base=/var/lib/git --chiliproject=chili.example.net --svm=git
+ reposman -b /var/lib/svn -h chili.example.net -u http://svn.example.net --scm=subversion
+
+Arguments (mandatory)
+---------------------
+
+ -b, --repo-base=DIR Use DIR as base directories for repositories
+ -h, --chiliproject=HOST Assume ChiliProject is hosted at URL. Repositories
+ will be registered there. Examples:
+ -c http://chili.example.net
+ -c https://example.net/chiliproject
+
+ -k, --key=KEY Use KEY as the ChiliProject Repository API key
+
+Options
+-------
+
+ -o, --owner=OWNER Owner of the created repositories. Default: #{Etc.getpwuid(Process.euid).name}
+ -g, --group=GROUP Group of the created repositories. Default: #{Etc.getgrgid(Process.egid).name}
+ -m, --mode=MODE The file mode the repository is created with.
+
+ Owner and Group can only be changed if this script runs as root. Consider
+ in your choices that depending on your setup, the Apache user (e.g. www-data)
+ has to read and write to the repositories while the ChiliProject user
+ (e.g. chiliproject) has to read it.
+
+ --scm=SCM The type of repository to create and register to
+ ChiliProject. Default: Subversion
+ reposman is able to create Git or Subversion
+ repositories. You can use other types known to
+ ChiliProject but have to specify the --command
+ option to create these
+ -c, --command=COMMAND Override the command used to create a repository.
+ If used it will override the default command from
+ the --scm option.
+ -u, --url=URL The base URL ChiliProject will use to access the
+ repositories. If this option is not set, reposman
+ won't register the repositories.
+ Examples:
+ -u https://example.net/svn
+ -u file:///var/lib/svn
+ -u /var/lib/git
+ -f, --force Force repository creation eben if the project
+ repository is already configured in ChiliProject
+ -t, --test Only show what should be done
+ -v, --verbose Show more log information
+ -q, --quiet Don't log anything
+
+ -V, --version Print version and exit
+ --help Show this help and exit
+
+References
+----------
+
+You can find more information on the project's wiki at
+
+ https://www.chiliproject.org/projects/reposman/wiki
+
+END_OF_USAGE
+
+SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
+options = Reposman::Options.new
+$options = options
+
+def usage(exit_code=0)
+ puts $usage_text
+ exit exit_code
+end
+
+def log(text, args={})
+ Reposman::Application.log(text, $options, args)
+end
+
+opts = GetoptLong.new(
+ ['--repo-base', '-b', GetoptLong::REQUIRED_ARGUMENT],
+ ['--svn-dir', '-s', GetoptLong::REQUIRED_ARGUMENT], # deprecated
+ ['--chiliproject', '-h', GetoptLong::REQUIRED_ARGUMENT],
+ ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT], # deprecated
+ ['--key', '-k', GetoptLong::REQUIRED_ARGUMENT],
+
+ ['--owner', '-o', GetoptLong::REQUIRED_ARGUMENT],
+ ['--group', '-g', GetoptLong::REQUIRED_ARGUMENT],
+ ['--mode', '-m', GetoptLong::REQUIRED_ARGUMENT],
+ ['--scm', GetoptLong::REQUIRED_ARGUMENT],
+ ['--command', '-c', GetoptLong::REQUIRED_ARGUMENT],
+ ['--url', '-u', GetoptLong::REQUIRED_ARGUMENT],
+ ['--test', '-t', GetoptLong::NO_ARGUMENT],
+ ['--force', '-f', GetoptLong::NO_ARGUMENT],
+ ['--verbose', '-v', GetoptLong::NO_ARGUMENT],
+ ['--quiet', '-q', GetoptLong::NO_ARGUMENT],
+ ['--version', '-V', GetoptLong::NO_ARGUMENT],
+ ['--help', GetoptLong::NO_ARGUMENT]
+)
+
+
+begin
+ opts.each do |opt, arg|
+ case opt
+ when '--repo-base', '--svn-dir':
+ options.repo_base = arg.strip
+ when '--chiliproject', '--redmine-host'
+ url = arg.strip
+
+ url.gsub!(/^/, "http://") unless url.match("^https?://")
+ url.gsub!(/\/$/, '')
+ options.chiliproject = url
+ when '--key'
+ options.api_key = arg.dup
+ when '--owner'
+ if arg.strip == arg.to_i.to_s
+ options.owner = arg.to_i
+ else
+ options.owner = Etc.getpwnam(arg.strip).ui
+ end
+ when '--group'
+ if arg.strip == arg.to_i.to_s
+ options.group = arg.to_i
+ else
+ options.group = Etc.getgrnam(arg.strip).gid
+ end
+ when 'mode'
+ options.mode = arg
+ if arg.length > 3 || arg != arg.to_i.to_s
+ log("Invalid mode: #{arg}", :exit => 1)
+ else
+ options.mode = arg.to_i
+ end
+ when '--scm'
+ options.scm = arg.capitalize
+ unless SUPPORTED_SCM.include?(options.scm)
+ log("Invalid SCM: #{options.scm}", :exit => 1)
+ end
+ when 'command': options.command = arg.dup
+ when '--url': options.url = arg.dup
+
+ when '--test': options.test = true
+ when '--force': options.force = true
+ when '--verbose': options.verbose += 1
+ when '--quiet': options.quiet = true
+
+ when '--version': puts Reposman::VERSION && exit
+ when '--help': usage
+ else usage(1)
+ end
+
+ end
+rescue => e
+ log("ERROR: #{e.message}")
+ usage(1)
+end
+
+# key is not formally mandatory
+if options.repo_base.strip.empty? || options.chiliproject.strip.empty?
+ log("ERROR: --repo-base and --chiliproject arguments are mandatory!")
+ usage(1)
+end
+
+Reposman::Application.new(options).run!
No changes.
@@ -0,0 +1,6 @@
+require 'reposman/version'
+require 'reposman/options'
+require 'reposman/application'
+
+module Reposman
+end
@@ -0,0 +1,116 @@
+module Reposman
+ class Application
+ def initialize (options = Options.new)
+ @options = options
+
+ @umasks = []
+ end
+
+ attr_reader :options
+
+ def run!
+ log("Running in test mode") if options.test
+
+ options.url << "/" unless options.url.end_with?("/")
+ unless File.directory?(options.repo_base)
+ log("The directory #{options.repo_base} doesn't exist", exit => true)
+ end
+
+ begin
+ log("Querying ChiliProject for projects...", :level => 1);
+ projects = project_class.all(:params => {:key => options.api_key})
+ rescue => e
+ log("ERROR: Unable to connect to #{Project.site}: #{e}", :exit => true)
+ end
+
+ if projects.nil?
+ log('ERROR: No project found, perhaps you forgot to "Enable WS for repository management"', :exit => 0)
+ end
+
+ log("Retrieved #{projects.size} projects", :level => 1)
+ projects.each{|p| log("\t#{p.identifier}", :level => 2)}
+
+ projects.each do |project|
+ handle_project(project)
+ end
+ end
+
+ def project_class
+ @project_class ||= begin
+ cls = Class.new(Reposman::Project)
+ cls.site = options.chiliproject
+ cls
+ end
+ end
+
+ def handle_project(project)
+ log("Handling project #{project.name}", :level => 1)
+ if project.identifier.empty?
+ log("\tNo identifier given for project #{project.name}")
+ return
+ elsif not project.identifier.match(/^[a-z0-9\-_]+$/)
+ log("\tInvalid identifier for project #{project.name}: #{project.identifier}");
+ return;
+ end
+
+ repos_path = File.join(options.repos_base, project.identifier)
+ repos_path.gsub!(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
+
+ if File.directory?(repos_path)
+ update_mode(repos_path)
+ else
+ create_repository(project, repos_path)
+ end
+
+ end
+
+ def update_mode(repos_path)
+ return log("\tchange mode on #{repos_path}") if options.test?
+
+ # TODO: update mode
+ # TODO: set_gid
+ end
+
+ def create_repository(project, repos_path)
+ if !options.force? && project.respond_to?(:repository)
+ log("\trepository for project #{project.identifier} is already configured in ChiliProject", :level => 1)
+ return
+ end
+
+ begin
+ set_owner_and_rights(repos_path) do
+ run_command()
+
+
+
+ if options.test?
+ log("\tCreated repository #{repos_path}")
+ end
+
+
+
+
+
+
+ end
+
+ def set_umask
+ umask = 777 - options.mask
+ @umasks << File.umask(umask)
+ end
+
+ def pop_umask
+ File.umask(@umasks.pop)
+ end
+
+ def self.log(text, options, args={})
+ level = args[:level] || 0
+ puts text unless options.quiet or level > options.verbose
+ exit args[:exit].to_i if args[:exit]
+ end
+
+ def log(text, args={})
+ self.class.log(text, options, args)
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 54b0396

Please sign in to comment.