Revision 1297:0a574315af3e .svn/pristine/8f
| .svn/pristine/8f/8f7d415c01cd1aa2a9653282ae2c4dbd9a43ab03.svn-base | ||
|---|---|---|
| 1 |
#!/usr/bin/env ruby |
|
| 2 |
|
|
| 3 |
require 'optparse' |
|
| 4 |
require 'find' |
|
| 5 |
require 'etc' |
|
| 6 |
require 'rubygems' |
|
| 7 |
|
|
| 8 |
Version = "1.4" |
|
| 9 |
SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem ) |
|
| 10 |
|
|
| 11 |
$verbose = 0 |
|
| 12 |
$quiet = false |
|
| 13 |
$redmine_host = '' |
|
| 14 |
$repos_base = '' |
|
| 15 |
$svn_owner = 'root' |
|
| 16 |
$svn_group = 'root' |
|
| 17 |
$use_groupid = true |
|
| 18 |
$svn_url = false |
|
| 19 |
$test = false |
|
| 20 |
$force = false |
|
| 21 |
$scm = 'Subversion' |
|
| 22 |
|
|
| 23 |
def log(text, options={})
|
|
| 24 |
level = options[:level] || 0 |
|
| 25 |
puts text unless $quiet or level > $verbose |
|
| 26 |
exit 1 if options[:exit] |
|
| 27 |
end |
|
| 28 |
|
|
| 29 |
def system_or_raise(command) |
|
| 30 |
raise "\"#{command}\" failed" unless system command
|
|
| 31 |
end |
|
| 32 |
|
|
| 33 |
module SCM |
|
| 34 |
|
|
| 35 |
module Subversion |
|
| 36 |
def self.create(path) |
|
| 37 |
system_or_raise "svnadmin create #{path}"
|
|
| 38 |
end |
|
| 39 |
end |
|
| 40 |
|
|
| 41 |
module Git |
|
| 42 |
def self.create(path) |
|
| 43 |
Dir.mkdir path |
|
| 44 |
Dir.chdir(path) do |
|
| 45 |
system_or_raise "git --bare init --shared" |
|
| 46 |
system_or_raise "git update-server-info" |
|
| 47 |
end |
|
| 48 |
end |
|
| 49 |
end |
|
| 50 |
|
|
| 51 |
end |
|
| 52 |
|
|
| 53 |
def read_key_from_file(filename) |
|
| 54 |
begin |
|
| 55 |
$api_key = File.read(filename).strip |
|
| 56 |
rescue Exception => e |
|
| 57 |
$stderr.puts "Unable to read the key from #{filename}: #{e.message}"
|
|
| 58 |
exit 1 |
|
| 59 |
end |
|
| 60 |
end |
|
| 61 |
|
|
| 62 |
def set_scm(scm) |
|
| 63 |
$scm = scm.capitalize |
|
| 64 |
unless SUPPORTED_SCM.include?($scm) |
|
| 65 |
log("Invalid SCM: #{$scm}\nValid SCM are: #{SUPPORTED_SCM.join(', ')}", :exit => true)
|
|
| 66 |
end |
|
| 67 |
end |
|
| 68 |
|
|
| 69 |
optparse = OptionParser.new do |opts| |
|
| 70 |
opts.banner = "Usage: reposman.rb [OPTIONS...] -s [DIR] -r [HOST] -k [KEY]" |
|
| 71 |
opts.separator("")
|
|
| 72 |
opts.separator("Manages your repositories with Redmine.")
|
|
| 73 |
opts.separator("")
|
|
| 74 |
opts.separator("Required arguments:")
|
|
| 75 |
opts.on("-s", "--svn-dir DIR", "use DIR as base directory for svn repositories") {|v| $repos_base = v}
|
|
| 76 |
opts.on("-r", "--redmine-host HOST","assume Redmine is hosted on HOST. Examples:",
|
|
| 77 |
" -r redmine.example.net", |
|
| 78 |
" -r http://redmine.example.net", |
|
| 79 |
" -r https://redmine.example.net") {|v| $redmine_host = v}
|
|
| 80 |
opts.on("-k", "--key KEY", "use KEY as the Redmine API key",
|
|
| 81 |
"(you can use --key-file option as an alternative)") {|v| $api_key = v}
|
|
| 82 |
opts.separator("")
|
|
| 83 |
opts.separator("Options:")
|
|
| 84 |
opts.on("-o", "--owner OWNER", "owner of the repository. using the rails login",
|
|
| 85 |
"allows users to browse the repository within", |
|
| 86 |
"Redmine even for private projects. If you want to", |
|
| 87 |
"share repositories through Redmine.pm, you need", |
|
| 88 |
"to use the apache owner.") {|v| $svn_owner = v; $use_groupid = false}
|
|
| 89 |
opts.on("-g", "--group GROUP", "group of the repository (default: root)") {|v| $svn_group = v; $use_groupid = false}
|
|
| 90 |
opts.on("-u", "--url URL", "the base url Redmine will use to access your",
|
|
| 91 |
"repositories. This option is used to register", |
|
| 92 |
"the repositories in Redmine automatically. The", |
|
| 93 |
"project identifier will be appended to this url.", |
|
| 94 |
"Examples:", |
|
| 95 |
" -u https://example.net/svn", |
|
| 96 |
" -u file:///var/svn/", |
|
| 97 |
"if this option isn't set, reposman won't register", |
|
| 98 |
"the repositories in Redmine") {|v| $svn_url = v}
|
|
| 99 |
opts.on( "--scm SCM", "the kind of SCM repository you want to create", |
|
| 100 |
"(and register) in Redmine (default: Subversion).", |
|
| 101 |
"reposman is able to create Git and Subversion", |
|
| 102 |
"repositories.", |
|
| 103 |
"For all other kind, you must specify a --command", |
|
| 104 |
"option") {|v| set_scm(v)}
|
|
| 105 |
opts.on("-c", "--command COMMAND", "use this command instead of `svnadmin create` to",
|
|
| 106 |
"create a repository. This option can be used to", |
|
| 107 |
"create repositories other than subversion and git", |
|
| 108 |
"kind.", |
|
| 109 |
"This command override the default creation for", |
|
| 110 |
"git and subversion.") {|v| $command = v}
|
|
| 111 |
opts.on( "--key-file FILE", "path to a file that contains the Redmine API key", |
|
| 112 |
"(use this option instead of --key if you don't", |
|
| 113 |
"want the key to appear in the command line)") {|v| read_key_from_file(v)}
|
|
| 114 |
opts.on("-t", "--test", "only show what should be done") {$test = true}
|
|
| 115 |
opts.on("-f", "--force", "force repository creation even if the project", "repository is already declared in Redmine") {$force = true}
|
|
| 116 |
opts.on("-v", "--verbose", "verbose") {$verbose += 1}
|
|
| 117 |
opts.on("-V", "--version", "show version and exit") {puts Version; exit}
|
|
| 118 |
opts.on("-h", "--help", "show help and exit") {puts opts; exit 1}
|
|
| 119 |
opts.on("-q", "--quiet", "no log") {$quiet = true}
|
|
| 120 |
opts.separator("")
|
|
| 121 |
opts.separator("Examples:")
|
|
| 122 |
opts.separator(" reposman.rb --svn-dir=/var/svn --redmine-host=redmine.host")
|
|
| 123 |
opts.separator(" reposman.rb -s /var/git -r redmine.host -u http://git.host --scm git")
|
|
| 124 |
opts.separator("")
|
|
| 125 |
opts.separator("You can find more information on the redmine's wiki:\nhttp://www.redmine.org/projects/redmine/wiki/HowTos")
|
|
| 126 |
|
|
| 127 |
opts.summary_width = 25 |
|
| 128 |
end |
|
| 129 |
optparse.parse! |
|
| 130 |
|
|
| 131 |
if $test |
|
| 132 |
log("running in test mode")
|
|
| 133 |
end |
|
| 134 |
|
|
| 135 |
# Make sure command is overridden if SCM vendor is not handled internally (for the moment Subversion and Git) |
|
| 136 |
if $command.nil? |
|
| 137 |
begin |
|
| 138 |
scm_module = SCM.const_get($scm) |
|
| 139 |
rescue |
|
| 140 |
log("Please use --command option to specify how to create a #{$scm} repository.", :exit => true)
|
|
| 141 |
end |
|
| 142 |
end |
|
| 143 |
|
|
| 144 |
$svn_url += "/" if $svn_url and not $svn_url.match(/\/$/) |
|
| 145 |
|
|
| 146 |
if ($redmine_host.empty? or $repos_base.empty?) |
|
| 147 |
puts "Some arguments are missing. Use reposman.rb --help for getting help." |
|
| 148 |
exit 1 |
|
| 149 |
end |
|
| 150 |
|
|
| 151 |
unless File.directory?($repos_base) |
|
| 152 |
log("directory '#{$repos_base}' doesn't exists", :exit => true)
|
|
| 153 |
end |
|
| 154 |
|
|
| 155 |
begin |
|
| 156 |
require 'active_resource' |
|
| 157 |
rescue LoadError |
|
| 158 |
log("This script requires activeresource.\nRun 'gem install activeresource' to install it.", :exit => true)
|
|
| 159 |
end |
|
| 160 |
|
|
| 161 |
class Project < ActiveResource::Base |
|
| 162 |
self.headers["User-agent"] = "Redmine repository manager/#{Version}"
|
|
| 163 |
self.format = :xml |
|
| 164 |
end |
|
| 165 |
|
|
| 166 |
log("querying Redmine for projects...", :level => 1);
|
|
| 167 |
|
|
| 168 |
$redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
|
|
| 169 |
$redmine_host.gsub!(/\/$/, '') |
|
| 170 |
|
|
| 171 |
Project.site = "#{$redmine_host}/sys";
|
|
| 172 |
|
|
| 173 |
begin |
|
| 174 |
# Get all active projects that have the Repository module enabled |
|
| 175 |
projects = Project.find(:all, :params => {:key => $api_key})
|
|
| 176 |
rescue ActiveResource::ForbiddenAccess |
|
| 177 |
log("Request was denied by your Redmine server. Make sure that 'WS for repository management' is enabled in application settings and that you provided the correct API key.")
|
|
| 178 |
rescue => e |
|
| 179 |
log("Unable to connect to #{Project.site}: #{e}", :exit => true)
|
|
| 180 |
end |
|
| 181 |
|
|
| 182 |
if projects.nil? |
|
| 183 |
log('No project found, perhaps you forgot to "Enable WS for repository management"', :exit => true)
|
|
| 184 |
end |
|
| 185 |
|
|
| 186 |
log("retrieved #{projects.size} projects", :level => 1)
|
|
| 187 |
|
|
| 188 |
def set_owner_and_rights(project, repos_path, &block) |
|
| 189 |
if mswin? |
|
| 190 |
yield if block_given? |
|
| 191 |
else |
|
| 192 |
uid, gid = Etc.getpwnam($svn_owner).uid, ($use_groupid ? Etc.getgrnam(project.identifier).gid : Etc.getgrnam($svn_group).gid) |
|
| 193 |
right = project.is_public ? 0775 : 0770 |
|
| 194 |
yield if block_given? |
|
| 195 |
Find.find(repos_path) do |f| |
|
| 196 |
File.chmod right, f |
|
| 197 |
File.chown uid, gid, f |
|
| 198 |
end |
|
| 199 |
end |
|
| 200 |
end |
|
| 201 |
|
|
| 202 |
def other_read_right?(file) |
|
| 203 |
(File.stat(file).mode & 0007).zero? ? false : true |
|
| 204 |
end |
|
| 205 |
|
|
| 206 |
def owner_name(file) |
|
| 207 |
mswin? ? |
|
| 208 |
$svn_owner : |
|
| 209 |
Etc.getpwuid( File.stat(file).uid ).name |
|
| 210 |
end |
|
| 211 |
|
|
| 212 |
def mswin? |
|
| 213 |
(RUBY_PLATFORM =~ /(:?mswin|mingw)/) || (RUBY_PLATFORM == 'java' && (ENV['OS'] || ENV['os']) =~ /windows/i) |
|
| 214 |
end |
|
| 215 |
|
|
| 216 |
projects.each do |project| |
|
| 217 |
log("treating project #{project.name}", :level => 1)
|
|
| 218 |
|
|
| 219 |
if project.identifier.empty? |
|
| 220 |
log("\tno identifier for project #{project.name}")
|
|
| 221 |
next |
|
| 222 |
elsif not project.identifier.match(/^[a-z0-9\-_]+$/) |
|
| 223 |
log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
|
|
| 224 |
next; |
|
| 225 |
end |
|
| 226 |
|
|
| 227 |
repos_path = File.join($repos_base, project.identifier).gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR) |
|
| 228 |
|
|
| 229 |
if File.directory?(repos_path) |
|
| 230 |
# we must verify that repository has the good owner and the good |
|
| 231 |
# rights before leaving |
|
| 232 |
other_read = other_read_right?(repos_path) |
|
| 233 |
owner = owner_name(repos_path) |
|
| 234 |
next if project.is_public == other_read and owner == $svn_owner |
|
| 235 |
|
|
| 236 |
if $test |
|
| 237 |
log("\tchange mode on #{repos_path}")
|
|
| 238 |
next |
|
| 239 |
end |
|
| 240 |
|
|
| 241 |
begin |
|
| 242 |
set_owner_and_rights(project, repos_path) |
|
| 243 |
rescue Errno::EPERM => e |
|
| 244 |
log("\tunable to change mode on #{repos_path} : #{e}\n")
|
|
| 245 |
next |
|
| 246 |
end |
|
| 247 |
|
|
| 248 |
log("\tmode change on #{repos_path}");
|
|
| 249 |
|
|
| 250 |
else |
|
| 251 |
# if repository is already declared in redmine, we don't create |
|
| 252 |
# unless user use -f with reposman |
|
| 253 |
if $force == false and project.respond_to?(:repository) |
|
| 254 |
log("\trepository for project #{project.identifier} already exists in Redmine", :level => 1)
|
|
| 255 |
next |
|
| 256 |
end |
|
| 257 |
|
|
| 258 |
project.is_public ? File.umask(0002) : File.umask(0007) |
|
| 259 |
|
|
| 260 |
if $test |
|
| 261 |
log("\tcreate repository #{repos_path}")
|
|
| 262 |
log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}") if $svn_url;
|
|
| 263 |
next |
|
| 264 |
end |
|
| 265 |
|
|
| 266 |
begin |
|
| 267 |
set_owner_and_rights(project, repos_path) do |
|
| 268 |
if scm_module.nil? |
|
| 269 |
system_or_raise "#{$command} #{repos_path}"
|
|
| 270 |
else |
|
| 271 |
scm_module.create(repos_path) |
|
| 272 |
end |
|
| 273 |
end |
|
| 274 |
rescue => e |
|
| 275 |
log("\tunable to create #{repos_path} : #{e}\n")
|
|
| 276 |
next |
|
| 277 |
end |
|
| 278 |
|
|
| 279 |
if $svn_url |
|
| 280 |
begin |
|
| 281 |
project.post(:repository, :vendor => $scm, :repository => {:url => "#{$svn_url}#{project.identifier}"}, :key => $api_key)
|
|
| 282 |
log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}");
|
|
| 283 |
rescue => e |
|
| 284 |
log("\trepository #{repos_path} not registered in Redmine: #{e.message}");
|
|
| 285 |
end |
|
| 286 |
end |
|
| 287 |
log("\trepository #{repos_path} created");
|
|
| 288 |
end |
|
| 289 |
end |
|
| .svn/pristine/8f/8fa37bd50f73aaaf794ed1e7474b6ffe3abf2008.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
module Redmine |
|
| 19 |
module Utils |
|
| 20 |
class << self |
|
| 21 |
# Returns the relative root url of the application |
|
| 22 |
def relative_url_root |
|
| 23 |
ActionController::Base.respond_to?('relative_url_root') ?
|
|
| 24 |
ActionController::Base.relative_url_root.to_s : |
|
| 25 |
ActionController::Base.config.relative_url_root.to_s |
|
| 26 |
end |
|
| 27 |
|
|
| 28 |
# Sets the relative root url of the application |
|
| 29 |
def relative_url_root=(arg) |
|
| 30 |
if ActionController::Base.respond_to?('relative_url_root=')
|
|
| 31 |
ActionController::Base.relative_url_root=arg |
|
| 32 |
else |
|
| 33 |
ActionController::Base.config.relative_url_root = arg |
|
| 34 |
end |
|
| 35 |
end |
|
| 36 |
|
|
| 37 |
# Generates a n bytes random hex string |
|
| 38 |
# Example: |
|
| 39 |
# random_hex(4) # => "89b8c729" |
|
| 40 |
def random_hex(n) |
|
| 41 |
SecureRandom.hex(n) |
|
| 42 |
end |
|
| 43 |
end |
|
| 44 |
|
|
| 45 |
module Shell |
|
| 46 |
def shell_quote(str) |
|
| 47 |
if Redmine::Platform.mswin? |
|
| 48 |
'"' + str.gsub(/"/, '\\"') + '"' |
|
| 49 |
else |
|
| 50 |
"'" + str.gsub(/'/, "'\"'\"'") + "'" |
|
| 51 |
end |
|
| 52 |
end |
|
| 53 |
end |
|
| 54 |
|
|
| 55 |
module DateCalculation |
|
| 56 |
# Returns the number of working days between from and to |
|
| 57 |
def working_days(from, to) |
|
| 58 |
days = (to - from).to_i |
|
| 59 |
if days > 0 |
|
| 60 |
weeks = days / 7 |
|
| 61 |
result = weeks * (7 - non_working_week_days.size) |
|
| 62 |
days_left = days - weeks * 7 |
|
| 63 |
start_cwday = from.cwday |
|
| 64 |
days_left.times do |i| |
|
| 65 |
unless non_working_week_days.include?(((start_cwday + i - 1) % 7) + 1) |
|
| 66 |
result += 1 |
|
| 67 |
end |
|
| 68 |
end |
|
| 69 |
result |
|
| 70 |
else |
|
| 71 |
0 |
|
| 72 |
end |
|
| 73 |
end |
|
| 74 |
|
|
| 75 |
# Adds working days to the given date |
|
| 76 |
def add_working_days(date, working_days) |
|
| 77 |
if working_days > 0 |
|
| 78 |
weeks = working_days / (7 - non_working_week_days.size) |
|
| 79 |
result = weeks * 7 |
|
| 80 |
days_left = working_days - weeks * (7 - non_working_week_days.size) |
|
| 81 |
cwday = date.cwday |
|
| 82 |
while days_left > 0 |
|
| 83 |
cwday += 1 |
|
| 84 |
unless non_working_week_days.include?(((cwday - 1) % 7) + 1) |
|
| 85 |
days_left -= 1 |
|
| 86 |
end |
|
| 87 |
result += 1 |
|
| 88 |
end |
|
| 89 |
next_working_date(date + result) |
|
| 90 |
else |
|
| 91 |
date |
|
| 92 |
end |
|
| 93 |
end |
|
| 94 |
|
|
| 95 |
# Returns the date of the first day on or after the given date that is a working day |
|
| 96 |
def next_working_date(date) |
|
| 97 |
cwday = date.cwday |
|
| 98 |
days = 0 |
|
| 99 |
while non_working_week_days.include?(((cwday + days - 1) % 7) + 1) |
|
| 100 |
days += 1 |
|
| 101 |
end |
|
| 102 |
date + days |
|
| 103 |
end |
|
| 104 |
|
|
| 105 |
# Returns the index of non working week days (1=monday, 7=sunday) |
|
| 106 |
def non_working_week_days |
|
| 107 |
@non_working_week_days ||= begin |
|
| 108 |
days = Setting.non_working_week_days |
|
| 109 |
if days.is_a?(Array) && days.size < 7 |
|
| 110 |
days.map(&:to_i) |
|
| 111 |
else |
|
| 112 |
[] |
|
| 113 |
end |
|
| 114 |
end |
|
| 115 |
end |
|
| 116 |
end |
|
| 117 |
end |
|
| 118 |
end |
|
| .svn/pristine/8f/8fb92a4b5691357b3504f3727bbca8084c1fed1a.svn-base | ||
|---|---|---|
| 1 |
Return-Path: <JSmith@somenet.foo> |
|
| 2 |
Received: from osiris ([127.0.0.1]) |
|
| 3 |
by OSIRIS |
|
| 4 |
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200 |
|
| 5 |
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> |
|
| 6 |
From: "John Smith" <JSmith@somenet.foo> |
|
| 7 |
To: <redmine@somenet.foo> |
|
| 8 |
Subject: New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say... |
|
| 9 |
Date: Sun, 22 Jun 2008 12:28:07 +0200 |
|
| 10 |
MIME-Version: 1.0 |
|
| 11 |
Content-Type: text/plain; |
|
| 12 |
format=flowed; |
|
| 13 |
charset="iso-8859-1"; |
|
| 14 |
reply-type=original |
|
| 15 |
Content-Transfer-Encoding: 7bit |
|
| 16 |
X-Priority: 3 |
|
| 17 |
X-MSMail-Priority: Normal |
|
| 18 |
X-Mailer: Microsoft Outlook Express 6.00.2900.2869 |
|
| 19 |
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 |
|
| 20 |
|
|
| 21 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet |
|
| 22 |
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus |
|
| 23 |
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti |
|
| 24 |
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In |
|
| 25 |
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras |
|
| 26 |
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum |
|
| 27 |
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus |
|
| 28 |
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique |
|
| 29 |
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et |
|
| 30 |
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse |
|
| 31 |
platea dictumst. |
|
| 32 |
|
|
| 33 |
--- This line starts with a delimiter and should not be stripped |
|
| 34 |
|
|
| 35 |
This paragraph is before delimiters. |
|
| 36 |
|
|
| 37 |
BREAK |
|
| 38 |
|
|
| 39 |
This paragraph is between delimiters. |
|
| 40 |
|
|
| 41 |
--- |
|
| 42 |
|
|
| 43 |
This paragraph is after the delimiter so it shouldn't appear. |
|
| 44 |
|
|
| 45 |
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque |
|
| 46 |
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. |
|
| 47 |
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, |
|
| 48 |
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, |
|
| 49 |
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo |
|
| 50 |
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus. |
|
| 51 |
|
|
| 52 |
Project: onlinestore |
|
| 53 |
Status: Resolved |
|
| 54 |
due date: 2010-12-31 |
|
| 55 |
Start Date:2010-01-01 |
|
| 56 |
Assigned to: John Smith |
|
| 57 |
|
|
| .svn/pristine/8f/8fdff2fea815e65bfcdb8ed501cd30a4424623ff.svn-base | ||
|---|---|---|
| 1 |
<div class="autoscroll"> |
|
| 2 |
<table class="filecontent syntaxhl"> |
|
| 3 |
<tbody> |
|
| 4 |
<% line_num = 1 %> |
|
| 5 |
<% syntax_highlight_lines(filename, Redmine::CodesetUtil.to_utf8_by_setting(content)).each do |line| %> |
|
| 6 |
<tr> |
|
| 7 |
<th class="line-num" id="L<%= line_num %>"> |
|
| 8 |
<a href="#L<%= line_num %>"><%= line_num %></a> |
|
| 9 |
</th> |
|
| 10 |
<td class="line-code"> |
|
| 11 |
<pre><%= line.html_safe %></pre> |
|
| 12 |
</td> |
|
| 13 |
</tr> |
|
| 14 |
<% line_num += 1 %> |
|
| 15 |
<% end %> |
|
| 16 |
</tbody> |
|
| 17 |
</table> |
|
| 18 |
</div> |
|
Also available in: Unified diff