parent
5720b26086
commit
3f7109e195
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'rack' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('rack', 'rackup', version) |
|
||||||
else |
|
||||||
gem "rack", version |
|
||||||
load Gem.bin_path("rack", "rackup", version) |
|
||||||
end |
|
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'rdoc' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('rdoc', 'rdoc', version) |
|
||||||
else |
|
||||||
gem "rdoc", version |
|
||||||
load Gem.bin_path("rdoc", "rdoc", version) |
|
||||||
end |
|
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'rdoc' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('rdoc', 'ri', version) |
|
||||||
else |
|
||||||
gem "rdoc", version |
|
||||||
load Gem.bin_path("rdoc", "ri", version) |
|
||||||
end |
|
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'slim' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('slim', 'slimrb', version) |
|
||||||
else |
|
||||||
gem "slim", version |
|
||||||
load Gem.bin_path("slim", "slimrb", version) |
|
||||||
end |
|
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'tilt' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('tilt', 'tilt', version) |
|
||||||
else |
|
||||||
gem "tilt", version |
|
||||||
load Gem.bin_path("tilt", "tilt", version) |
|
||||||
end |
|
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'yard' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('yard', 'yard', version) |
|
||||||
else |
|
||||||
gem "yard", version |
|
||||||
load Gem.bin_path("yard", "yard", version) |
|
||||||
end |
|
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'yard' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('yard', 'yardoc', version) |
|
||||||
else |
|
||||||
gem "yard", version |
|
||||||
load Gem.bin_path("yard", "yardoc", version) |
|
||||||
end |
|
@ -1,29 +0,0 @@ |
|||||||
#!/usr/bin/env ruby |
|
||||||
# |
|
||||||
# This file was generated by RubyGems. |
|
||||||
# |
|
||||||
# The application 'yard' is installed as part of a gem, and |
|
||||||
# this file is here to facilitate running it. |
|
||||||
# |
|
||||||
|
|
||||||
require 'rubygems' |
|
||||||
|
|
||||||
Gem.use_gemdeps |
|
||||||
|
|
||||||
version = ">= 0.a" |
|
||||||
|
|
||||||
str = ARGV.first |
|
||||||
if str |
|
||||||
str = str.b[/\A_(.*)_\z/, 1] |
|
||||||
if str and Gem::Version.correct?(str) |
|
||||||
version = str |
|
||||||
ARGV.shift |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
if Gem.respond_to?(:activate_bin_path) |
|
||||||
load Gem.activate_bin_path('yard', 'yri', version) |
|
||||||
else |
|
||||||
gem "yard", version |
|
||||||
load Gem.bin_path("yard", "yri", version) |
|
||||||
end |
|
@ -1 +0,0 @@ |
|||||||
Subproject commit 226e048f615bdf068e65010d47f8cb143fd08865 |
|
Binary file not shown.
Binary file not shown.
@ -1,8 +0,0 @@ |
|||||||
226e048f615bdf068e65010d47f8cb143fd08865 branch 'master' of https://github.com/chrisb/yard-sinatra |
|
||||||
226e048f615bdf068e65010d47f8cb143fd08865 branch 'swagger-2' of https://github.com/chrisb/yard-sinatra |
|
||||||
2fae74f3302c8a6a0563f88bbc37a0e2da7a654e branch 'work' of https://github.com/chrisb/yard-sinatra |
|
||||||
f5ca95436ba9db78f47e37c04dfca921285f911e not-for-merge tag 'v0.4.0' of https://github.com/chrisb/yard-sinatra |
|
||||||
b81262e2cc9f051650c6f0fc9889a8f8e9a1ab21 not-for-merge tag 'v0.4.0.1' of https://github.com/chrisb/yard-sinatra |
|
||||||
f9152938e4b85f4011420903bd986d516a8c5771 not-for-merge tag 'v0.5.0' of https://github.com/chrisb/yard-sinatra |
|
||||||
8e7a96bced01378f5d5d47ebe7a5f5403a324d52 not-for-merge tag 'v0.5.1' of https://github.com/chrisb/yard-sinatra |
|
||||||
a730ffa306d1709ba9b551c1056622e54e50d7e7 not-for-merge tag 'v1.0.0' of https://github.com/chrisb/yard-sinatra |
|
@ -1 +0,0 @@ |
|||||||
ref: refs/heads/master |
|
@ -1,6 +0,0 @@ |
|||||||
[core] |
|
||||||
repositoryformatversion = 0 |
|
||||||
filemode = true |
|
||||||
bare = true |
|
||||||
[remote "origin"] |
|
||||||
url = https://github.com/chrisb/yard-sinatra |
|
@ -1 +0,0 @@ |
|||||||
Unnamed repository; edit this file 'description' to name the repository. |
|
@ -1,15 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to check the commit log message taken by |
|
||||||
# applypatch from an e-mail message. |
|
||||||
# |
|
||||||
# The hook should exit with non-zero status after issuing an |
|
||||||
# appropriate message if it wants to stop the commit. The hook is |
|
||||||
# allowed to edit the commit message file. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "applypatch-msg". |
|
||||||
|
|
||||||
. git-sh-setup |
|
||||||
commitmsg="$(git rev-parse --git-path hooks/commit-msg)" |
|
||||||
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} |
|
||||||
: |
|
@ -1,24 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to check the commit log message. |
|
||||||
# Called by "git commit" with one argument, the name of the file |
|
||||||
# that has the commit message. The hook should exit with non-zero |
|
||||||
# status after issuing an appropriate message if it wants to stop the |
|
||||||
# commit. The hook is allowed to edit the commit message file. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "commit-msg". |
|
||||||
|
|
||||||
# Uncomment the below to add a Signed-off-by line to the message. |
|
||||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg |
|
||||||
# hook is more suited to it. |
|
||||||
# |
|
||||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') |
|
||||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" |
|
||||||
|
|
||||||
# This example catches duplicate Signed-off-by lines. |
|
||||||
|
|
||||||
test "" = "$(grep '^Signed-off-by: ' "$1" | |
|
||||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { |
|
||||||
echo >&2 Duplicate Signed-off-by lines. |
|
||||||
exit 1 |
|
||||||
} |
|
@ -1,173 +0,0 @@ |
|||||||
#!/usr/bin/perl |
|
||||||
|
|
||||||
use strict; |
|
||||||
use warnings; |
|
||||||
use IPC::Open2; |
|
||||||
|
|
||||||
# An example hook script to integrate Watchman |
|
||||||
# (https://facebook.github.io/watchman/) with git to speed up detecting |
|
||||||
# new and modified files. |
|
||||||
# |
|
||||||
# The hook is passed a version (currently 2) and last update token |
|
||||||
# formatted as a string and outputs to stdout a new update token and |
|
||||||
# all files that have been modified since the update token. Paths must |
|
||||||
# be relative to the root of the working tree and separated by a single NUL. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "query-watchman" and set |
|
||||||
# 'git config core.fsmonitor .git/hooks/query-watchman' |
|
||||||
# |
|
||||||
my ($version, $last_update_token) = @ARGV; |
|
||||||
|
|
||||||
# Uncomment for debugging |
|
||||||
# print STDERR "$0 $version $last_update_token\n"; |
|
||||||
|
|
||||||
# Check the hook interface version |
|
||||||
if ($version ne 2) { |
|
||||||
die "Unsupported query-fsmonitor hook version '$version'.\n" . |
|
||||||
"Falling back to scanning...\n"; |
|
||||||
} |
|
||||||
|
|
||||||
my $git_work_tree = get_working_dir(); |
|
||||||
|
|
||||||
my $retry = 1; |
|
||||||
|
|
||||||
my $json_pkg; |
|
||||||
eval { |
|
||||||
require JSON::XS; |
|
||||||
$json_pkg = "JSON::XS"; |
|
||||||
1; |
|
||||||
} or do { |
|
||||||
require JSON::PP; |
|
||||||
$json_pkg = "JSON::PP"; |
|
||||||
}; |
|
||||||
|
|
||||||
launch_watchman(); |
|
||||||
|
|
||||||
sub launch_watchman { |
|
||||||
my $o = watchman_query(); |
|
||||||
if (is_work_tree_watched($o)) { |
|
||||||
output_result($o->{clock}, @{$o->{files}}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sub output_result { |
|
||||||
my ($clockid, @files) = @_; |
|
||||||
|
|
||||||
# Uncomment for debugging watchman output |
|
||||||
# open (my $fh, ">", ".git/watchman-output.out"); |
|
||||||
# binmode $fh, ":utf8"; |
|
||||||
# print $fh "$clockid\n@files\n"; |
|
||||||
# close $fh; |
|
||||||
|
|
||||||
binmode STDOUT, ":utf8"; |
|
||||||
print $clockid; |
|
||||||
print "\0"; |
|
||||||
local $, = "\0"; |
|
||||||
print @files; |
|
||||||
} |
|
||||||
|
|
||||||
sub watchman_clock { |
|
||||||
my $response = qx/watchman clock "$git_work_tree"/; |
|
||||||
die "Failed to get clock id on '$git_work_tree'.\n" . |
|
||||||
"Falling back to scanning...\n" if $? != 0; |
|
||||||
|
|
||||||
return $json_pkg->new->utf8->decode($response); |
|
||||||
} |
|
||||||
|
|
||||||
sub watchman_query { |
|
||||||
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') |
|
||||||
or die "open2() failed: $!\n" . |
|
||||||
"Falling back to scanning...\n"; |
|
||||||
|
|
||||||
# In the query expression below we're asking for names of files that |
|
||||||
# changed since $last_update_token but not from the .git folder. |
|
||||||
# |
|
||||||
# To accomplish this, we're using the "since" generator to use the |
|
||||||
# recency index to select candidate nodes and "fields" to limit the |
|
||||||
# output to file names only. Then we're using the "expression" term to |
|
||||||
# further constrain the results. |
|
||||||
if (substr($last_update_token, 0, 1) eq "c") { |
|
||||||
$last_update_token = "\"$last_update_token\""; |
|
||||||
} |
|
||||||
my $query = <<" END"; |
|
||||||
["query", "$git_work_tree", { |
|
||||||
"since": $last_update_token, |
|
||||||
"fields": ["name"], |
|
||||||
"expression": ["not", ["dirname", ".git"]] |
|
||||||
}] |
|
||||||
END |
|
||||||
|
|
||||||
# Uncomment for debugging the watchman query |
|
||||||
# open (my $fh, ">", ".git/watchman-query.json"); |
|
||||||
# print $fh $query; |
|
||||||
# close $fh; |
|
||||||
|
|
||||||
print CHLD_IN $query; |
|
||||||
close CHLD_IN; |
|
||||||
my $response = do {local $/; <CHLD_OUT>}; |
|
||||||
|
|
||||||
# Uncomment for debugging the watch response |
|
||||||
# open ($fh, ">", ".git/watchman-response.json"); |
|
||||||
# print $fh $response; |
|
||||||
# close $fh; |
|
||||||
|
|
||||||
die "Watchman: command returned no output.\n" . |
|
||||||
"Falling back to scanning...\n" if $response eq ""; |
|
||||||
die "Watchman: command returned invalid output: $response\n" . |
|
||||||
"Falling back to scanning...\n" unless $response =~ /^\{/; |
|
||||||
|
|
||||||
return $json_pkg->new->utf8->decode($response); |
|
||||||
} |
|
||||||
|
|
||||||
sub is_work_tree_watched { |
|
||||||
my ($output) = @_; |
|
||||||
my $error = $output->{error}; |
|
||||||
if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { |
|
||||||
$retry--; |
|
||||||
my $response = qx/watchman watch "$git_work_tree"/; |
|
||||||
die "Failed to make watchman watch '$git_work_tree'.\n" . |
|
||||||
"Falling back to scanning...\n" if $? != 0; |
|
||||||
$output = $json_pkg->new->utf8->decode($response); |
|
||||||
$error = $output->{error}; |
|
||||||
die "Watchman: $error.\n" . |
|
||||||
"Falling back to scanning...\n" if $error; |
|
||||||
|
|
||||||
# Uncomment for debugging watchman output |
|
||||||
# open (my $fh, ">", ".git/watchman-output.out"); |
|
||||||
# close $fh; |
|
||||||
|
|
||||||
# Watchman will always return all files on the first query so |
|
||||||
# return the fast "everything is dirty" flag to git and do the |
|
||||||
# Watchman query just to get it over with now so we won't pay |
|
||||||
# the cost in git to look up each individual file. |
|
||||||
my $o = watchman_clock(); |
|
||||||
$error = $output->{error}; |
|
||||||
|
|
||||||
die "Watchman: $error.\n" . |
|
||||||
"Falling back to scanning...\n" if $error; |
|
||||||
|
|
||||||
output_result($o->{clock}, ("/")); |
|
||||||
$last_update_token = $o->{clock}; |
|
||||||
|
|
||||||
eval { launch_watchman() }; |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
die "Watchman: $error.\n" . |
|
||||||
"Falling back to scanning...\n" if $error; |
|
||||||
|
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
sub get_working_dir { |
|
||||||
my $working_dir; |
|
||||||
if ($^O =~ 'msys' || $^O =~ 'cygwin') { |
|
||||||
$working_dir = Win32::GetCwd(); |
|
||||||
$working_dir =~ tr/\\/\//; |
|
||||||
} else { |
|
||||||
require Cwd; |
|
||||||
$working_dir = Cwd::cwd(); |
|
||||||
} |
|
||||||
|
|
||||||
return $working_dir; |
|
||||||
} |
|
@ -1,8 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to prepare a packed repository for use over |
|
||||||
# dumb transports. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "post-update". |
|
||||||
|
|
||||||
exec git update-server-info |
|
@ -1,14 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to verify what is about to be committed |
|
||||||
# by applypatch from an e-mail message. |
|
||||||
# |
|
||||||
# The hook should exit with non-zero status after issuing an |
|
||||||
# appropriate message if it wants to stop the commit. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "pre-applypatch". |
|
||||||
|
|
||||||
. git-sh-setup |
|
||||||
precommit="$(git rev-parse --git-path hooks/pre-commit)" |
|
||||||
test -x "$precommit" && exec "$precommit" ${1+"$@"} |
|
||||||
: |
|
@ -1,49 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to verify what is about to be committed. |
|
||||||
# Called by "git commit" with no arguments. The hook should |
|
||||||
# exit with non-zero status after issuing an appropriate message if |
|
||||||
# it wants to stop the commit. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "pre-commit". |
|
||||||
|
|
||||||
if git rev-parse --verify HEAD >/dev/null 2>&1 |
|
||||||
then |
|
||||||
against=HEAD |
|
||||||
else |
|
||||||
# Initial commit: diff against an empty tree object |
|
||||||
against=$(git hash-object -t tree /dev/null) |
|
||||||
fi |
|
||||||
|
|
||||||
# If you want to allow non-ASCII filenames set this variable to true. |
|
||||||
allownonascii=$(git config --type=bool hooks.allownonascii) |
|
||||||
|
|
||||||
# Redirect output to stderr. |
|
||||||
exec 1>&2 |
|
||||||
|
|
||||||
# Cross platform projects tend to avoid non-ASCII filenames; prevent |
|
||||||
# them from being added to the repository. We exploit the fact that the |
|
||||||
# printable range starts at the space character and ends with tilde. |
|
||||||
if [ "$allownonascii" != "true" ] && |
|
||||||
# Note that the use of brackets around a tr range is ok here, (it's |
|
||||||
# even required, for portability to Solaris 10's /usr/bin/tr), since |
|
||||||
# the square bracket bytes happen to fall in the designated range. |
|
||||||
test $(git diff --cached --name-only --diff-filter=A -z $against | |
|
||||||
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 |
|
||||||
then |
|
||||||
cat <<\EOF |
|
||||||
Error: Attempt to add a non-ASCII file name. |
|
||||||
|
|
||||||
This can cause problems if you want to work with people on other platforms. |
|
||||||
|
|
||||||
To be portable it is advisable to rename the file. |
|
||||||
|
|
||||||
If you know what you are doing you can disable this check using: |
|
||||||
|
|
||||||
git config hooks.allownonascii true |
|
||||||
EOF |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
|
|
||||||
# If there are whitespace errors, print the offending file names and fail. |
|
||||||
exec git diff-index --check --cached $against -- |
|
@ -1,13 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to verify what is about to be committed. |
|
||||||
# Called by "git merge" with no arguments. The hook should |
|
||||||
# exit with non-zero status after issuing an appropriate message to |
|
||||||
# stderr if it wants to stop the merge commit. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "pre-merge-commit". |
|
||||||
|
|
||||||
. git-sh-setup |
|
||||||
test -x "$GIT_DIR/hooks/pre-commit" && |
|
||||||
exec "$GIT_DIR/hooks/pre-commit" |
|
||||||
: |
|
@ -1,53 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
|
|
||||||
# An example hook script to verify what is about to be pushed. Called by "git |
|
||||||
# push" after it has checked the remote status, but before anything has been |
|
||||||
# pushed. If this script exits with a non-zero status nothing will be pushed. |
|
||||||
# |
|
||||||
# This hook is called with the following parameters: |
|
||||||
# |
|
||||||
# $1 -- Name of the remote to which the push is being done |
|
||||||
# $2 -- URL to which the push is being done |
|
||||||
# |
|
||||||
# If pushing without using a named remote those arguments will be equal. |
|
||||||
# |
|
||||||
# Information about the commits which are being pushed is supplied as lines to |
|
||||||
# the standard input in the form: |
|
||||||
# |
|
||||||
# <local ref> <local oid> <remote ref> <remote oid> |
|
||||||
# |
|
||||||
# This sample shows how to prevent push of commits where the log message starts |
|
||||||
# with "WIP" (work in progress). |
|
||||||
|
|
||||||
remote="$1" |
|
||||||
url="$2" |
|
||||||
|
|
||||||
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0') |
|
||||||
|
|
||||||
while read local_ref local_oid remote_ref remote_oid |
|
||||||
do |
|
||||||
if test "$local_oid" = "$zero" |
|
||||||
then |
|
||||||
# Handle delete |
|
||||||
: |
|
||||||
else |
|
||||||
if test "$remote_oid" = "$zero" |
|
||||||
then |
|
||||||
# New branch, examine all commits |
|
||||||
range="$local_oid" |
|
||||||
else |
|
||||||
# Update to existing branch, examine new commits |
|
||||||
range="$remote_oid..$local_oid" |
|
||||||
fi |
|
||||||
|
|
||||||
# Check for WIP commit |
|
||||||
commit=$(git rev-list -n 1 --grep '^WIP' "$range") |
|
||||||
if test -n "$commit" |
|
||||||
then |
|
||||||
echo >&2 "Found WIP commit in $local_ref, not pushing" |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
fi |
|
||||||
done |
|
||||||
|
|
||||||
exit 0 |
|
@ -1,169 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# Copyright (c) 2006, 2008 Junio C Hamano |
|
||||||
# |
|
||||||
# The "pre-rebase" hook is run just before "git rebase" starts doing |
|
||||||
# its job, and can prevent the command from running by exiting with |
|
||||||
# non-zero status. |
|
||||||
# |
|
||||||
# The hook is called with the following parameters: |
|
||||||
# |
|
||||||
# $1 -- the upstream the series was forked from. |
|
||||||
# $2 -- the branch being rebased (or empty when rebasing the current branch). |
|
||||||
# |
|
||||||
# This sample shows how to prevent topic branches that are already |
|
||||||
# merged to 'next' branch from getting rebased, because allowing it |
|
||||||
# would result in rebasing already published history. |
|
||||||
|
|
||||||
publish=next |
|
||||||
basebranch="$1" |
|
||||||
if test "$#" = 2 |
|
||||||
then |
|
||||||
topic="refs/heads/$2" |
|
||||||
else |
|
||||||
topic=`git symbolic-ref HEAD` || |
|
||||||
exit 0 ;# we do not interrupt rebasing detached HEAD |
|
||||||
fi |
|
||||||
|
|
||||||
case "$topic" in |
|
||||||
refs/heads/??/*) |
|
||||||
;; |
|
||||||
*) |
|
||||||
exit 0 ;# we do not interrupt others. |
|
||||||
;; |
|
||||||
esac |
|
||||||
|
|
||||||
# Now we are dealing with a topic branch being rebased |
|
||||||
# on top of master. Is it OK to rebase it? |
|
||||||
|
|
||||||
# Does the topic really exist? |
|
||||||
git show-ref -q "$topic" || { |
|
||||||
echo >&2 "No such branch $topic" |
|
||||||
exit 1 |
|
||||||
} |
|
||||||
|
|
||||||
# Is topic fully merged to master? |
|
||||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"` |
|
||||||
if test -z "$not_in_master" |
|
||||||
then |
|
||||||
echo >&2 "$topic is fully merged to master; better remove it." |
|
||||||
exit 1 ;# we could allow it, but there is no point. |
|
||||||
fi |
|
||||||
|
|
||||||
# Is topic ever merged to next? If so you should not be rebasing it. |
|
||||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` |
|
||||||
only_next_2=`git rev-list ^master ${publish} | sort` |
|
||||||
if test "$only_next_1" = "$only_next_2" |
|
||||||
then |
|
||||||
not_in_topic=`git rev-list "^$topic" master` |
|
||||||
if test -z "$not_in_topic" |
|
||||||
then |
|
||||||
echo >&2 "$topic is already up to date with master" |
|
||||||
exit 1 ;# we could allow it, but there is no point. |
|
||||||
else |
|
||||||
exit 0 |
|
||||||
fi |
|
||||||
else |
|
||||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` |
|
||||||
/usr/bin/perl -e ' |
|
||||||
my $topic = $ARGV[0]; |
|
||||||
my $msg = "* $topic has commits already merged to public branch:\n"; |
|
||||||
my (%not_in_next) = map { |
|
||||||
/^([0-9a-f]+) /; |
|
||||||
($1 => 1); |
|
||||||
} split(/\n/, $ARGV[1]); |
|
||||||
for my $elem (map { |
|
||||||
/^([0-9a-f]+) (.*)$/; |
|
||||||
[$1 => $2]; |
|
||||||
} split(/\n/, $ARGV[2])) { |
|
||||||
if (!exists $not_in_next{$elem->[0]}) { |
|
||||||
if ($msg) { |
|
||||||
print STDERR $msg; |
|
||||||
undef $msg; |
|
||||||
} |
|
||||||
print STDERR " $elem->[1]\n"; |
|
||||||
} |
|
||||||
} |
|
||||||
' "$topic" "$not_in_next" "$not_in_master" |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
|
|
||||||
<<\DOC_END |
|
||||||
|
|
||||||
This sample hook safeguards topic branches that have been |
|
||||||
published from being rewound. |
|
||||||
|
|
||||||
The workflow assumed here is: |
|
||||||
|
|
||||||
* Once a topic branch forks from "master", "master" is never |
|
||||||
merged into it again (either directly or indirectly). |
|
||||||
|
|
||||||
* Once a topic branch is fully cooked and merged into "master", |
|
||||||
it is deleted. If you need to build on top of it to correct |
|
||||||
earlier mistakes, a new topic branch is created by forking at |
|
||||||
the tip of the "master". This is not strictly necessary, but |
|
||||||
it makes it easier to keep your history simple. |
|
||||||
|
|
||||||
* Whenever you need to test or publish your changes to topic |
|
||||||
branches, merge them into "next" branch. |
|
||||||
|
|
||||||
The script, being an example, hardcodes the publish branch name |
|
||||||
to be "next", but it is trivial to make it configurable via |
|
||||||
$GIT_DIR/config mechanism. |
|
||||||
|
|
||||||
With this workflow, you would want to know: |
|
||||||
|
|
||||||
(1) ... if a topic branch has ever been merged to "next". Young |
|
||||||
topic branches can have stupid mistakes you would rather |
|
||||||
clean up before publishing, and things that have not been |
|
||||||
merged into other branches can be easily rebased without |
|
||||||
affecting other people. But once it is published, you would |
|
||||||
not want to rewind it. |
|
||||||
|
|
||||||
(2) ... if a topic branch has been fully merged to "master". |
|
||||||
Then you can delete it. More importantly, you should not |
|
||||||
build on top of it -- other people may already want to |
|
||||||
change things related to the topic as patches against your |
|
||||||
"master", so if you need further changes, it is better to |
|
||||||
fork the topic (perhaps with the same name) afresh from the |
|
||||||
tip of "master". |
|
||||||
|
|
||||||
Let's look at this example: |
|
||||||
|
|
||||||
o---o---o---o---o---o---o---o---o---o "next" |
|
||||||
/ / / / |
|
||||||
/ a---a---b A / / |
|
||||||
/ / / / |
|
||||||
/ / c---c---c---c B / |
|
||||||
/ / / \ / |
|
||||||
/ / / b---b C \ / |
|
||||||
/ / / / \ / |
|
||||||
---o---o---o---o---o---o---o---o---o---o---o "master" |
|
||||||
|
|
||||||
|
|
||||||
A, B and C are topic branches. |
|
||||||
|
|
||||||
* A has one fix since it was merged up to "next". |
|
||||||
|
|
||||||
* B has finished. It has been fully merged up to "master" and "next", |
|
||||||
and is ready to be deleted. |
|
||||||
|
|
||||||
* C has not merged to "next" at all. |
|
||||||
|
|
||||||
We would want to allow C to be rebased, refuse A, and encourage |
|
||||||
B to be deleted. |
|
||||||
|
|
||||||
To compute (1): |
|
||||||
|
|
||||||
git rev-list ^master ^topic next |
|
||||||
git rev-list ^master next |
|
||||||
|
|
||||||
if these match, topic has not merged in next at all. |
|
||||||
|
|
||||||
To compute (2): |
|
||||||
|
|
||||||
git rev-list master..topic |
|
||||||
|
|
||||||
if this is empty, it is fully merged to "master". |
|
||||||
|
|
||||||
DOC_END |
|
@ -1,24 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to make use of push options. |
|
||||||
# The example simply echoes all push options that start with 'echoback=' |
|
||||||
# and rejects all pushes when the "reject" push option is used. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "pre-receive". |
|
||||||
|
|
||||||
if test -n "$GIT_PUSH_OPTION_COUNT" |
|
||||||
then |
|
||||||
i=0 |
|
||||||
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" |
|
||||||
do |
|
||||||
eval "value=\$GIT_PUSH_OPTION_$i" |
|
||||||
case "$value" in |
|
||||||
echoback=*) |
|
||||||
echo "echo from the pre-receive-hook: ${value#*=}" >&2 |
|
||||||
;; |
|
||||||
reject) |
|
||||||
exit 1 |
|
||||||
esac |
|
||||||
i=$((i + 1)) |
|
||||||
done |
|
||||||
fi |
|
@ -1,42 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to prepare the commit log message. |
|
||||||
# Called by "git commit" with the name of the file that has the |
|
||||||
# commit message, followed by the description of the commit |
|
||||||
# message's source. The hook's purpose is to edit the commit |
|
||||||
# message file. If the hook fails with a non-zero status, |
|
||||||
# the commit is aborted. |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "prepare-commit-msg". |
|
||||||
|
|
||||||
# This hook includes three examples. The first one removes the |
|
||||||
# "# Please enter the commit message..." help message. |
|
||||||
# |
|
||||||
# The second includes the output of "git diff --name-status -r" |
|
||||||
# into the message, just before the "git status" output. It is |
|
||||||
# commented because it doesn't cope with --amend or with squashed |
|
||||||
# commits. |
|
||||||
# |
|
||||||
# The third example adds a Signed-off-by line to the message, that can |
|
||||||
# still be edited. This is rarely a good idea. |
|
||||||
|
|
||||||
COMMIT_MSG_FILE=$1 |
|
||||||
COMMIT_SOURCE=$2 |
|
||||||
SHA1=$3 |
|
||||||
|
|
||||||
/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" |
|
||||||
|
|
||||||
# case "$COMMIT_SOURCE,$SHA1" in |
|
||||||
# ,|template,) |
|
||||||
# /usr/bin/perl -i.bak -pe ' |
|
||||||
# print "\n" . `git diff --cached --name-status -r` |
|
||||||
# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; |
|
||||||
# *) ;; |
|
||||||
# esac |
|
||||||
|
|
||||||
# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') |
|
||||||
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" |
|
||||||
# if test -z "$COMMIT_SOURCE" |
|
||||||
# then |
|
||||||
# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" |
|
||||||
# fi |
|
@ -1,78 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
|
|
||||||
# An example hook script to update a checked-out tree on a git push. |
|
||||||
# |
|
||||||
# This hook is invoked by git-receive-pack(1) when it reacts to git |
|
||||||
# push and updates reference(s) in its repository, and when the push |
|
||||||
# tries to update the branch that is currently checked out and the |
|
||||||
# receive.denyCurrentBranch configuration variable is set to |
|
||||||
# updateInstead. |
|
||||||
# |
|
||||||
# By default, such a push is refused if the working tree and the index |
|
||||||
# of the remote repository has any difference from the currently |
|
||||||
# checked out commit; when both the working tree and the index match |
|
||||||
# the current commit, they are updated to match the newly pushed tip |
|
||||||
# of the branch. This hook is to be used to override the default |
|
||||||
# behaviour; however the code below reimplements the default behaviour |
|
||||||
# as a starting point for convenient modification. |
|
||||||
# |
|
||||||
# The hook receives the commit with which the tip of the current |
|
||||||
# branch is going to be updated: |
|
||||||
commit=$1 |
|
||||||
|
|
||||||
# It can exit with a non-zero status to refuse the push (when it does |
|
||||||
# so, it must not modify the index or the working tree). |
|
||||||
die () { |
|
||||||
echo >&2 "$*" |
|
||||||
exit 1 |
|
||||||
} |
|
||||||
|
|
||||||
# Or it can make any necessary changes to the working tree and to the |
|
||||||
# index to bring them to the desired state when the tip of the current |
|
||||||
# branch is updated to the new commit, and exit with a zero status. |
|
||||||
# |
|
||||||
# For example, the hook can simply run git read-tree -u -m HEAD "$1" |
|
||||||
# in order to emulate git fetch that is run in the reverse direction |
|
||||||
# with git push, as the two-tree form of git read-tree -u -m is |
|
||||||
# essentially the same as git switch or git checkout that switches |
|
||||||
# branches while keeping the local changes in the working tree that do |
|
||||||
# not interfere with the difference between the branches. |
|
||||||
|
|
||||||
# The below is a more-or-less exact translation to shell of the C code |
|
||||||
# for the default behaviour for git's push-to-checkout hook defined in |
|
||||||
# the push_to_deploy() function in builtin/receive-pack.c. |
|
||||||
# |
|
||||||
# Note that the hook will be executed from the repository directory, |
|
||||||
# not from the working tree, so if you want to perform operations on |
|
||||||
# the working tree, you will have to adapt your code accordingly, e.g. |
|
||||||
# by adding "cd .." or using relative paths. |
|
||||||
|
|
||||||
if ! git update-index -q --ignore-submodules --refresh |
|
||||||
then |
|
||||||
die "Up-to-date check failed" |
|
||||||
fi |
|
||||||
|
|
||||||
if ! git diff-files --quiet --ignore-submodules -- |
|
||||||
then |
|
||||||
die "Working directory has unstaged changes" |
|
||||||
fi |
|
||||||
|
|
||||||
# This is a rough translation of: |
|
||||||
# |
|
||||||
# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX |
|
||||||
if git cat-file -e HEAD 2>/dev/null |
|
||||||
then |
|
||||||
head=HEAD |
|
||||||
else |
|
||||||
head=$(git hash-object -t tree --stdin </dev/null) |
|
||||||
fi |
|
||||||
|
|
||||||
if ! git diff-index --quiet --cached --ignore-submodules $head -- |
|
||||||
then |
|
||||||
die "Working directory has staged changes" |
|
||||||
fi |
|
||||||
|
|
||||||
if ! git read-tree -u -m "$commit" |
|
||||||
then |
|
||||||
die "Could not update working tree to new HEAD" |
|
||||||
fi |
|
@ -1,128 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# |
|
||||||
# An example hook script to block unannotated tags from entering. |
|
||||||
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new |
|
||||||
# |
|
||||||
# To enable this hook, rename this file to "update". |
|
||||||
# |
|
||||||
# Config |
|
||||||
# ------ |
|
||||||
# hooks.allowunannotated |
|
||||||
# This boolean sets whether unannotated tags will be allowed into the |
|
||||||
# repository. By default they won't be. |
|
||||||
# hooks.allowdeletetag |
|
||||||
# This boolean sets whether deleting tags will be allowed in the |
|
||||||
# repository. By default they won't be. |
|
||||||
# hooks.allowmodifytag |
|
||||||
# This boolean sets whether a tag may be modified after creation. By default |
|
||||||
# it won't be. |
|
||||||
# hooks.allowdeletebranch |
|
||||||
# This boolean sets whether deleting branches will be allowed in the |
|
||||||
# repository. By default they won't be. |
|
||||||
# hooks.denycreatebranch |
|
||||||
# This boolean sets whether remotely creating branches will be denied |
|
||||||
# in the repository. By default this is allowed. |
|
||||||
# |
|
||||||
|
|
||||||
# --- Command line |
|
||||||
refname="$1" |
|
||||||
oldrev="$2" |
|
||||||
newrev="$3" |
|
||||||
|
|
||||||
# --- Safety check |
|
||||||
if [ -z "$GIT_DIR" ]; then |
|
||||||
echo "Don't run this script from the command line." >&2 |
|
||||||
echo " (if you want, you could supply GIT_DIR then run" >&2 |
|
||||||
echo " $0 <ref> <oldrev> <newrev>)" >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
|
|
||||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then |
|
||||||
echo "usage: $0 <ref> <oldrev> <newrev>" >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
|
|
||||||
# --- Config |
|
||||||
allowunannotated=$(git config --type=bool hooks.allowunannotated) |
|
||||||
allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) |
|
||||||
denycreatebranch=$(git config --type=bool hooks.denycreatebranch) |
|
||||||
allowdeletetag=$(git config --type=bool hooks.allowdeletetag) |
|
||||||
allowmodifytag=$(git config --type=bool hooks.allowmodifytag) |
|
||||||
|
|
||||||
# check for no description |
|
||||||
projectdesc=$(sed -e '1q' "$GIT_DIR/description") |
|
||||||
case "$projectdesc" in |
|
||||||
"Unnamed repository"* | "") |
|
||||||
echo "*** Project description file hasn't been set" >&2 |
|
||||||
exit 1 |
|
||||||
;; |
|
||||||
esac |
|
||||||
|
|
||||||
# --- Check types |
|
||||||
# if $newrev is 0000...0000, it's a commit to delete a ref. |
|
||||||
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0') |
|
||||||
if [ "$newrev" = "$zero" ]; then |
|
||||||
newrev_type=delete |
|
||||||
else |
|
||||||
newrev_type=$(git cat-file -t $newrev) |
|
||||||
fi |
|
||||||
|
|
||||||
case "$refname","$newrev_type" in |
|
||||||
refs/tags/*,commit) |
|
||||||
# un-annotated tag |
|
||||||
short_refname=${refname##refs/tags/} |
|
||||||
if [ "$allowunannotated" != "true" ]; then |
|
||||||
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 |
|
||||||
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
;; |
|
||||||
refs/tags/*,delete) |
|
||||||
# delete tag |
|
||||||
if [ "$allowdeletetag" != "true" ]; then |
|
||||||
echo "*** Deleting a tag is not allowed in this repository" >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
;; |
|
||||||
refs/tags/*,tag) |
|
||||||
# annotated tag |
|
||||||
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 |
|
||||||
then |
|
||||||
echo "*** Tag '$refname' already exists." >&2 |
|
||||||
echo "*** Modifying a tag is not allowed in this repository." >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
;; |
|
||||||
refs/heads/*,commit) |
|
||||||
# branch |
|
||||||
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then |
|
||||||
echo "*** Creating a branch is not allowed in this repository" >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
;; |
|
||||||
refs/heads/*,delete) |
|
||||||
# delete branch |
|
||||||
if [ "$allowdeletebranch" != "true" ]; then |
|
||||||
echo "*** Deleting a branch is not allowed in this repository" >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
;; |
|
||||||
refs/remotes/*,commit) |
|
||||||
# tracking branch |
|
||||||
;; |
|
||||||
refs/remotes/*,delete) |
|
||||||
# delete tracking branch |
|
||||||
if [ "$allowdeletebranch" != "true" ]; then |
|
||||||
echo "*** Deleting a tracking branch is not allowed in this repository" >&2 |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
;; |
|
||||||
*) |
|
||||||
# Anything else (is there anything else?) |
|
||||||
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 |
|
||||||
exit 1 |
|
||||||
;; |
|
||||||
esac |
|
||||||
|
|
||||||
# --- Finished |
|
||||||
exit 0 |
|
@ -1,6 +0,0 @@ |
|||||||
# git ls-files --others --exclude-from=.git/info/exclude |
|
||||||
# Lines that start with '#' are comments. |
|
||||||
# For a project mostly in C, the following would be a good set of |
|
||||||
# exclude patterns (uncomment them if you want to use them): |
|
||||||
# *.[oa] |
|
||||||
# *~ |
|
Binary file not shown.
Binary file not shown.
@ -1,14 +0,0 @@ |
|||||||
# pack-refs with: peeled fully-peeled sorted |
|
||||||
226e048f615bdf068e65010d47f8cb143fd08865 refs/heads/master |
|
||||||
226e048f615bdf068e65010d47f8cb143fd08865 refs/heads/swagger-2 |
|
||||||
2fae74f3302c8a6a0563f88bbc37a0e2da7a654e refs/heads/work |
|
||||||
f5ca95436ba9db78f47e37c04dfca921285f911e refs/tags/v0.4.0 |
|
||||||
^fe5f8854a0d7318d04a103a16572b7e5b33d406d |
|
||||||
b81262e2cc9f051650c6f0fc9889a8f8e9a1ab21 refs/tags/v0.4.0.1 |
|
||||||
^87a0398bd8f903cdaf63d900d993fdb772c51291 |
|
||||||
f9152938e4b85f4011420903bd986d516a8c5771 refs/tags/v0.5.0 |
|
||||||
^b4f554c281601e483bf2cca28a232959fd2331c0 |
|
||||||
8e7a96bced01378f5d5d47ebe7a5f5403a324d52 refs/tags/v0.5.1 |
|
||||||
^8170a1052e29f24e2d811632f656c8e97dea69ae |
|
||||||
a730ffa306d1709ba9b551c1056622e54e50d7e7 refs/tags/v1.0.0 |
|
||||||
^45678cd123e829fdff6574067cd3e5852942b084 |
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,22 +0,0 @@ |
|||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/bcrypt-3.1.17/ext/mri |
|
||||||
/usr/bin/ruby -I /usr/lib/ruby/3.0.0 -r ./siteconf20220424-672384-r0s1w5.rb extconf.rb |
|
||||||
creating Makefile |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/bcrypt-3.1.17/ext/mri |
|
||||||
make DESTDIR\= clean |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/bcrypt-3.1.17/ext/mri |
|
||||||
make DESTDIR\= |
|
||||||
compiling bcrypt_ext.c |
|
||||||
compiling crypt_blowfish.c |
|
||||||
gcc -D__SKIP_GNU -c -o x86.o x86.S |
|
||||||
compiling crypt_gensalt.c |
|
||||||
compiling wrapper.c |
|
||||||
wrapper.c:182:60: warning: ‘struct crypt_data’ declared inside parameter list will not be visible outside of this definition or declaration |
|
||||||
182 | char *crypt_r(const char *key, const char *setting, struct crypt_data *data) |
|
||||||
| ^~~~~~~~~~ |
|
||||||
linking shared-object bcrypt_ext.so |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/bcrypt-3.1.17/ext/mri |
|
||||||
make DESTDIR\= install |
|
||||||
/usr/bin/install -c -m 0755 bcrypt_ext.so ./.gem.20220424-672384-aslyfc |
|
Binary file not shown.
@ -1,43 +0,0 @@ |
|||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/ffi-1.15.5/ext/ffi_c |
|
||||||
/usr/bin/ruby -I /usr/lib/ruby/3.0.0 -r ./siteconf20220424-672384-j636kg.rb extconf.rb |
|
||||||
checking for ffi_prep_closure_loc() in -lffi... yes |
|
||||||
checking for ffi_prep_cif_var()... yes |
|
||||||
checking for ffi_raw_call()... yes |
|
||||||
checking for ffi_prep_raw_closure()... yes |
|
||||||
checking for whether -pthread is accepted as LDFLAGS... yes |
|
||||||
creating extconf.h |
|
||||||
creating Makefile |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/ffi-1.15.5/ext/ffi_c |
|
||||||
make DESTDIR\= clean |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/ffi-1.15.5/ext/ffi_c |
|
||||||
make DESTDIR\= |
|
||||||
compiling AbstractMemory.c |
|
||||||
compiling ArrayType.c |
|
||||||
compiling Buffer.c |
|
||||||
compiling Call.c |
|
||||||
compiling ClosurePool.c |
|
||||||
compiling DynamicLibrary.c |
|
||||||
compiling Function.c |
|
||||||
compiling FunctionInfo.c |
|
||||||
compiling LastError.c |
|
||||||
compiling LongDouble.c |
|
||||||
compiling MappedType.c |
|
||||||
compiling MemoryPointer.c |
|
||||||
compiling MethodHandle.c |
|
||||||
compiling Platform.c |
|
||||||
compiling Pointer.c |
|
||||||
compiling Struct.c |
|
||||||
compiling StructByValue.c |
|
||||||
compiling StructLayout.c |
|
||||||
compiling Thread.c |
|
||||||
compiling Type.c |
|
||||||
compiling Types.c |
|
||||||
compiling Variadic.c |
|
||||||
compiling ffi.c |
|
||||||
linking shared-object ffi_c.so |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/ffi-1.15.5/ext/ffi_c |
|
||||||
make DESTDIR\= install |
|
||||||
/usr/bin/install -c -m 0755 ffi_c.so ./.gem.20220424-672384-3l4xqm |
|
@ -1,232 +0,0 @@ |
|||||||
"pkg-config --exists libffi" |
|
||||||
| pkg-config --libs libffi |
|
||||||
=> "-lffi \n" |
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main(int argc, char **argv) |
|
||||||
4: { |
|
||||||
5: return !!argv[argc]; |
|
||||||
6: } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lffi -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main(int argc, char **argv) |
|
||||||
4: { |
|
||||||
5: return !!argv[argc]; |
|
||||||
6: } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
| pkg-config --cflags-only-I libffi |
|
||||||
=> "\n" |
|
||||||
| pkg-config --cflags-only-other libffi |
|
||||||
=> "\n" |
|
||||||
| pkg-config --libs-only-l libffi |
|
||||||
=> "-lffi \n" |
|
||||||
package configuration for libffi |
|
||||||
incflags: |
|
||||||
cflags: |
|
||||||
ldflags: |
|
||||||
libs: -lffi |
|
||||||
|
|
||||||
have_library: checking for ffi_prep_closure_loc() in -lffi... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lruby -lffi -lffi -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <ffi.h> |
|
||||||
4: |
|
||||||
5: /*top*/ |
|
||||||
6: extern int t(void); |
|
||||||
7: int main(int argc, char **argv) |
|
||||||
8: { |
|
||||||
9: if (argc > 1000000) { |
|
||||||
10: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
11: printf("%d", (*tp)()); |
|
||||||
12: } |
|
||||||
13: |
|
||||||
14: return !!argv[argc]; |
|
||||||
15: } |
|
||||||
16: int t(void) { void ((*volatile p)()); p = (void ((*)()))ffi_prep_closure_loc; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for ffi_prep_cif_var()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lffi -lruby -lffi -lffi -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘ffi_prep_cif_var’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))ffi_prep_cif_var; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))ffi_prep_cif_var; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lffi -lruby -lffi -lffi -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void ffi_prep_cif_var(); |
|
||||||
15: int t(void) { ffi_prep_cif_var(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for ffi_raw_call()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lffi -lruby -lffi -lffi -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘ffi_raw_call’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))ffi_raw_call; return !p; } |
|
||||||
| ^~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))ffi_raw_call; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lffi -lruby -lffi -lffi -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void ffi_raw_call(); |
|
||||||
15: int t(void) { ffi_raw_call(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for ffi_prep_raw_closure()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lffi -lruby -lffi -lffi -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘ffi_prep_raw_closure’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))ffi_prep_raw_closure; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))ffi_prep_raw_closure; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lffi -lruby -lffi -lffi -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void ffi_prep_raw_closure(); |
|
||||||
15: int t(void) { ffi_prep_raw_closure(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
block in append_ldflags: checking for whether -pthread is accepted as LDFLAGS... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lffi -lffi -lruby -pthread -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main(int argc, char **argv) |
|
||||||
4: { |
|
||||||
5: return !!argv[argc]; |
|
||||||
6: } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
extconf.h is: |
|
||||||
/* begin */ |
|
||||||
1: #ifndef EXTCONF_H |
|
||||||
2: #define EXTCONF_H |
|
||||||
3: #define HAVE_FFI_PREP_CIF_VAR 1 |
|
||||||
4: #define HAVE_FFI_RAW_CALL 1 |
|
||||||
5: #define HAVE_FFI_PREP_RAW_CLOSURE 1 |
|
||||||
6: #define HAVE_RAW_API 1 |
|
||||||
7: #endif |
|
||||||
/* end */ |
|
||||||
|
|
@ -1,21 +0,0 @@ |
|||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/psych-4.0.3/ext/psych |
|
||||||
/usr/bin/ruby -I /usr/lib/ruby/3.0.0 -r ./siteconf20220424-672384-38ekq0.rb extconf.rb |
|
||||||
checking for yaml.h... yes |
|
||||||
checking for yaml_get_version() in -lyaml... yes |
|
||||||
creating Makefile |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/psych-4.0.3/ext/psych |
|
||||||
make DESTDIR\= clean |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/psych-4.0.3/ext/psych |
|
||||||
make DESTDIR\= |
|
||||||
compiling psych.c |
|
||||||
compiling psych_emitter.c |
|
||||||
compiling psych_parser.c |
|
||||||
compiling psych_to_ruby.c |
|
||||||
compiling psych_yaml_tree.c |
|
||||||
linking shared-object psych.so |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/psych-4.0.3/ext/psych |
|
||||||
make DESTDIR\= install |
|
||||||
/usr/bin/install -c -m 0755 psych.so ./.gem.20220424-672384-uh7xmc |
|
@ -1,71 +0,0 @@ |
|||||||
find_header: checking for yaml.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main(int argc, char **argv) |
|
||||||
4: { |
|
||||||
5: return !!argv[argc]; |
|
||||||
6: } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -E -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -o conftest.i" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <yaml.h> |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
find_library: checking for yaml_get_version() in -lyaml... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lyaml -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘yaml_get_version’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))yaml_get_version; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))yaml_get_version; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lyaml -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void yaml_get_version(); |
|
||||||
15: int t(void) { yaml_get_version(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
Binary file not shown.
Binary file not shown.
@ -1,60 +0,0 @@ |
|||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/rmagick-4.2.5/ext/RMagick |
|
||||||
/usr/bin/ruby -I /usr/lib/ruby/3.0.0 -r ./siteconf20220424-672384-vq7axx.rb extconf.rb |
|
||||||
checking for brew... no |
|
||||||
checking for pacman... yes |
|
||||||
checking for Ruby version >= 2.3.0... yes |
|
||||||
checking for pkg-config... yes |
|
||||||
checking for outdated ImageMagick version (<= 6.7.7)... no |
|
||||||
checking for gcc... yes |
|
||||||
|
|
||||||
Warning: Found a partial ImageMagick installation. Your operating |
|
||||||
system likely has some built-in ImageMagick libraries but not all of |
|
||||||
ImageMagick. This will most likely cause problems at both compile and |
|
||||||
runtime. |
|
||||||
Found partial installation at: /usr |
|
||||||
|
|
||||||
checking for __GNUC__... yes |
|
||||||
checking for MagickCore/MagickCore.h... yes |
|
||||||
checking for rb_gc_adjust_memory_usage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... yes |
|
||||||
checking for posix_memalign() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... yes |
|
||||||
checking for malloc_usable_size() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... yes |
|
||||||
checking for malloc_size() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... no |
|
||||||
checking for _aligned_msize() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... no |
|
||||||
checking for GetImageChannelEntropy() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... no |
|
||||||
checking for SetImageGray() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... yes |
|
||||||
checking for SetMagickAlignedMemoryMethods() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... yes |
|
||||||
checking for malloc.h... yes |
|
||||||
creating extconf.h |
|
||||||
creating Makefile |
|
||||||
====================================================================== |
|
||||||
Sun 24 Apr 22 22:39:04 |
|
||||||
This installation of RMagick 4.2.5 is configured for |
|
||||||
Ruby 3.0.4 (x86_64-linux) and ImageMagick 7.1.0 |
|
||||||
====================================================================== |
|
||||||
|
|
||||||
|
|
||||||
Configured compile options: {:magick_version=>"7.1.0", :local_libs=>" -lMagickCore-7.Q16HDRI ", :cppflags=>" -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99", :ldflags=>" -lMagickCore-7.Q16HDRI -Wl,-rpath,", :defs=>[], :config_h=>"Makefile"} |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/rmagick-4.2.5/ext/RMagick |
|
||||||
make DESTDIR\= clean |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/rmagick-4.2.5/ext/RMagick |
|
||||||
make DESTDIR\= |
|
||||||
compiling rmagick.c |
|
||||||
compiling rmdraw.c |
|
||||||
compiling rmenum.c |
|
||||||
compiling rmfill.c |
|
||||||
compiling rmilist.c |
|
||||||
compiling rmimage.c |
|
||||||
compiling rminfo.c |
|
||||||
compiling rmkinfo.c |
|
||||||
compiling rmmain.c |
|
||||||
compiling rmmontage.c |
|
||||||
compiling rmpixel.c |
|
||||||
compiling rmstruct.c |
|
||||||
compiling rmutil.c |
|
||||||
linking shared-object RMagick2.so |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/rmagick-4.2.5/ext/RMagick |
|
||||||
make DESTDIR\= install |
|
||||||
/usr/bin/install -c -m 0755 RMagick2.so ./.gem.20220424-672384-htztp3 |
|
@ -1,523 +0,0 @@ |
|||||||
find_executable: checking for brew... -------------------- no |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
find_executable: checking for pacman... -------------------- yes |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
assert_minimum_ruby_version!: checking for Ruby version >= 2.3.0... -------------------- yes |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
find_executable: checking for pkg-config... -------------------- yes |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
assert_has_dev_libs!: checking for outdated ImageMagick version (<= 6.7.7)... -------------------- no |
|
||||||
|
|
||||||
Detected ImageMagick version: 7.1.0 |
|
||||||
-------------------- |
|
||||||
|
|
||||||
find_executable: checking for gcc... -------------------- yes |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
|
|
||||||
Warning: Found a partial ImageMagick installation. Your operating |
|
||||||
system likely has some built-in ImageMagick libraries but not all of |
|
||||||
ImageMagick. This will most likely cause problems at both compile and |
|
||||||
runtime. |
|
||||||
Found partial installation at: /usr |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main(int argc, char **argv) |
|
||||||
4: { |
|
||||||
5: return !!argv[argc]; |
|
||||||
6: } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main() { } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
have_macro: checking for __GNUC__... -------------------- yes |
|
||||||
|
|
||||||
"gcc -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC -c conftest.c" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: #ifndef __GNUC__ |
|
||||||
5: # error |
|
||||||
6: |:/ === __GNUC__ undefined === /:| |
|
||||||
7: #endif |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_header: checking for MagickCore/MagickCore.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -E -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -o conftest.i" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <MagickCore/MagickCore.h> |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for rb_gc_adjust_memory_usage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_gc_adjust_memory_usage; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for posix_memalign() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))posix_memalign; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for malloc_usable_size() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:23:57: error: ‘malloc_usable_size’ undeclared (first use in this function) |
|
||||||
23 | int t(void) { void ((*volatile p)()); p = (void ((*)()))malloc_usable_size; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:23:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))malloc_usable_size; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: extern void malloc_usable_size(); |
|
||||||
24: int t(void) { malloc_usable_size(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for malloc_size() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- no |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:23:57: error: ‘malloc_size’ undeclared (first use in this function) |
|
||||||
23 | int t(void) { void ((*volatile p)()); p = (void ((*)()))malloc_size; return !p; } |
|
||||||
| ^~~~~~~~~~~ |
|
||||||
conftest.c:23:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))malloc_size; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
/usr/bin/ld: /tmp/ccUiujjd.o: in function `t': |
|
||||||
conftest.c:(.text+0xc): undefined reference to `malloc_size' |
|
||||||
collect2: error: ld returned 1 exit status |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: extern void malloc_size(); |
|
||||||
24: int t(void) { malloc_size(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for _aligned_msize() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- no |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:23:57: error: ‘_aligned_msize’ undeclared (first use in this function) |
|
||||||
23 | int t(void) { void ((*volatile p)()); p = (void ((*)()))_aligned_msize; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~ |
|
||||||
conftest.c:23:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))_aligned_msize; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
/usr/bin/ld: /tmp/ccladuxD.o: in function `t': |
|
||||||
conftest.c:(.text+0xc): undefined reference to `_aligned_msize' |
|
||||||
collect2: error: ld returned 1 exit status |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: extern void _aligned_msize(); |
|
||||||
24: int t(void) { _aligned_msize(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for GetImageChannelEntropy() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- no |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:23:57: error: ‘GetImageChannelEntropy’ undeclared (first use in this function); did you mean ‘GetImageEntropy’? |
|
||||||
23 | int t(void) { void ((*volatile p)()); p = (void ((*)()))GetImageChannelEntropy; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
| GetImageEntropy |
|
||||||
conftest.c:23:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))GetImageChannelEntropy; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
/usr/bin/ld: /tmp/ccIp9PZ3.o: in function `t': |
|
||||||
conftest.c:(.text+0xc): undefined reference to `GetImageChannelEntropy' |
|
||||||
collect2: error: ld returned 1 exit status |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: extern void GetImageChannelEntropy(); |
|
||||||
24: int t(void) { GetImageChannelEntropy(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for SetImageGray() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))SetImageGray; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for SetMagickAlignedMemoryMethods() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,sys/types.h,MagickCore/MagickCore.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -lMagickCore-7.Q16HDRI -Wl,-rpath, -lMagickCore-7.Q16HDRI -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <assert.h> |
|
||||||
4: #include <ctype.h> |
|
||||||
5: #include <stdio.h> |
|
||||||
6: #include <stdlib.h> |
|
||||||
7: #include <math.h> |
|
||||||
8: #include <time.h> |
|
||||||
9: #include <sys/types.h> |
|
||||||
10: #include <MagickCore/MagickCore.h> |
|
||||||
11: |
|
||||||
12: /*top*/ |
|
||||||
13: extern int t(void); |
|
||||||
14: int main(int argc, char **argv) |
|
||||||
15: { |
|
||||||
16: if (argc > 1000000) { |
|
||||||
17: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
18: printf("%d", (*tp)()); |
|
||||||
19: } |
|
||||||
20: |
|
||||||
21: return !!argv[argc]; |
|
||||||
22: } |
|
||||||
23: int t(void) { void ((*volatile p)()); p = (void ((*)()))SetMagickAlignedMemoryMethods; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_header: checking for malloc.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -E -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -o conftest.i" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <malloc.h> |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
extconf.h is: |
|
||||||
/* begin */ |
|
||||||
1: #ifndef EXTCONF_H |
|
||||||
2: #define EXTCONF_H |
|
||||||
3: #define HAVE_MAGICKCORE_MAGICKCORE_H 1 |
|
||||||
4: #define HAVE_RB_GC_ADJUST_MEMORY_USAGE 1 |
|
||||||
5: #define HAVE_POSIX_MEMALIGN 1 |
|
||||||
6: #define HAVE_MALLOC_USABLE_SIZE 1 |
|
||||||
7: #define HAVE_SETIMAGEGRAY 1 |
|
||||||
8: #define HAVE_SETMAGICKALIGNEDMEMORYMETHODS 1 |
|
||||||
9: #define HAVE_MALLOC_H 1 |
|
||||||
10: #define RUBY_VERSION_STRING ruby 3.0.4 |
|
||||||
11: #define RMAGICK_VERSION_STRING RMagick 4.2.5 |
|
||||||
12: #define IMAGEMAGICK_GREATER_THAN_EQUAL_6_8_9 1 |
|
||||||
13: #define IMAGEMAGICK_GREATER_THAN_EQUAL_6_9_0 1 |
|
||||||
14: #define IMAGEMAGICK_GREATER_THAN_EQUAL_6_9_10 1 |
|
||||||
15: #define IMAGEMAGICK_7 1 |
|
||||||
16: #define IMAGEMAGICK_GREATER_THAN_EQUAL_7_0_8 1 |
|
||||||
17: #define IMAGEMAGICK_GREATER_THAN_EQUAL_7_0_10 1 |
|
||||||
18: #endif |
|
||||||
/* end */ |
|
||||||
|
|
||||||
====================================================================== |
|
||||||
Sun 24 Apr 22 22:39:04 |
|
||||||
This installation of RMagick 4.2.5 is configured for |
|
||||||
Ruby 3.0.4 (x86_64-linux) and ImageMagick 7.1.0 |
|
||||||
====================================================================== |
|
||||||
|
|
||||||
|
|
||||||
Configured compile options: {:magick_version=>"7.1.0", :local_libs=>" -lMagickCore-7.Q16HDRI ", :cppflags=>" -I/usr/include/ImageMagick-7 -fopenmp -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -std=gnu99", :ldflags=>" -lMagickCore-7.Q16HDRI -Wl,-rpath,", :defs=>[], :config_h=>"Makefile"} |
|
@ -1,80 +0,0 @@ |
|||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sassc-2.4.0/ext |
|
||||||
/usr/bin/ruby -I /usr/lib/ruby/3.0.0 -r ./siteconf20220424-673820-jbni8g.rb extconf.rb |
|
||||||
creating Makefile |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sassc-2.4.0/ext |
|
||||||
make DESTDIR\= clean |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sassc-2.4.0/ext |
|
||||||
make DESTDIR\= |
|
||||||
compiling ./libsass/src/ast.cpp |
|
||||||
compiling ./libsass/src/ast2c.cpp |
|
||||||
compiling ./libsass/src/ast_fwd_decl.cpp |
|
||||||
compiling ./libsass/src/ast_sel_cmp.cpp |
|
||||||
compiling ./libsass/src/ast_sel_super.cpp |
|
||||||
compiling ./libsass/src/ast_sel_unify.cpp |
|
||||||
compiling ./libsass/src/ast_sel_weave.cpp |
|
||||||
compiling ./libsass/src/ast_selectors.cpp |
|
||||||
compiling ./libsass/src/ast_supports.cpp |
|
||||||
compiling ./libsass/src/ast_values.cpp |
|
||||||
compiling ./libsass/src/backtrace.cpp |
|
||||||
compiling ./libsass/src/base64vlq.cpp |
|
||||||
compiling ./libsass/src/bind.cpp |
|
||||||
compiling ./libsass/src/c2ast.cpp |
|
||||||
compiling ./libsass/src/c99func.c |
|
||||||
compiling ./libsass/src/cencode.c |
|
||||||
compiling ./libsass/src/check_nesting.cpp |
|
||||||
compiling ./libsass/src/color_maps.cpp |
|
||||||
compiling ./libsass/src/constants.cpp |
|
||||||
compiling ./libsass/src/context.cpp |
|
||||||
compiling ./libsass/src/cssize.cpp |
|
||||||
compiling ./libsass/src/emitter.cpp |
|
||||||
compiling ./libsass/src/environment.cpp |
|
||||||
compiling ./libsass/src/error_handling.cpp |
|
||||||
compiling ./libsass/src/eval.cpp |
|
||||||
compiling ./libsass/src/eval_selectors.cpp |
|
||||||
compiling ./libsass/src/expand.cpp |
|
||||||
compiling ./libsass/src/extender.cpp |
|
||||||
compiling ./libsass/src/extension.cpp |
|
||||||
compiling ./libsass/src/file.cpp |
|
||||||
compiling ./libsass/src/fn_colors.cpp |
|
||||||
compiling ./libsass/src/fn_lists.cpp |
|
||||||
compiling ./libsass/src/fn_maps.cpp |
|
||||||
compiling ./libsass/src/fn_miscs.cpp |
|
||||||
compiling ./libsass/src/fn_numbers.cpp |
|
||||||
compiling ./libsass/src/fn_selectors.cpp |
|
||||||
compiling ./libsass/src/fn_strings.cpp |
|
||||||
compiling ./libsass/src/fn_utils.cpp |
|
||||||
compiling ./libsass/src/inspect.cpp |
|
||||||
compiling ./libsass/src/json.cpp |
|
||||||
compiling ./libsass/src/lexer.cpp |
|
||||||
compiling ./libsass/src/listize.cpp |
|
||||||
compiling ./libsass/src/memory/allocator.cpp |
|
||||||
compiling ./libsass/src/memory/shared_ptr.cpp |
|
||||||
compiling ./libsass/src/operators.cpp |
|
||||||
compiling ./libsass/src/output.cpp |
|
||||||
compiling ./libsass/src/parser.cpp |
|
||||||
compiling ./libsass/src/parser_selectors.cpp |
|
||||||
compiling ./libsass/src/plugins.cpp |
|
||||||
compiling ./libsass/src/position.cpp |
|
||||||
compiling ./libsass/src/prelexer.cpp |
|
||||||
compiling ./libsass/src/remove_placeholders.cpp |
|
||||||
compiling ./libsass/src/sass.cpp |
|
||||||
compiling ./libsass/src/sass2scss.cpp |
|
||||||
compiling ./libsass/src/sass_context.cpp |
|
||||||
compiling ./libsass/src/sass_functions.cpp |
|
||||||
compiling ./libsass/src/sass_values.cpp |
|
||||||
compiling ./libsass/src/source.cpp |
|
||||||
compiling ./libsass/src/source_map.cpp |
|
||||||
compiling ./libsass/src/stylesheet.cpp |
|
||||||
compiling ./libsass/src/to_value.cpp |
|
||||||
compiling ./libsass/src/units.cpp |
|
||||||
compiling ./libsass/src/utf8_string.cpp |
|
||||||
compiling ./libsass/src/util.cpp |
|
||||||
compiling ./libsass/src/util_string.cpp |
|
||||||
compiling ./libsass/src/values.cpp |
|
||||||
linking shared-object sassc/libsass.so |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sassc-2.4.0/ext |
|
||||||
make DESTDIR\= install |
|
||||||
/usr/bin/install -c -m 0755 libsass.so ./.gem.20220424-673820-x27wv9/sassc |
|
Binary file not shown.
@ -1,76 +0,0 @@ |
|||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sqlite3-1.4.2/ext/sqlite3 |
|
||||||
/usr/bin/ruby -I /usr/lib/ruby/3.0.0 -r ./siteconf20220424-672384-6f01zl.rb extconf.rb |
|
||||||
checking for sqlite3.h... yes |
|
||||||
checking for pthread_create() in -lpthread... yes |
|
||||||
checking for -ldl... yes |
|
||||||
checking for sqlite3_libversion_number() in -lsqlite3... yes |
|
||||||
checking for rb_proc_arity()... yes |
|
||||||
checking for rb_integer_pack()... yes |
|
||||||
checking for sqlite3_initialize()... yes |
|
||||||
checking for sqlite3_backup_init()... yes |
|
||||||
checking for sqlite3_column_database_name()... yes |
|
||||||
checking for sqlite3_enable_load_extension()... yes |
|
||||||
checking for sqlite3_load_extension()... yes |
|
||||||
checking for sqlite3_open_v2()... yes |
|
||||||
checking for sqlite3_prepare_v2()... yes |
|
||||||
checking for sqlite3_int64 in sqlite3.h... yes |
|
||||||
checking for sqlite3_uint64 in sqlite3.h... yes |
|
||||||
creating Makefile |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sqlite3-1.4.2/ext/sqlite3 |
|
||||||
make DESTDIR\= clean |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sqlite3-1.4.2/ext/sqlite3 |
|
||||||
make DESTDIR\= |
|
||||||
compiling aggregator.c |
|
||||||
compiling backup.c |
|
||||||
compiling database.c |
|
||||||
database.c: In function ‘exec_batch’: |
|
||||||
database.c:726:57: warning: passing argument 3 of ‘sqlite3_exec’ from incompatible pointer type [-Wincompatible-pointer-types] |
|
||||||
726 | status = sqlite3_exec(ctx->db, StringValuePtr(sql), hash_callback_function, callback_ary, &errMsg); |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
| | |
|
||||||
| int (*)(VALUE, int, char **, char **) {aka int (*)(long unsigned int, int, char **, char **)} |
|
||||||
In file included from ./sqlite3_ruby.h:25, |
|
||||||
from database.c:1: |
|
||||||
/usr/include/sqlite3.h:428:9: note: expected ‘int (*)(void *, int, char **, char **)’ but argument is of type ‘int (*)(VALUE, int, char **, char **)’ {aka ‘int (*)(long unsigned int, int, char **, char **)’} |
|
||||||
428 | int (*callback)(void*,int,char**,char**), /* Callback function */ |
|
||||||
| ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
database.c:726:81: warning: passing argument 4 of ‘sqlite3_exec’ makes pointer from integer without a cast [-Wint-conversion] |
|
||||||
726 | status = sqlite3_exec(ctx->db, StringValuePtr(sql), hash_callback_function, callback_ary, &errMsg); |
|
||||||
| ^~~~~~~~~~~~ |
|
||||||
| | |
|
||||||
| VALUE {aka long unsigned int} |
|
||||||
In file included from ./sqlite3_ruby.h:25, |
|
||||||
from database.c:1: |
|
||||||
/usr/include/sqlite3.h:429:3: note: expected ‘void *’ but argument is of type ‘VALUE’ {aka ‘long unsigned int’} |
|
||||||
429 | void *, /* 1st argument to callback */ |
|
||||||
| ^~~~~~ |
|
||||||
database.c:728:57: warning: passing argument 3 of ‘sqlite3_exec’ from incompatible pointer type [-Wincompatible-pointer-types] |
|
||||||
728 | status = sqlite3_exec(ctx->db, StringValuePtr(sql), regular_callback_function, callback_ary, &errMsg); |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
| | |
|
||||||
| int (*)(VALUE, int, char **, char **) {aka int (*)(long unsigned int, int, char **, char **)} |
|
||||||
In file included from ./sqlite3_ruby.h:25, |
|
||||||
from database.c:1: |
|
||||||
/usr/include/sqlite3.h:428:9: note: expected ‘int (*)(void *, int, char **, char **)’ but argument is of type ‘int (*)(VALUE, int, char **, char **)’ {aka ‘int (*)(long unsigned int, int, char **, char **)’} |
|
||||||
428 | int (*callback)(void*,int,char**,char**), /* Callback function */ |
|
||||||
| ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
database.c:728:84: warning: passing argument 4 of ‘sqlite3_exec’ makes pointer from integer without a cast [-Wint-conversion] |
|
||||||
728 | status = sqlite3_exec(ctx->db, StringValuePtr(sql), regular_callback_function, callback_ary, &errMsg); |
|
||||||
| ^~~~~~~~~~~~ |
|
||||||
| | |
|
||||||
| VALUE {aka long unsigned int} |
|
||||||
In file included from ./sqlite3_ruby.h:25, |
|
||||||
from database.c:1: |
|
||||||
/usr/include/sqlite3.h:429:3: note: expected ‘void *’ but argument is of type ‘VALUE’ {aka ‘long unsigned int’} |
|
||||||
429 | void *, /* 1st argument to callback */ |
|
||||||
| ^~~~~~ |
|
||||||
compiling exception.c |
|
||||||
compiling sqlite3.c |
|
||||||
compiling statement.c |
|
||||||
linking shared-object sqlite3/sqlite3_native.so |
|
||||||
|
|
||||||
current directory: /home/elal/Projects/websites/the_auctionhouse/vendor/bundle/ruby/3.0.0/gems/sqlite3-1.4.2/ext/sqlite3 |
|
||||||
make DESTDIR\= install |
|
||||||
/usr/bin/install -c -m 0755 sqlite3_native.so ./.gem.20220424-672384-xzlu6m/sqlite3 |
|
@ -1,584 +0,0 @@ |
|||||||
"pkg-config --exists sqlite3" |
|
||||||
| pkg-config --libs sqlite3 |
|
||||||
=> "-lsqlite3 \n" |
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main(int argc, char **argv) |
|
||||||
4: { |
|
||||||
5: return !!argv[argc]; |
|
||||||
6: } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: int main(int argc, char **argv) |
|
||||||
4: { |
|
||||||
5: return !!argv[argc]; |
|
||||||
6: } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
| pkg-config --cflags-only-I sqlite3 |
|
||||||
=> "\n" |
|
||||||
| pkg-config --cflags-only-other sqlite3 |
|
||||||
=> "\n" |
|
||||||
| pkg-config --libs-only-l sqlite3 |
|
||||||
=> "-lsqlite3 \n" |
|
||||||
package configuration for sqlite3 |
|
||||||
incflags: |
|
||||||
cflags: |
|
||||||
ldflags: |
|
||||||
libs: -lsqlite3 |
|
||||||
|
|
||||||
find_header: checking for sqlite3.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -E -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -o conftest.i" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <sqlite3.h> |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
find_library: checking for pthread_create() in -lpthread... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -lruby -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘pthread_create’ undeclared (first use in this function); did you mean ‘rb_thread_create’? |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))pthread_create; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~ |
|
||||||
| rb_thread_create |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))pthread_create; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -lruby -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void pthread_create(); |
|
||||||
15: int t(void) { pthread_create(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_library: checking for -ldl... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lpthread -lsqlite3 -lruby -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: |
|
||||||
15: int t(void) { ; return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
find_library: checking for sqlite3_libversion_number() in -lsqlite3... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_libversion_number’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_libversion_number; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_libversion_number; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_libversion_number(); |
|
||||||
15: int t(void) { sqlite3_libversion_number(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for rb_proc_arity()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_proc_arity; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for rb_integer_pack()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_integer_pack; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for sqlite3_initialize()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_initialize’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_initialize; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_initialize; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_initialize(); |
|
||||||
15: int t(void) { sqlite3_initialize(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for sqlite3_backup_init()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_backup_init’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_backup_init; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_backup_init; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_backup_init(); |
|
||||||
15: int t(void) { sqlite3_backup_init(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for sqlite3_column_database_name()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_column_database_name’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_column_database_name; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_column_database_name; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_column_database_name(); |
|
||||||
15: int t(void) { sqlite3_column_database_name(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for sqlite3_enable_load_extension()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_enable_load_extension’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_enable_load_extension; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_enable_load_extension; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_enable_load_extension(); |
|
||||||
15: int t(void) { sqlite3_enable_load_extension(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for sqlite3_load_extension()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_load_extension’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_load_extension; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_load_extension; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_load_extension(); |
|
||||||
15: int t(void) { sqlite3_load_extension(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for sqlite3_open_v2()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_open_v2’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_open_v2; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_open_v2; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_open_v2(); |
|
||||||
15: int t(void) { sqlite3_open_v2(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_func: checking for sqlite3_prepare_v2()... -------------------- yes |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
conftest.c: In function ‘t’: |
|
||||||
conftest.c:14:57: error: ‘sqlite3_prepare_v2’ undeclared (first use in this function) |
|
||||||
14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_prepare_v2; return !p; } |
|
||||||
| ^~~~~~~~~~~~~~~~~~ |
|
||||||
conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_prepare_v2; return !p; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
"gcc -o conftest -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lsqlite3 -ldl -lpthread -lsqlite3 -lruby -lsqlite3 -ldl -lpthread -lsqlite3 -lm -lc" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: /*top*/ |
|
||||||
4: extern int t(void); |
|
||||||
5: int main(int argc, char **argv) |
|
||||||
6: { |
|
||||||
7: if (argc > 1000000) { |
|
||||||
8: int (* volatile tp)(void)=(int (*)(void))&t; |
|
||||||
9: printf("%d", (*tp)()); |
|
||||||
10: } |
|
||||||
11: |
|
||||||
12: return !!argv[argc]; |
|
||||||
13: } |
|
||||||
14: extern void sqlite3_prepare_v2(); |
|
||||||
15: int t(void) { sqlite3_prepare_v2(); return 0; } |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_type: checking for sqlite3_int64 in sqlite3.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC -c conftest.c" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <sqlite3.h> |
|
||||||
4: |
|
||||||
5: /*top*/ |
|
||||||
6: typedef sqlite3_int64 conftest_type; |
|
||||||
7: int conftestval[sizeof(conftest_type)?1:-1]; |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
||||||
have_type: checking for sqlite3_uint64 in sqlite3.h... -------------------- yes |
|
||||||
|
|
||||||
"gcc -I/usr/include/ruby-3.0.0/x86_64-linux -I/usr/include/ruby-3.0.0/ruby/backward -I/usr/include/ruby-3.0.0 -I. -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fPIC -c conftest.c" |
|
||||||
checked program was: |
|
||||||
/* begin */ |
|
||||||
1: #include "ruby.h" |
|
||||||
2: |
|
||||||
3: #include <sqlite3.h> |
|
||||||
4: |
|
||||||
5: /*top*/ |
|
||||||
6: typedef sqlite3_uint64 conftest_type; |
|
||||||
7: int conftestval[sizeof(conftest_type)?1:-1]; |
|
||||||
/* end */ |
|
||||||
|
|
||||||
-------------------- |
|
||||||
|
|
Binary file not shown.
@ -1,419 +0,0 @@ |
|||||||
## Rails 7.0.2.3 (March 08, 2022) ## |
|
||||||
|
|
||||||
* No changes. |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.2.2 (February 11, 2022) ## |
|
||||||
|
|
||||||
* Fix Reloader method signature to work with the new Executor signature |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.2.1 (February 11, 2022) ## |
|
||||||
|
|
||||||
* No changes. |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.2 (February 08, 2022) ## |
|
||||||
|
|
||||||
* Fix `ActiveSupport::EncryptedConfiguration` to be compatible with Psych 4 |
|
||||||
|
|
||||||
*Stephen Sugden* |
|
||||||
|
|
||||||
* Improve `File.atomic_write` error handling. |
|
||||||
|
|
||||||
*Daniel Pepper* |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.1 (January 06, 2022) ## |
|
||||||
|
|
||||||
* Fix `Class#descendants` and `DescendantsTracker#descendants` compatibility with Ruby 3.1. |
|
||||||
|
|
||||||
[The native `Class#descendants` was reverted prior to Ruby 3.1 release](https://bugs.ruby-lang.org/issues/14394#note-33), |
|
||||||
but `Class#subclasses` was kept, breaking the feature detection. |
|
||||||
|
|
||||||
*Jean Boussier* |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.0 (December 15, 2021) ## |
|
||||||
|
|
||||||
* Fix `ActiveSupport::Duration.build` to support negative values. |
|
||||||
|
|
||||||
The algorithm to collect the `parts` of the `ActiveSupport::Duration` |
|
||||||
ignored the sign of the `value` and accumulated incorrect part values. This |
|
||||||
impacted `ActiveSupport::Duration#sum` (which is dependent on `parts`) but |
|
||||||
not `ActiveSupport::Duration#eql?` (which is dependent on `value`). |
|
||||||
|
|
||||||
*Caleb Buxton*, *Braden Staudacher* |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.0.rc3 (December 14, 2021) ## |
|
||||||
|
|
||||||
* No changes. |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.0.rc2 (December 14, 2021) ## |
|
||||||
|
|
||||||
* No changes. |
|
||||||
|
|
||||||
## Rails 7.0.0.rc1 (December 06, 2021) ## |
|
||||||
|
|
||||||
* Deprecate passing a format to `#to_s` in favor of `#to_formatted_s` in `Array`, `Range`, `Date`, `DateTime`, `Time`, |
|
||||||
`BigDecimal`, `Float` and, `Integer`. |
|
||||||
|
|
||||||
*Rafael Mendonça França* |
|
||||||
|
|
||||||
* Document `ActiveSupport::Testing::Deprecation`. |
|
||||||
|
|
||||||
*Sam Bostock & Sam Jordan* |
|
||||||
|
|
||||||
* Add `Pathname#existence`. |
|
||||||
|
|
||||||
```ruby |
|
||||||
Pathname.new("file").existence&.read |
|
||||||
``` |
|
||||||
|
|
||||||
*Timo Schilling* |
|
||||||
|
|
||||||
* Remove deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`. |
|
||||||
|
|
||||||
*Rafael Mendonça França* |
|
||||||
|
|
||||||
* Remove deprecated support to use `Range#include?` to check the inclusion of a value in |
|
||||||
a date time range is deprecated. |
|
||||||
|
|
||||||
*Rafael Mendonça França* |
|
||||||
|
|
||||||
* Remove deprecated `URI.parser`. |
|
||||||
|
|
||||||
*Rafael Mendonça França* |
|
||||||
|
|
||||||
* Remove deprecated `config.active_support.use_sha1_digests`. |
|
||||||
|
|
||||||
*Rafael Mendonça França* |
|
||||||
|
|
||||||
* Invoking `Object#with_options` without a `&block` argument returns the |
|
||||||
`ActiveSupport::OptionMerger` instance. |
|
||||||
|
|
||||||
*Sean Doyle* |
|
||||||
|
|
||||||
* `Rails.application.executor` hooks can now be called around every test |
|
||||||
|
|
||||||
This helps to better simulate request or job local state being reset around tests and prevents state |
|
||||||
leaking from one test to another. |
|
||||||
|
|
||||||
However it requires the executor hooks executed in the test environment to be re-entrant. |
|
||||||
|
|
||||||
To enable this, set `config.active_support.executor_around_test_case = true` (this is the default in Rails 7). |
|
||||||
|
|
||||||
*Jean Boussier* |
|
||||||
|
|
||||||
* `ActiveSupport::DescendantsTracker` now mostly delegate to `Class#descendants` on Ruby 3.1 |
|
||||||
|
|
||||||
Ruby now provides a fast `Class#descendants` making `ActiveSupport::DescendantsTracker` mostly useless. |
|
||||||
|
|
||||||
As a result the following methods are deprecated: |
|
||||||
|
|
||||||
- `ActiveSupport::DescendantsTracker.direct_descendants` |
|
||||||
- `ActiveSupport::DescendantsTracker#direct_descendants` |
|
||||||
|
|
||||||
*Jean Boussier* |
|
||||||
|
|
||||||
* Fix the `Digest::UUID.uuid_from_hash` behavior for namespace IDs that are different from the ones defined on `Digest::UUID`. |
|
||||||
|
|
||||||
The new behavior will be enabled by setting the |
|
||||||
`config.active_support.use_rfc4122_namespaced_uuids` option to `true` |
|
||||||
and is the default for new apps. |
|
||||||
|
|
||||||
The old behavior is the default for upgraded apps and will output a |
|
||||||
deprecation warning every time a value that is different than one of |
|
||||||
the constants defined on the `Digest::UUID` extension is used as the |
|
||||||
namespace ID. |
|
||||||
|
|
||||||
*Alex Robbin*, *Erich Soares Machado*, *Eugene Kenny* |
|
||||||
|
|
||||||
* `ActiveSupport::Inflector::Inflections#clear(:acronyms)` is now supported, |
|
||||||
and `inflector.clear` / `inflector.clear(:all)` also clears acronyms. |
|
||||||
|
|
||||||
*Alex Ghiculescu*, *Oliver Peate* |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.0.alpha2 (September 15, 2021) ## |
|
||||||
|
|
||||||
* No changes. |
|
||||||
|
|
||||||
|
|
||||||
## Rails 7.0.0.alpha1 (September 15, 2021) ## |
|
||||||
|
|
||||||
* `ActiveSupport::Dependencies` no longer installs a `const_missing` hook. Before this, you could push to the autoload paths and have constants autoloaded. This feature, known as the `classic` autoloader, has been removed. |
|
||||||
|
|
||||||
*Xavier Noria* |
|
||||||
|
|
||||||
* Private internal classes of `ActiveSupport::Dependencies` have been deleted, like `ActiveSupport::Dependencies::Reference`, `ActiveSupport::Dependencies::Blamable`, and others. |
|
||||||
|
|
||||||
*Xavier Noria* |
|
||||||
|
|
||||||
* The private API of `ActiveSupport::Dependencies` has been deleted. That includes methods like `hook!`, `unhook!`, `depend_on`, `require_or_load`, `mechanism`, and many others. |
|
||||||
|
|
||||||
*Xavier Noria* |
|
||||||
|
|
||||||
* Improves the performance of `ActiveSupport::NumberHelper` formatters by avoiding the use of exceptions as flow control. |
|
||||||
|
|
||||||
*Mike Dalessio* |
|
||||||
|
|
||||||
* Removed rescue block from `ActiveSupport::Cache::RedisCacheStore#handle_exception` |
|
||||||
|
|
||||||
Previously, if you provided a `error_handler` to `redis_cache_store`, any errors thrown by |
|
||||||
the error handler would be rescued and logged only. Removed the `rescue` clause from `handle_exception` |
|
||||||
to allow these to be thrown. |
|
||||||
|
|
||||||
*Nicholas A. Stuart* |
|
||||||
|
|
||||||
* Allow entirely opting out of deprecation warnings. |
|
||||||
|
|
||||||
Previously if you did `app.config.active_support.deprecation = :silence`, some work would |
|
||||||
still be done on each call to `ActiveSupport::Deprecation.warn`. In very hot paths, this could |
|
||||||
cause performance issues. |
|
||||||
|
|
||||||
Now, you can make `ActiveSupport::Deprecation.warn` a no-op: |
|
||||||
|
|
||||||
```ruby |
|
||||||
config.active_support.report_deprecations = false |
|
||||||
``` |
|
||||||
|
|
||||||
This is the default in production for new apps. It is the equivalent to: |
|
||||||
|
|
||||||
```ruby |
|
||||||
config.active_support.deprecation = :silence |
|
||||||
config.active_support.disallowed_deprecation = :silence |
|
||||||
``` |
|
||||||
|
|
||||||
but will take a more optimised code path. |
|
||||||
|
|
||||||
*Alex Ghiculescu* |
|
||||||
|
|
||||||
* Faster tests by parallelizing only when overhead is justified by the number |
|
||||||
of them. |
|
||||||
|
|
||||||
Running tests in parallel adds overhead in terms of database |
|
||||||
setup and fixture loading. Now, Rails will only parallelize test executions when |
|
||||||
there are enough tests to make it worth it. |
|
||||||
|
|
||||||
This threshold is 50 by default, and is configurable via config setting in |
|
||||||
your test.rb: |
|
||||||
|
|
||||||
```ruby |
|
||||||
config.active_support.test_parallelization_threshold = 100 |
|
||||||
``` |
|
||||||
|
|
||||||
It's also configurable at the test case level: |
|
||||||
|
|
||||||
```ruby |
|
||||||
class ActiveSupport::TestCase |
|
||||||
parallelize threshold: 100 |
|
||||||
end |
|
||||||
``` |
|
||||||
|
|
||||||
*Jorge Manrubia* |
|
||||||
|
|
||||||
* OpenSSL constants are now used for Digest computations. |
|
||||||
|
|
||||||
*Dirkjan Bussink* |
|
||||||
|
|
||||||
* `TimeZone.iso8601` now accepts valid ordinal values similar to Ruby's `Date._iso8601` method. |
|
||||||
A valid ordinal value will be converted to an instance of `TimeWithZone` using the `:year` |
|
||||||
and `:yday` fragments returned from `Date._iso8601`. |
|
||||||
|
|
||||||
```ruby |
|
||||||
twz = ActiveSupport::TimeZone["Eastern Time (US & Canada)"].iso8601("21087") |
|
||||||
twz.to_a[0, 6] == [0, 0, 0, 28, 03, 2021] |
|
||||||
``` |
|
||||||
|
|
||||||
*Steve Laing* |
|
||||||
|
|
||||||
* `Time#change` and methods that call it (e.g. `Time#advance`) will now |
|
||||||
return a `Time` with the timezone argument provided, if the caller was |
|
||||||
initialized with a timezone argument. |
|
||||||
|
|
||||||
Fixes [#42467](https://github.com/rails/rails/issues/42467). |
|
||||||
|
|
||||||
*Alex Ghiculescu* |
|
||||||
|
|
||||||
* Allow serializing any module or class to JSON by name. |
|
||||||
|
|
||||||
*Tyler Rick*, *Zachary Scott* |
|
||||||
|
|
||||||
* Raise `ActiveSupport::EncryptedFile::MissingKeyError` when the |
|
||||||
`RAILS_MASTER_KEY` environment variable is blank (e.g. `""`). |
|
||||||
|
|
||||||
*Sunny Ripert* |
|
||||||
|
|
||||||
* The `from:` option is added to `ActiveSupport::TestCase#assert_no_changes`. |
|
||||||
|
|
||||||
It permits asserting on the initial value that is expected not to change. |
|
||||||
|
|
||||||
```ruby |
|
||||||
assert_no_changes -> { Status.all_good? }, from: true do |
|
||||||
post :create, params: { status: { ok: true } } |
|
||||||
end |
|
||||||
``` |
|
||||||
|
|
||||||
*George Claghorn* |
|
||||||
|
|
||||||
* Deprecate `ActiveSupport::SafeBuffer`'s incorrect implicit conversion of objects into string. |
|
||||||
|
|
||||||
Except for a few methods like `String#%`, objects must implement `#to_str` |
|
||||||
to be implicitly converted to a String in string operations. In some |
|
||||||
circumstances `ActiveSupport::SafeBuffer` was incorrectly calling the |
|
||||||
explicit conversion method (`#to_s`) on them. This behavior is now |
|
||||||
deprecated. |
|
||||||
|
|
||||||
*Jean Boussier* |
|
||||||
|
|
||||||
* Allow nested access to keys on `Rails.application.credentials`. |
|
||||||
|
|
||||||
Previously only top level keys in `credentials.yml.enc` could be accessed with method calls. Now any key can. |
|
||||||
|
|
||||||
For example, given these secrets: |
|
||||||
|
|
||||||
```yml |
|
||||||
aws: |
|
||||||
access_key_id: 123 |
|
||||||
secret_access_key: 345 |
|
||||||
``` |
|
||||||
|
|
||||||
`Rails.application.credentials.aws.access_key_id` will now return the same thing as |
|
||||||
`Rails.application.credentials.aws[:access_key_id]`. |
|
||||||
|
|
||||||
*Alex Ghiculescu* |
|
||||||
|
|
||||||
* Added a faster and more compact `ActiveSupport::Cache` serialization format. |
|
||||||
|
|
||||||
It can be enabled with `config.active_support.cache_format_version = 7.0` or |
|
||||||
`config.load_defaults 7.0`. Regardless of the configuration Active Support |
|
||||||
7.0 can read cache entries serialized by Active Support 6.1 which allows to |
|
||||||
upgrade without invalidating the cache. However Rails 6.1 can't read the |
|
||||||
new format, so all readers must be upgraded before the new format is enabled. |
|
||||||
|
|
||||||
*Jean Boussier* |
|
||||||
|
|
||||||
* Add `Enumerable#sole`, per `ActiveRecord::FinderMethods#sole`. Returns the |
|
||||||
sole item of the enumerable, raising if no items are found, or if more than |
|
||||||
one is. |
|
||||||
|
|
||||||
*Asherah Connor* |
|
||||||
|
|
||||||
* Freeze `ActiveSupport::Duration#parts` and remove writer methods. |
|
||||||
|
|
||||||
Durations are meant to be value objects and should not be mutated. |
|
||||||
|
|
||||||
*Andrew White* |
|
||||||
|
|
||||||
* Fix `ActiveSupport::TimeZone#utc_to_local` with fractional seconds. |
|
||||||
|
|
||||||
When `utc_to_local_returns_utc_offset_times` is false and the time |
|
||||||
instance had fractional seconds the new UTC time instance was out by |
|
||||||
a factor of 1,000,000 as the `Time.utc` constructor takes a usec |
|
||||||
value and not a fractional second value. |
|
||||||
|
|
||||||
*Andrew White* |
|
||||||
|
|
||||||
* Add `expires_at` argument to `ActiveSupport::Cache` `write` and `fetch` to set a cache entry TTL as an absolute time. |
|
||||||
|
|
||||||
```ruby |
|
||||||
Rails.cache.write(key, value, expires_at: Time.now.at_end_of_hour) |
|
||||||
``` |
|
||||||
|
|
||||||
*Jean Boussier* |
|
||||||
|
|
||||||
* Deprecate `ActiveSupport::TimeWithZone.name` so that from Rails 7.1 it will use the default implementation. |
|
||||||
|
|
||||||
*Andrew White* |
|
||||||
|
|
||||||
* Deprecates Rails custom `Enumerable#sum` and `Array#sum` in favor of Ruby's native implementation which |
|
||||||
is considerably faster. |
|
||||||
|
|
||||||
Ruby requires an initializer for non-numeric type as per examples below: |
|
||||||
|
|
||||||
```ruby |
|
||||||
%w[foo bar].sum('') |
|
||||||
# instead of %w[foo bar].sum |
|
||||||
|
|
||||||
[[1, 2], [3, 4, 5]].sum([]) |
|
||||||
# instead of [[1, 2], [3, 4, 5]].sum |
|
||||||
``` |
|
||||||
|
|
||||||
*Alberto Mota* |
|
||||||
|
|
||||||
* Tests parallelization is now disabled when running individual files to prevent the setup overhead. |
|
||||||
|
|
||||||
It can still be enforced if the environment variable `PARALLEL_WORKERS` is present and set to a value greater than 1. |
|
||||||
|
|
||||||
*Ricardo Díaz* |
|
||||||
|
|
||||||
* Fix proxying keyword arguments in `ActiveSupport::CurrentAttributes`. |
|
||||||
|
|
||||||
*Marcin Kołodziej* |
|
||||||
|
|
||||||
* Add `Enumerable#maximum` and `Enumerable#minimum` to easily calculate the maximum or minimum from extracted |
|
||||||
elements of an enumerable. |
|
||||||
|
|
||||||
```ruby |
|
||||||
payments = [Payment.new(5), Payment.new(15), Payment.new(10)] |
|
||||||
|
|
||||||
payments.minimum(:price) # => 5 |
|
||||||
payments.maximum(:price) # => 15 |
|
||||||
``` |
|
||||||
|
|
||||||
This also allows passing enumerables to `fresh_when` and `stale?` in Action Controller. |
|
||||||
See PR [#41404](https://github.com/rails/rails/pull/41404) for an example. |
|
||||||
|
|
||||||
*Ayrton De Craene* |
|
||||||
|
|
||||||
* `ActiveSupport::Cache::MemCacheStore` now accepts an explicit `nil` for its `addresses` argument. |
|
||||||
|
|
||||||
```ruby |
|
||||||
config.cache_store = :mem_cache_store, nil |
|
||||||
|
|
||||||
# is now equivalent to |
|
||||||
|
|
||||||
config.cache_store = :mem_cache_store |
|
||||||
|
|
||||||
# and is also equivalent to |
|
||||||
|
|
||||||
config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211" |
|
||||||
|
|
||||||
# which is the fallback behavior of Dalli |
|
||||||
``` |
|
||||||
|
|
||||||
This helps those migrating from `:dalli_store`, where an explicit `nil` was permitted. |
|
||||||
|
|
||||||
*Michael Overmeyer* |
|
||||||
|
|
||||||
* Add `Enumerable#in_order_of` to put an Enumerable in a certain order by a key. |
|
||||||
|
|
||||||
*DHH* |
|
||||||
|
|
||||||
* `ActiveSupport::Inflector.camelize` behaves expected when provided a symbol `:upper` or `:lower` argument. Matches |
|
||||||
`String#camelize` behavior. |
|
||||||
|
|
||||||
*Alex Ghiculescu* |
|
||||||
|
|
||||||
* Raises an `ArgumentError` when the first argument of `ActiveSupport::Notification.subscribe` is |
|
||||||
invalid. |
|
||||||
|
|
||||||
*Vipul A M* |
|
||||||
|
|
||||||
* `HashWithIndifferentAccess#deep_transform_keys` now returns a `HashWithIndifferentAccess` instead of a `Hash`. |
|
||||||
|
|
||||||
*Nathaniel Woodthorpe* |
|
||||||
|
|
||||||
* Consume dalli’s `cache_nils` configuration as `ActiveSupport::Cache`'s `skip_nil` when using `MemCacheStore`. |
|
||||||
|
|
||||||
*Ritikesh G* |
|
||||||
|
|
||||||
* Add `RedisCacheStore#stats` method similar to `MemCacheStore#stats`. Calls `redis#info` internally. |
|
||||||
|
|
||||||
*Ritikesh G* |
|
||||||
|
|
||||||
|
|
||||||
Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activesupport/CHANGELOG.md) for previous changes. |
|
@ -1,20 +0,0 @@ |
|||||||
Copyright (c) 2005-2022 David Heinemeier Hansson |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining |
|
||||||
a copy of this software and associated documentation files (the |
|
||||||
"Software"), to deal in the Software without restriction, including |
|
||||||
without limitation the rights to use, copy, modify, merge, publish, |
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to |
|
||||||
permit persons to whom the Software is furnished to do so, subject to |
|
||||||
the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be |
|
||||||
included in all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
@ -1,40 +0,0 @@ |
|||||||
= Active Support -- Utility classes and Ruby extensions from Rails |
|
||||||
|
|
||||||
Active Support is a collection of utility classes and standard library |
|
||||||
extensions that were found useful for the Rails framework. These additions |
|
||||||
reside in this package so they can be loaded as needed in Ruby projects |
|
||||||
outside of Rails. |
|
||||||
|
|
||||||
You can read more about the extensions in the {Active Support Core Extensions}[https://edgeguides.rubyonrails.org/active_support_core_extensions.html] guide. |
|
||||||
|
|
||||||
== Download and installation |
|
||||||
|
|
||||||
The latest version of Active Support can be installed with RubyGems: |
|
||||||
|
|
||||||
$ gem install activesupport |
|
||||||
|
|
||||||
Source code can be downloaded as part of the Rails project on GitHub: |
|
||||||
|
|
||||||
* https://github.com/rails/rails/tree/main/activesupport |
|
||||||
|
|
||||||
|
|
||||||
== License |
|
||||||
|
|
||||||
Active Support is released under the MIT license: |
|
||||||
|
|
||||||
* https://opensource.org/licenses/MIT |
|
||||||
|
|
||||||
|
|
||||||
== Support |
|
||||||
|
|
||||||
API documentation is at: |
|
||||||
|
|
||||||
* https://api.rubyonrails.org |
|
||||||
|
|
||||||
Bug reports for the Ruby on Rails project can be filed here: |
|
||||||
|
|
||||||
* https://github.com/rails/rails/issues |
|
||||||
|
|
||||||
Feature requests should be discussed on the rails-core mailing list here: |
|
||||||
|
|
||||||
* https://discuss.rubyonrails.org/c/rubyonrails-core |
|
@ -1,124 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
#-- |
|
||||||
# Copyright (c) 2005-2022 David Heinemeier Hansson |
|
||||||
# |
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining |
|
||||||
# a copy of this software and associated documentation files (the |
|
||||||
# "Software"), to deal in the Software without restriction, including |
|
||||||
# without limitation the rights to use, copy, modify, merge, publish, |
|
||||||
# distribute, sublicense, and/or sell copies of the Software, and to |
|
||||||
# permit persons to whom the Software is furnished to do so, subject to |
|
||||||
# the following conditions: |
|
||||||
# |
|
||||||
# The above copyright notice and this permission notice shall be |
|
||||||
# included in all copies or substantial portions of the Software. |
|
||||||
# |
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
||||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
||||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|
||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
||||||
#++ |
|
||||||
|
|
||||||
require "securerandom" |
|
||||||
require "active_support/dependencies/autoload" |
|
||||||
require "active_support/version" |
|
||||||
require "active_support/logger" |
|
||||||
require "active_support/lazy_load_hooks" |
|
||||||
require "active_support/core_ext/date_and_time/compatibility" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
extend ActiveSupport::Autoload |
|
||||||
|
|
||||||
autoload :Concern |
|
||||||
autoload :CodeGenerator |
|
||||||
autoload :ActionableError |
|
||||||
autoload :ConfigurationFile |
|
||||||
autoload :CurrentAttributes |
|
||||||
autoload :Dependencies |
|
||||||
autoload :DescendantsTracker |
|
||||||
autoload :ExecutionContext |
|
||||||
autoload :ExecutionWrapper |
|
||||||
autoload :Executor |
|
||||||
autoload :ErrorReporter |
|
||||||
autoload :FileUpdateChecker |
|
||||||
autoload :EventedFileUpdateChecker |
|
||||||
autoload :ForkTracker |
|
||||||
autoload :LogSubscriber |
|
||||||
autoload :IsolatedExecutionState |
|
||||||
autoload :Notifications |
|
||||||
autoload :Reloader |
|
||||||
autoload :PerThreadRegistry |
|
||||||
autoload :SecureCompareRotator |
|
||||||
|
|
||||||
eager_autoload do |
|
||||||
autoload :BacktraceCleaner |
|
||||||
autoload :ProxyObject |
|
||||||
autoload :Benchmarkable |
|
||||||
autoload :Cache |
|
||||||
autoload :Callbacks |
|
||||||
autoload :Configurable |
|
||||||
autoload :Deprecation |
|
||||||
autoload :Digest |
|
||||||
autoload :Gzip |
|
||||||
autoload :Inflector |
|
||||||
autoload :JSON |
|
||||||
autoload :KeyGenerator |
|
||||||
autoload :MessageEncryptor |
|
||||||
autoload :MessageVerifier |
|
||||||
autoload :Multibyte |
|
||||||
autoload :NumberHelper |
|
||||||
autoload :OptionMerger |
|
||||||
autoload :OrderedHash |
|
||||||
autoload :OrderedOptions |
|
||||||
autoload :StringInquirer |
|
||||||
autoload :EnvironmentInquirer |
|
||||||
autoload :TaggedLogging |
|
||||||
autoload :XmlMini |
|
||||||
autoload :ArrayInquirer |
|
||||||
end |
|
||||||
|
|
||||||
autoload :Rescuable |
|
||||||
autoload :SafeBuffer, "active_support/core_ext/string/output_safety" |
|
||||||
autoload :TestCase |
|
||||||
|
|
||||||
def self.eager_load! |
|
||||||
super |
|
||||||
|
|
||||||
NumberHelper.eager_load! |
|
||||||
end |
|
||||||
|
|
||||||
cattr_accessor :test_order # :nodoc: |
|
||||||
cattr_accessor :test_parallelization_threshold, default: 50 # :nodoc: |
|
||||||
|
|
||||||
singleton_class.attr_accessor :error_reporter # :nodoc: |
|
||||||
|
|
||||||
def self.cache_format_version |
|
||||||
Cache.format_version |
|
||||||
end |
|
||||||
|
|
||||||
def self.cache_format_version=(value) |
|
||||||
Cache.format_version = value |
|
||||||
end |
|
||||||
|
|
||||||
def self.to_time_preserves_timezone |
|
||||||
DateAndTime::Compatibility.preserve_timezone |
|
||||||
end |
|
||||||
|
|
||||||
def self.to_time_preserves_timezone=(value) |
|
||||||
DateAndTime::Compatibility.preserve_timezone = value |
|
||||||
end |
|
||||||
|
|
||||||
def self.utc_to_local_returns_utc_offset_times |
|
||||||
DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times |
|
||||||
end |
|
||||||
|
|
||||||
def self.utc_to_local_returns_utc_offset_times=(value) |
|
||||||
DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times = value |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
autoload :I18n, "active_support/i18n" |
|
@ -1,48 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
# Actionable errors lets you define actions to resolve an error. |
|
||||||
# |
|
||||||
# To make an error actionable, include the <tt>ActiveSupport::ActionableError</tt> |
|
||||||
# module and invoke the +action+ class macro to define the action. An action |
|
||||||
# needs a name and a block to execute. |
|
||||||
module ActionableError |
|
||||||
extend Concern |
|
||||||
|
|
||||||
class NonActionable < StandardError; end |
|
||||||
|
|
||||||
included do |
|
||||||
class_attribute :_actions, default: {} |
|
||||||
end |
|
||||||
|
|
||||||
def self.actions(error) # :nodoc: |
|
||||||
case error |
|
||||||
when ActionableError, -> it { Class === it && it < ActionableError } |
|
||||||
error._actions |
|
||||||
else |
|
||||||
{} |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def self.dispatch(error, name) # :nodoc: |
|
||||||
actions(error).fetch(name).call |
|
||||||
rescue KeyError |
|
||||||
raise NonActionable, "Cannot find action \"#{name}\"" |
|
||||||
end |
|
||||||
|
|
||||||
module ClassMethods |
|
||||||
# Defines an action that can resolve the error. |
|
||||||
# |
|
||||||
# class PendingMigrationError < MigrationError |
|
||||||
# include ActiveSupport::ActionableError |
|
||||||
# |
|
||||||
# action "Run pending migrations" do |
|
||||||
# ActiveRecord::Tasks::DatabaseTasks.migrate |
|
||||||
# end |
|
||||||
# end |
|
||||||
def action(name, &block) |
|
||||||
_actions[name] = block |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,5 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
require "active_support" |
|
||||||
require "active_support/time" |
|
||||||
require "active_support/core_ext" |
|
@ -1,48 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
# Wrapping an array in an +ArrayInquirer+ gives a friendlier way to check |
|
||||||
# its string-like contents: |
|
||||||
# |
|
||||||
# variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet]) |
|
||||||
# |
|
||||||
# variants.phone? # => true |
|
||||||
# variants.tablet? # => true |
|
||||||
# variants.desktop? # => false |
|
||||||
class ArrayInquirer < Array |
|
||||||
# Passes each element of +candidates+ collection to ArrayInquirer collection. |
|
||||||
# The method returns true if any element from the ArrayInquirer collection |
|
||||||
# is equal to the stringified or symbolized form of any element in the +candidates+ collection. |
|
||||||
# |
|
||||||
# If +candidates+ collection is not given, method returns true. |
|
||||||
# |
|
||||||
# variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet]) |
|
||||||
# |
|
||||||
# variants.any? # => true |
|
||||||
# variants.any?(:phone, :tablet) # => true |
|
||||||
# variants.any?('phone', 'desktop') # => true |
|
||||||
# variants.any?(:desktop, :watch) # => false |
|
||||||
def any?(*candidates) |
|
||||||
if candidates.none? |
|
||||||
super |
|
||||||
else |
|
||||||
candidates.any? do |candidate| |
|
||||||
include?(candidate.to_sym) || include?(candidate.to_s) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
def respond_to_missing?(name, include_private = false) |
|
||||||
name.end_with?("?") || super |
|
||||||
end |
|
||||||
|
|
||||||
def method_missing(name, *args) |
|
||||||
if name.end_with?("?") |
|
||||||
any?(name[0..-2]) |
|
||||||
else |
|
||||||
super |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,131 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
# Backtraces often include many lines that are not relevant for the context |
|
||||||
# under review. This makes it hard to find the signal amongst the backtrace |
|
||||||
# noise, and adds debugging time. With a BacktraceCleaner, filters and |
|
||||||
# silencers are used to remove the noisy lines, so that only the most relevant |
|
||||||
# lines remain. |
|
||||||
# |
|
||||||
# Filters are used to modify lines of data, while silencers are used to remove |
|
||||||
# lines entirely. The typical filter use case is to remove lengthy path |
|
||||||
# information from the start of each line, and view file paths relevant to the |
|
||||||
# app directory instead of the file system root. The typical silencer use case |
|
||||||
# is to exclude the output of a noisy library from the backtrace, so that you |
|
||||||
# can focus on the rest. |
|
||||||
# |
|
||||||
# bc = ActiveSupport::BacktraceCleaner.new |
|
||||||
# bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix |
|
||||||
# bc.add_silencer { |line| /puma|rubygems/.match?(line) } # skip any lines from puma or rubygems |
|
||||||
# bc.clean(exception.backtrace) # perform the cleanup |
|
||||||
# |
|
||||||
# To reconfigure an existing BacktraceCleaner (like the default one in Rails) |
|
||||||
# and show as much data as possible, you can always call |
|
||||||
# <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the |
|
||||||
# backtrace to a pristine state. If you need to reconfigure an existing |
|
||||||
# BacktraceCleaner so that it does not filter or modify the paths of any lines |
|
||||||
# of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt> |
|
||||||
# These two methods will give you a completely untouched backtrace. |
|
||||||
# |
|
||||||
# Inspired by the Quiet Backtrace gem by thoughtbot. |
|
||||||
class BacktraceCleaner |
|
||||||
def initialize |
|
||||||
@filters, @silencers = [], [] |
|
||||||
add_gem_filter |
|
||||||
add_gem_silencer |
|
||||||
add_stdlib_silencer |
|
||||||
end |
|
||||||
|
|
||||||
# Returns the backtrace after all filters and silencers have been run |
|
||||||
# against it. Filters run first, then silencers. |
|
||||||
def clean(backtrace, kind = :silent) |
|
||||||
filtered = filter_backtrace(backtrace) |
|
||||||
|
|
||||||
case kind |
|
||||||
when :silent |
|
||||||
silence(filtered) |
|
||||||
when :noise |
|
||||||
noise(filtered) |
|
||||||
else |
|
||||||
filtered |
|
||||||
end |
|
||||||
end |
|
||||||
alias :filter :clean |
|
||||||
|
|
||||||
# Adds a filter from the block provided. Each line in the backtrace will be |
|
||||||
# mapped against this filter. |
|
||||||
# |
|
||||||
# # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb" |
|
||||||
# backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') } |
|
||||||
def add_filter(&block) |
|
||||||
@filters << block |
|
||||||
end |
|
||||||
|
|
||||||
# Adds a silencer from the block provided. If the silencer returns +true+ |
|
||||||
# for a given line, it will be excluded from the clean backtrace. |
|
||||||
# |
|
||||||
# # Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb" |
|
||||||
# backtrace_cleaner.add_silencer { |line| /puma/.match?(line) } |
|
||||||
def add_silencer(&block) |
|
||||||
@silencers << block |
|
||||||
end |
|
||||||
|
|
||||||
# Removes all silencers, but leaves in the filters. Useful if your |
|
||||||
# context of debugging suddenly expands as you suspect a bug in one of |
|
||||||
# the libraries you use. |
|
||||||
def remove_silencers! |
|
||||||
@silencers = [] |
|
||||||
end |
|
||||||
|
|
||||||
# Removes all filters, but leaves in the silencers. Useful if you suddenly |
|
||||||
# need to see entire filepaths in the backtrace that you had already |
|
||||||
# filtered out. |
|
||||||
def remove_filters! |
|
||||||
@filters = [] |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
FORMATTED_GEMS_PATTERN = /\A[^\/]+ \([\w.]+\) / |
|
||||||
|
|
||||||
def add_gem_filter |
|
||||||
gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) } |
|
||||||
return if gems_paths.empty? |
|
||||||
|
|
||||||
gems_regexp = %r{\A(#{gems_paths.join('|')})/(bundler/)?gems/([^/]+)-([\w.]+)/(.*)} |
|
||||||
gems_result = '\3 (\4) \5' |
|
||||||
add_filter { |line| line.sub(gems_regexp, gems_result) } |
|
||||||
end |
|
||||||
|
|
||||||
def add_gem_silencer |
|
||||||
add_silencer { |line| FORMATTED_GEMS_PATTERN.match?(line) } |
|
||||||
end |
|
||||||
|
|
||||||
def add_stdlib_silencer |
|
||||||
add_silencer { |line| line.start_with?(RbConfig::CONFIG["rubylibdir"]) } |
|
||||||
end |
|
||||||
|
|
||||||
def filter_backtrace(backtrace) |
|
||||||
@filters.each do |f| |
|
||||||
backtrace = backtrace.map { |line| f.call(line) } |
|
||||||
end |
|
||||||
|
|
||||||
backtrace |
|
||||||
end |
|
||||||
|
|
||||||
def silence(backtrace) |
|
||||||
@silencers.each do |s| |
|
||||||
backtrace = backtrace.reject { |line| s.call(line) } |
|
||||||
end |
|
||||||
|
|
||||||
backtrace |
|
||||||
end |
|
||||||
|
|
||||||
def noise(backtrace) |
|
||||||
backtrace.select do |line| |
|
||||||
@silencers.any? do |s| |
|
||||||
s.call(line) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,51 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
require "active_support/core_ext/benchmark" |
|
||||||
require "active_support/core_ext/hash/keys" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Benchmarkable |
|
||||||
# Allows you to measure the execution time of a block in a template and |
|
||||||
# records the result to the log. Wrap this block around expensive operations |
|
||||||
# or possible bottlenecks to get a time reading for the operation. For |
|
||||||
# example, let's say you thought your file processing method was taking too |
|
||||||
# long; you could wrap it in a benchmark block. |
|
||||||
# |
|
||||||
# <% benchmark 'Process data files' do %> |
|
||||||
# <%= expensive_files_operation %> |
|
||||||
# <% end %> |
|
||||||
# |
|
||||||
# That would add something like "Process data files (345.2ms)" to the log, |
|
||||||
# which you can then use to compare timings when optimizing your code. |
|
||||||
# |
|
||||||
# You may give an optional logger level (<tt>:debug</tt>, <tt>:info</tt>, |
|
||||||
# <tt>:warn</tt>, <tt>:error</tt>) as the <tt>:level</tt> option. The |
|
||||||
# default logger level value is <tt>:info</tt>. |
|
||||||
# |
|
||||||
# <% benchmark 'Low-level files', level: :debug do %> |
|
||||||
# <%= lowlevel_files_operation %> |
|
||||||
# <% end %> |
|
||||||
# |
|
||||||
# Finally, you can pass true as the third argument to silence all log |
|
||||||
# activity (other than the timing information) from inside the block. This |
|
||||||
# is great for boiling down a noisy block to just a single statement that |
|
||||||
# produces one log line: |
|
||||||
# |
|
||||||
# <% benchmark 'Process data files', level: :info, silence: true do %> |
|
||||||
# <%= expensive_and_chatty_files_operation %> |
|
||||||
# <% end %> |
|
||||||
def benchmark(message = "Benchmarking", options = {}, &block) |
|
||||||
if logger |
|
||||||
options.assert_valid_keys(:level, :silence) |
|
||||||
options[:level] ||= :info |
|
||||||
|
|
||||||
result = nil |
|
||||||
ms = Benchmark.ms { result = options[:silence] ? logger.silence(&block) : yield } |
|
||||||
logger.public_send(options[:level], "%s (%.1fms)" % [ message, ms ]) |
|
||||||
result |
|
||||||
else |
|
||||||
yield |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,8 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
begin |
|
||||||
require "builder" |
|
||||||
rescue LoadError => e |
|
||||||
$stderr.puts "You don't have builder installed in your application. Please add it to your Gemfile and run bundle install" |
|
||||||
raise e |
|
||||||
end |
|
File diff suppressed because it is too large
Load Diff
@ -1,202 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
require "active_support/core_ext/file/atomic" |
|
||||||
require "active_support/core_ext/string/conversions" |
|
||||||
require "uri/common" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Cache |
|
||||||
# A cache store implementation which stores everything on the filesystem. |
|
||||||
# |
|
||||||
# FileStore implements the Strategy::LocalCache strategy which implements |
|
||||||
# an in-memory cache inside of a block. |
|
||||||
class FileStore < Store |
|
||||||
attr_reader :cache_path |
|
||||||
|
|
||||||
DIR_FORMATTER = "%03X" |
|
||||||
FILENAME_MAX_SIZE = 226 # max filename size on file system is 255, minus room for timestamp, pid, and random characters appended by Tempfile (used by atomic write) |
|
||||||
FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room |
|
||||||
GITKEEP_FILES = [".gitkeep", ".keep"].freeze |
|
||||||
|
|
||||||
def initialize(cache_path, **options) |
|
||||||
super(options) |
|
||||||
@cache_path = cache_path.to_s |
|
||||||
end |
|
||||||
|
|
||||||
# Advertise cache versioning support. |
|
||||||
def self.supports_cache_versioning? |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
# Deletes all items from the cache. In this case it deletes all the entries in the specified |
|
||||||
# file store directory except for .keep or .gitkeep. Be careful which directory is specified in your |
|
||||||
# config file when using +FileStore+ because everything in that directory will be deleted. |
|
||||||
def clear(options = nil) |
|
||||||
root_dirs = (Dir.children(cache_path) - GITKEEP_FILES) |
|
||||||
FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) }) |
|
||||||
rescue Errno::ENOENT, Errno::ENOTEMPTY |
|
||||||
end |
|
||||||
|
|
||||||
# Preemptively iterates through all stored keys and removes the ones which have expired. |
|
||||||
def cleanup(options = nil) |
|
||||||
options = merged_options(options) |
|
||||||
search_dir(cache_path) do |fname| |
|
||||||
entry = read_entry(fname, **options) |
|
||||||
delete_entry(fname, **options) if entry && entry.expired? |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Increments an already existing integer value that is stored in the cache. |
|
||||||
# If the key is not found nothing is done. |
|
||||||
def increment(name, amount = 1, options = nil) |
|
||||||
modify_value(name, amount, options) |
|
||||||
end |
|
||||||
|
|
||||||
# Decrements an already existing integer value that is stored in the cache. |
|
||||||
# If the key is not found nothing is done. |
|
||||||
def decrement(name, amount = 1, options = nil) |
|
||||||
modify_value(name, -amount, options) |
|
||||||
end |
|
||||||
|
|
||||||
def delete_matched(matcher, options = nil) |
|
||||||
options = merged_options(options) |
|
||||||
instrument(:delete_matched, matcher.inspect) do |
|
||||||
matcher = key_matcher(matcher, options) |
|
||||||
search_dir(cache_path) do |path| |
|
||||||
key = file_path_key(path) |
|
||||||
delete_entry(path, **options) if key.match(matcher) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
def read_entry(key, **options) |
|
||||||
if payload = read_serialized_entry(key, **options) |
|
||||||
entry = deserialize_entry(payload) |
|
||||||
entry if entry.is_a?(Cache::Entry) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def read_serialized_entry(key, **) |
|
||||||
File.binread(key) if File.exist?(key) |
|
||||||
rescue => error |
|
||||||
logger.error("FileStoreError (#{error}): #{error.message}") if logger |
|
||||||
nil |
|
||||||
end |
|
||||||
|
|
||||||
def write_entry(key, entry, **options) |
|
||||||
write_serialized_entry(key, serialize_entry(entry, **options), **options) |
|
||||||
end |
|
||||||
|
|
||||||
def write_serialized_entry(key, payload, **options) |
|
||||||
return false if options[:unless_exist] && File.exist?(key) |
|
||||||
ensure_cache_path(File.dirname(key)) |
|
||||||
File.atomic_write(key, cache_path) { |f| f.write(payload) } |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
def delete_entry(key, **options) |
|
||||||
if File.exist?(key) |
|
||||||
begin |
|
||||||
File.delete(key) |
|
||||||
delete_empty_directories(File.dirname(key)) |
|
||||||
true |
|
||||||
rescue |
|
||||||
# Just in case the error was caused by another process deleting the file first. |
|
||||||
raise if File.exist?(key) |
|
||||||
false |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Lock a file for a block so only one process can modify it at a time. |
|
||||||
def lock_file(file_name, &block) |
|
||||||
if File.exist?(file_name) |
|
||||||
File.open(file_name, "r+") do |f| |
|
||||||
f.flock File::LOCK_EX |
|
||||||
yield |
|
||||||
ensure |
|
||||||
f.flock File::LOCK_UN |
|
||||||
end |
|
||||||
else |
|
||||||
yield |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Translate a key into a file path. |
|
||||||
def normalize_key(key, options) |
|
||||||
key = super |
|
||||||
fname = URI.encode_www_form_component(key) |
|
||||||
|
|
||||||
if fname.size > FILEPATH_MAX_SIZE |
|
||||||
fname = ActiveSupport::Digest.hexdigest(key) |
|
||||||
end |
|
||||||
|
|
||||||
hash = Zlib.adler32(fname) |
|
||||||
hash, dir_1 = hash.divmod(0x1000) |
|
||||||
dir_2 = hash.modulo(0x1000) |
|
||||||
|
|
||||||
# Make sure file name doesn't exceed file system limits. |
|
||||||
if fname.length < FILENAME_MAX_SIZE |
|
||||||
fname_paths = fname |
|
||||||
else |
|
||||||
fname_paths = [] |
|
||||||
begin |
|
||||||
fname_paths << fname[0, FILENAME_MAX_SIZE] |
|
||||||
fname = fname[FILENAME_MAX_SIZE..-1] |
|
||||||
end until fname.blank? |
|
||||||
end |
|
||||||
|
|
||||||
File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, fname_paths) |
|
||||||
end |
|
||||||
|
|
||||||
# Translate a file path into a key. |
|
||||||
def file_path_key(path) |
|
||||||
fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last |
|
||||||
URI.decode_www_form_component(fname, Encoding::UTF_8) |
|
||||||
end |
|
||||||
|
|
||||||
# Delete empty directories in the cache. |
|
||||||
def delete_empty_directories(dir) |
|
||||||
return if File.realpath(dir) == File.realpath(cache_path) |
|
||||||
if Dir.children(dir).empty? |
|
||||||
Dir.delete(dir) rescue nil |
|
||||||
delete_empty_directories(File.dirname(dir)) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Make sure a file path's directories exist. |
|
||||||
def ensure_cache_path(path) |
|
||||||
FileUtils.makedirs(path) unless File.exist?(path) |
|
||||||
end |
|
||||||
|
|
||||||
def search_dir(dir, &callback) |
|
||||||
return if !File.exist?(dir) |
|
||||||
Dir.each_child(dir) do |d| |
|
||||||
name = File.join(dir, d) |
|
||||||
if File.directory?(name) |
|
||||||
search_dir(name, &callback) |
|
||||||
else |
|
||||||
callback.call name |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Modifies the amount of an already existing integer value that is stored in the cache. |
|
||||||
# If the key is not found nothing is done. |
|
||||||
def modify_value(name, amount, options) |
|
||||||
file_name = normalize_key(name, options) |
|
||||||
|
|
||||||
lock_file(file_name) do |
|
||||||
options = merged_options(options) |
|
||||||
|
|
||||||
if num = read(name, options) |
|
||||||
num = num.to_i + amount |
|
||||||
write(name, num, options) |
|
||||||
num |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,308 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
begin |
|
||||||
require "dalli" |
|
||||||
rescue LoadError => e |
|
||||||
$stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install" |
|
||||||
raise e |
|
||||||
end |
|
||||||
|
|
||||||
require "delegate" |
|
||||||
require "active_support/core_ext/enumerable" |
|
||||||
require "active_support/core_ext/array/extract_options" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Cache |
|
||||||
# A cache store implementation which stores data in Memcached: |
|
||||||
# https://memcached.org |
|
||||||
# |
|
||||||
# This is currently the most popular cache store for production websites. |
|
||||||
# |
|
||||||
# Special features: |
|
||||||
# - Clustering and load balancing. One can specify multiple memcached servers, |
|
||||||
# and MemCacheStore will load balance between all available servers. If a |
|
||||||
# server goes down, then MemCacheStore will ignore it until it comes back up. |
|
||||||
# |
|
||||||
# MemCacheStore implements the Strategy::LocalCache strategy which implements |
|
||||||
# an in-memory cache inside of a block. |
|
||||||
class MemCacheStore < Store |
|
||||||
# Advertise cache versioning support. |
|
||||||
def self.supports_cache_versioning? |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
prepend Strategy::LocalCache |
|
||||||
|
|
||||||
module DupLocalCache |
|
||||||
class DupLocalStore < DelegateClass(Strategy::LocalCache::LocalStore) |
|
||||||
def write_entry(_key, entry) |
|
||||||
if entry.is_a?(Entry) |
|
||||||
entry.dup_value! |
|
||||||
end |
|
||||||
super |
|
||||||
end |
|
||||||
|
|
||||||
def fetch_entry(key) |
|
||||||
entry = super do |
|
||||||
new_entry = yield |
|
||||||
if entry.is_a?(Entry) |
|
||||||
new_entry.dup_value! |
|
||||||
end |
|
||||||
new_entry |
|
||||||
end |
|
||||||
entry = entry.dup |
|
||||||
|
|
||||||
if entry.is_a?(Entry) |
|
||||||
entry.dup_value! |
|
||||||
end |
|
||||||
|
|
||||||
entry |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
def local_cache |
|
||||||
if ActiveSupport::Cache.format_version == 6.1 |
|
||||||
if local_cache = super |
|
||||||
DupLocalStore.new(local_cache) |
|
||||||
end |
|
||||||
else |
|
||||||
super |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
prepend DupLocalCache |
|
||||||
|
|
||||||
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n |
|
||||||
|
|
||||||
# Creates a new Dalli::Client instance with specified addresses and options. |
|
||||||
# If no addresses are provided, we give nil to Dalli::Client, so it uses its fallbacks: |
|
||||||
# - ENV["MEMCACHE_SERVERS"] (if defined) |
|
||||||
# - "127.0.0.1:11211" (otherwise) |
|
||||||
# |
|
||||||
# ActiveSupport::Cache::MemCacheStore.build_mem_cache |
|
||||||
# # => #<Dalli::Client:0x007f98a47d2028 @servers=["127.0.0.1:11211"], @options={}, @ring=nil> |
|
||||||
# ActiveSupport::Cache::MemCacheStore.build_mem_cache('localhost:10290') |
|
||||||
# # => #<Dalli::Client:0x007f98a47b3a60 @servers=["localhost:10290"], @options={}, @ring=nil> |
|
||||||
def self.build_mem_cache(*addresses) # :nodoc: |
|
||||||
addresses = addresses.flatten |
|
||||||
options = addresses.extract_options! |
|
||||||
addresses = nil if addresses.compact.empty? |
|
||||||
pool_options = retrieve_pool_options(options) |
|
||||||
|
|
||||||
if pool_options.empty? |
|
||||||
Dalli::Client.new(addresses, options) |
|
||||||
else |
|
||||||
ensure_connection_pool_added! |
|
||||||
ConnectionPool.new(pool_options) { Dalli::Client.new(addresses, options.merge(threadsafe: false)) } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Creates a new MemCacheStore object, with the given memcached server |
|
||||||
# addresses. Each address is either a host name, or a host-with-port string |
|
||||||
# in the form of "host_name:port". For example: |
|
||||||
# |
|
||||||
# ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229") |
|
||||||
# |
|
||||||
# If no addresses are provided, but ENV['MEMCACHE_SERVERS'] is defined, it will be used instead. Otherwise, |
|
||||||
# MemCacheStore will connect to localhost:11211 (the default memcached port). |
|
||||||
def initialize(*addresses) |
|
||||||
addresses = addresses.flatten |
|
||||||
options = addresses.extract_options! |
|
||||||
if options.key?(:cache_nils) |
|
||||||
options[:skip_nil] = !options.delete(:cache_nils) |
|
||||||
end |
|
||||||
super(options) |
|
||||||
|
|
||||||
unless [String, Dalli::Client, NilClass].include?(addresses.first.class) |
|
||||||
raise ArgumentError, "First argument must be an empty array, an array of hosts or a Dalli::Client instance." |
|
||||||
end |
|
||||||
if addresses.first.is_a?(Dalli::Client) |
|
||||||
@data = addresses.first |
|
||||||
else |
|
||||||
mem_cache_options = options.dup |
|
||||||
# The value "compress: false" prevents duplicate compression within Dalli. |
|
||||||
mem_cache_options[:compress] = false |
|
||||||
(UNIVERSAL_OPTIONS - %i(compress)).each { |name| mem_cache_options.delete(name) } |
|
||||||
@data = self.class.build_mem_cache(*(addresses + [mem_cache_options])) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Increment a cached value. This method uses the memcached incr atomic |
|
||||||
# operator and can only be used on values written with the :raw option. |
|
||||||
# Calling it on a value not stored with :raw will initialize that value |
|
||||||
# to zero. |
|
||||||
def increment(name, amount = 1, options = nil) |
|
||||||
options = merged_options(options) |
|
||||||
instrument(:increment, name, amount: amount) do |
|
||||||
rescue_error_with nil do |
|
||||||
@data.with { |c| c.incr(normalize_key(name, options), amount, options[:expires_in]) } |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Decrement a cached value. This method uses the memcached decr atomic |
|
||||||
# operator and can only be used on values written with the :raw option. |
|
||||||
# Calling it on a value not stored with :raw will initialize that value |
|
||||||
# to zero. |
|
||||||
def decrement(name, amount = 1, options = nil) |
|
||||||
options = merged_options(options) |
|
||||||
instrument(:decrement, name, amount: amount) do |
|
||||||
rescue_error_with nil do |
|
||||||
@data.with { |c| c.decr(normalize_key(name, options), amount, options[:expires_in]) } |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Clear the entire cache on all memcached servers. This method should |
|
||||||
# be used with care when shared cache is being used. |
|
||||||
def clear(options = nil) |
|
||||||
rescue_error_with(nil) { @data.with { |c| c.flush_all } } |
|
||||||
end |
|
||||||
|
|
||||||
# Get the statistics from the memcached servers. |
|
||||||
def stats |
|
||||||
@data.with { |c| c.stats } |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
module Coders # :nodoc: |
|
||||||
class << self |
|
||||||
def [](version) |
|
||||||
case version |
|
||||||
when 6.1 |
|
||||||
Rails61Coder |
|
||||||
when 7.0 |
|
||||||
Rails70Coder |
|
||||||
else |
|
||||||
raise ArgumentError, "Unknown ActiveSupport::Cache.format_version #{Cache.format_version.inspect}" |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
module Loader |
|
||||||
def load(payload) |
|
||||||
if payload.is_a?(Entry) |
|
||||||
payload |
|
||||||
else |
|
||||||
Cache::Coders::Loader.load(payload) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
module Rails61Coder |
|
||||||
include Loader |
|
||||||
extend self |
|
||||||
|
|
||||||
def dump(entry) |
|
||||||
entry |
|
||||||
end |
|
||||||
|
|
||||||
def dump_compressed(entry, threshold) |
|
||||||
entry.compressed(threshold) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
module Rails70Coder |
|
||||||
include Cache::Coders::Rails70Coder |
|
||||||
include Loader |
|
||||||
extend self |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def default_coder |
|
||||||
Coders[Cache.format_version] |
|
||||||
end |
|
||||||
|
|
||||||
# Read an entry from the cache. |
|
||||||
def read_entry(key, **options) |
|
||||||
deserialize_entry(read_serialized_entry(key, **options), **options) |
|
||||||
end |
|
||||||
|
|
||||||
def read_serialized_entry(key, **options) |
|
||||||
rescue_error_with(nil) do |
|
||||||
@data.with { |c| c.get(key, options) } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Write an entry to the cache. |
|
||||||
def write_entry(key, entry, **options) |
|
||||||
write_serialized_entry(key, serialize_entry(entry, **options), **options) |
|
||||||
end |
|
||||||
|
|
||||||
def write_serialized_entry(key, payload, **options) |
|
||||||
method = options[:unless_exist] ? :add : :set |
|
||||||
expires_in = options[:expires_in].to_i |
|
||||||
if options[:race_condition_ttl] && expires_in > 0 && !options[:raw] |
|
||||||
# Set the memcache expire a few minutes in the future to support race condition ttls on read |
|
||||||
expires_in += 5.minutes |
|
||||||
end |
|
||||||
rescue_error_with false do |
|
||||||
# Don't pass compress option to Dalli since we are already dealing with compression. |
|
||||||
options.delete(:compress) |
|
||||||
@data.with { |c| c.send(method, key, payload, expires_in, **options) } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Reads multiple entries from the cache implementation. |
|
||||||
def read_multi_entries(names, **options) |
|
||||||
keys_to_names = names.index_by { |name| normalize_key(name, options) } |
|
||||||
|
|
||||||
raw_values = @data.with { |c| c.get_multi(keys_to_names.keys) } |
|
||||||
values = {} |
|
||||||
|
|
||||||
raw_values.each do |key, value| |
|
||||||
entry = deserialize_entry(value, raw: options[:raw]) |
|
||||||
|
|
||||||
unless entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options)) |
|
||||||
values[keys_to_names[key]] = entry.value |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
values |
|
||||||
end |
|
||||||
|
|
||||||
# Delete an entry from the cache. |
|
||||||
def delete_entry(key, **options) |
|
||||||
rescue_error_with(false) { @data.with { |c| c.delete(key) } } |
|
||||||
end |
|
||||||
|
|
||||||
def serialize_entry(entry, raw: false, **options) |
|
||||||
if raw |
|
||||||
entry.value.to_s |
|
||||||
else |
|
||||||
super(entry, raw: raw, **options) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Memcache keys are binaries. So we need to force their encoding to binary |
|
||||||
# before applying the regular expression to ensure we are escaping all |
|
||||||
# characters properly. |
|
||||||
def normalize_key(key, options) |
|
||||||
key = super |
|
||||||
if key |
|
||||||
key = key.dup.force_encoding(Encoding::ASCII_8BIT) |
|
||||||
key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" } |
|
||||||
key = "#{key[0, 212]}:hash:#{ActiveSupport::Digest.hexdigest(key)}" if key.size > 250 |
|
||||||
end |
|
||||||
key |
|
||||||
end |
|
||||||
|
|
||||||
def deserialize_entry(payload, raw: false, **) |
|
||||||
if payload && raw |
|
||||||
Entry.new(payload) |
|
||||||
else |
|
||||||
super(payload) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def rescue_error_with(fallback) |
|
||||||
yield |
|
||||||
rescue Dalli::DalliError => error |
|
||||||
ActiveSupport.error_reporter&.report(error, handled: true, severity: :warning) |
|
||||||
logger.error("DalliError (#{error}): #{error.message}") if logger |
|
||||||
fallback |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,203 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
require "monitor" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Cache |
|
||||||
# A cache store implementation which stores everything into memory in the |
|
||||||
# same process. If you're running multiple Ruby on Rails server processes |
|
||||||
# (which is the case if you're using Phusion Passenger or puma clustered mode), |
|
||||||
# then this means that Rails server process instances won't be able |
|
||||||
# to share cache data with each other and this may not be the most |
|
||||||
# appropriate cache in that scenario. |
|
||||||
# |
|
||||||
# This cache has a bounded size specified by the :size options to the |
|
||||||
# initializer (default is 32Mb). When the cache exceeds the allotted size, |
|
||||||
# a cleanup will occur which tries to prune the cache down to three quarters |
|
||||||
# of the maximum size by removing the least recently used entries. |
|
||||||
# |
|
||||||
# Unlike other Cache store implementations, MemoryStore does not compress |
|
||||||
# values by default. MemoryStore does not benefit from compression as much |
|
||||||
# as other Store implementations, as it does not send data over a network. |
|
||||||
# However, when compression is enabled, it still pays the full cost of |
|
||||||
# compression in terms of cpu use. |
|
||||||
# |
|
||||||
# MemoryStore is thread-safe. |
|
||||||
class MemoryStore < Store |
|
||||||
module DupCoder # :nodoc: |
|
||||||
extend self |
|
||||||
|
|
||||||
def dump(entry) |
|
||||||
entry.dup_value! unless entry.compressed? |
|
||||||
entry |
|
||||||
end |
|
||||||
|
|
||||||
def dump_compressed(entry, threshold) |
|
||||||
entry = entry.compressed(threshold) |
|
||||||
entry.dup_value! unless entry.compressed? |
|
||||||
entry |
|
||||||
end |
|
||||||
|
|
||||||
def load(entry) |
|
||||||
entry = entry.dup |
|
||||||
entry.dup_value! |
|
||||||
entry |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def initialize(options = nil) |
|
||||||
options ||= {} |
|
||||||
# Disable compression by default. |
|
||||||
options[:compress] ||= false |
|
||||||
super(options) |
|
||||||
@data = {} |
|
||||||
@max_size = options[:size] || 32.megabytes |
|
||||||
@max_prune_time = options[:max_prune_time] || 2 |
|
||||||
@cache_size = 0 |
|
||||||
@monitor = Monitor.new |
|
||||||
@pruning = false |
|
||||||
end |
|
||||||
|
|
||||||
# Advertise cache versioning support. |
|
||||||
def self.supports_cache_versioning? |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
# Delete all data stored in a given cache store. |
|
||||||
def clear(options = nil) |
|
||||||
synchronize do |
|
||||||
@data.clear |
|
||||||
@cache_size = 0 |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Preemptively iterates through all stored keys and removes the ones which have expired. |
|
||||||
def cleanup(options = nil) |
|
||||||
options = merged_options(options) |
|
||||||
instrument(:cleanup, size: @data.size) do |
|
||||||
keys = synchronize { @data.keys } |
|
||||||
keys.each do |key| |
|
||||||
entry = @data[key] |
|
||||||
delete_entry(key, **options) if entry && entry.expired? |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# To ensure entries fit within the specified memory prune the cache by removing the least |
|
||||||
# recently accessed entries. |
|
||||||
def prune(target_size, max_time = nil) |
|
||||||
return if pruning? |
|
||||||
@pruning = true |
|
||||||
begin |
|
||||||
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) |
|
||||||
cleanup |
|
||||||
instrument(:prune, target_size, from: @cache_size) do |
|
||||||
keys = synchronize { @data.keys } |
|
||||||
keys.each do |key| |
|
||||||
delete_entry(key, **options) |
|
||||||
return if @cache_size <= target_size || (max_time && Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time > max_time) |
|
||||||
end |
|
||||||
end |
|
||||||
ensure |
|
||||||
@pruning = false |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Returns true if the cache is currently being pruned. |
|
||||||
def pruning? |
|
||||||
@pruning |
|
||||||
end |
|
||||||
|
|
||||||
# Increment an integer value in the cache. |
|
||||||
def increment(name, amount = 1, options = nil) |
|
||||||
modify_value(name, amount, options) |
|
||||||
end |
|
||||||
|
|
||||||
# Decrement an integer value in the cache. |
|
||||||
def decrement(name, amount = 1, options = nil) |
|
||||||
modify_value(name, -amount, options) |
|
||||||
end |
|
||||||
|
|
||||||
# Deletes cache entries if the cache key matches a given pattern. |
|
||||||
def delete_matched(matcher, options = nil) |
|
||||||
options = merged_options(options) |
|
||||||
instrument(:delete_matched, matcher.inspect) do |
|
||||||
matcher = key_matcher(matcher, options) |
|
||||||
keys = synchronize { @data.keys } |
|
||||||
keys.each do |key| |
|
||||||
delete_entry(key, **options) if key.match(matcher) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inspect # :nodoc: |
|
||||||
"#<#{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>" |
|
||||||
end |
|
||||||
|
|
||||||
# Synchronize calls to the cache. This should be called wherever the underlying cache implementation |
|
||||||
# is not thread safe. |
|
||||||
def synchronize(&block) # :nodoc: |
|
||||||
@monitor.synchronize(&block) |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
PER_ENTRY_OVERHEAD = 240 |
|
||||||
|
|
||||||
def default_coder |
|
||||||
DupCoder |
|
||||||
end |
|
||||||
|
|
||||||
def cached_size(key, payload) |
|
||||||
key.to_s.bytesize + payload.bytesize + PER_ENTRY_OVERHEAD |
|
||||||
end |
|
||||||
|
|
||||||
def read_entry(key, **options) |
|
||||||
entry = nil |
|
||||||
synchronize do |
|
||||||
payload = @data.delete(key) |
|
||||||
if payload |
|
||||||
@data[key] = payload |
|
||||||
entry = deserialize_entry(payload) |
|
||||||
end |
|
||||||
end |
|
||||||
entry |
|
||||||
end |
|
||||||
|
|
||||||
def write_entry(key, entry, **options) |
|
||||||
payload = serialize_entry(entry, **options) |
|
||||||
synchronize do |
|
||||||
return false if options[:unless_exist] && @data.key?(key) |
|
||||||
|
|
||||||
old_payload = @data[key] |
|
||||||
if old_payload |
|
||||||
@cache_size -= (old_payload.bytesize - payload.bytesize) |
|
||||||
else |
|
||||||
@cache_size += cached_size(key, payload) |
|
||||||
end |
|
||||||
@data[key] = payload |
|
||||||
prune(@max_size * 0.75, @max_prune_time) if @cache_size > @max_size |
|
||||||
true |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def delete_entry(key, **options) |
|
||||||
synchronize do |
|
||||||
payload = @data.delete(key) |
|
||||||
@cache_size -= cached_size(key, payload) if payload |
|
||||||
!!payload |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def modify_value(name, amount, options) |
|
||||||
options = merged_options(options) |
|
||||||
synchronize do |
|
||||||
if num = read(name, options) |
|
||||||
num = num.to_i + amount |
|
||||||
write(name, num, options) |
|
||||||
num |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,56 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Cache |
|
||||||
# A cache store implementation which doesn't actually store anything. Useful in |
|
||||||
# development and test environments where you don't want caching turned on but |
|
||||||
# need to go through the caching interface. |
|
||||||
# |
|
||||||
# This cache does implement the local cache strategy, so values will actually |
|
||||||
# be cached inside blocks that utilize this strategy. See |
|
||||||
# ActiveSupport::Cache::Strategy::LocalCache for more details. |
|
||||||
class NullStore < Store |
|
||||||
prepend Strategy::LocalCache |
|
||||||
|
|
||||||
# Advertise cache versioning support. |
|
||||||
def self.supports_cache_versioning? |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
def clear(options = nil) |
|
||||||
end |
|
||||||
|
|
||||||
def cleanup(options = nil) |
|
||||||
end |
|
||||||
|
|
||||||
def increment(name, amount = 1, options = nil) |
|
||||||
end |
|
||||||
|
|
||||||
def decrement(name, amount = 1, options = nil) |
|
||||||
end |
|
||||||
|
|
||||||
def delete_matched(matcher, options = nil) |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
def read_entry(key, **s) |
|
||||||
deserialize_entry(read_serialized_entry(key)) |
|
||||||
end |
|
||||||
|
|
||||||
def read_serialized_entry(_key, **) |
|
||||||
end |
|
||||||
|
|
||||||
def write_entry(key, entry, **) |
|
||||||
write_serialized_entry(key, serialize_entry(entry)) |
|
||||||
end |
|
||||||
|
|
||||||
def write_serialized_entry(_key, _payload, **) |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
def delete_entry(key, **options) |
|
||||||
false |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,468 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
begin |
|
||||||
gem "redis", ">= 4.0.1" |
|
||||||
require "redis" |
|
||||||
require "redis/distributed" |
|
||||||
rescue LoadError |
|
||||||
warn "The Redis cache store requires the redis gem, version 4.0.1 or later. Please add it to your Gemfile: `gem \"redis\", \"~> 4.0\"`" |
|
||||||
raise |
|
||||||
end |
|
||||||
|
|
||||||
# Prefer the hiredis driver but don't require it. |
|
||||||
begin |
|
||||||
require "redis/connection/hiredis" |
|
||||||
rescue LoadError |
|
||||||
end |
|
||||||
|
|
||||||
require "active_support/digest" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Cache |
|
||||||
module ConnectionPoolLike |
|
||||||
def with |
|
||||||
yield self |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
::Redis.include(ConnectionPoolLike) |
|
||||||
::Redis::Distributed.include(ConnectionPoolLike) |
|
||||||
|
|
||||||
# Redis cache store. |
|
||||||
# |
|
||||||
# Deployment note: Take care to use a *dedicated Redis cache* rather |
|
||||||
# than pointing this at your existing Redis server. It won't cope well |
|
||||||
# with mixed usage patterns and it won't expire cache entries by default. |
|
||||||
# |
|
||||||
# Redis cache server setup guide: https://redis.io/topics/lru-cache |
|
||||||
# |
|
||||||
# * Supports vanilla Redis, hiredis, and Redis::Distributed. |
|
||||||
# * Supports Memcached-like sharding across Redises with Redis::Distributed. |
|
||||||
# * Fault tolerant. If the Redis server is unavailable, no exceptions are |
|
||||||
# raised. Cache fetches are all misses and writes are dropped. |
|
||||||
# * Local cache. Hot in-memory primary cache within block/middleware scope. |
|
||||||
# * +read_multi+ and +write_multi+ support for Redis mget/mset. Use Redis::Distributed |
|
||||||
# 4.0.1+ for distributed mget support. |
|
||||||
# * +delete_matched+ support for Redis KEYS globs. |
|
||||||
class RedisCacheStore < Store |
|
||||||
# Keys are truncated with the ActiveSupport digest if they exceed 1kB |
|
||||||
MAX_KEY_BYTESIZE = 1024 |
|
||||||
|
|
||||||
DEFAULT_REDIS_OPTIONS = { |
|
||||||
connect_timeout: 20, |
|
||||||
read_timeout: 1, |
|
||||||
write_timeout: 1, |
|
||||||
reconnect_attempts: 0, |
|
||||||
} |
|
||||||
|
|
||||||
DEFAULT_ERROR_HANDLER = -> (method:, returning:, exception:) do |
|
||||||
if logger |
|
||||||
logger.error { "RedisCacheStore: #{method} failed, returned #{returning.inspect}: #{exception.class}: #{exception.message}" } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# The maximum number of entries to receive per SCAN call. |
|
||||||
SCAN_BATCH_SIZE = 1000 |
|
||||||
private_constant :SCAN_BATCH_SIZE |
|
||||||
|
|
||||||
# Advertise cache versioning support. |
|
||||||
def self.supports_cache_versioning? |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
prepend Strategy::LocalCache |
|
||||||
|
|
||||||
class << self |
|
||||||
# Factory method to create a new Redis instance. |
|
||||||
# |
|
||||||
# Handles four options: :redis block, :redis instance, single :url |
|
||||||
# string, and multiple :url strings. |
|
||||||
# |
|
||||||
# Option Class Result |
|
||||||
# :redis Proc -> options[:redis].call |
|
||||||
# :redis Object -> options[:redis] |
|
||||||
# :url String -> Redis.new(url: …) |
|
||||||
# :url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …]) |
|
||||||
# |
|
||||||
def build_redis(redis: nil, url: nil, **redis_options) # :nodoc: |
|
||||||
urls = Array(url) |
|
||||||
|
|
||||||
if redis.is_a?(Proc) |
|
||||||
redis.call |
|
||||||
elsif redis |
|
||||||
redis |
|
||||||
elsif urls.size > 1 |
|
||||||
build_redis_distributed_client urls: urls, **redis_options |
|
||||||
else |
|
||||||
build_redis_client url: urls.first, **redis_options |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
def build_redis_distributed_client(urls:, **redis_options) |
|
||||||
::Redis::Distributed.new([], DEFAULT_REDIS_OPTIONS.merge(redis_options)).tap do |dist| |
|
||||||
urls.each { |u| dist.add_node url: u } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def build_redis_client(url:, **redis_options) |
|
||||||
::Redis.new DEFAULT_REDIS_OPTIONS.merge(redis_options.merge(url: url)) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
attr_reader :redis_options |
|
||||||
attr_reader :max_key_bytesize |
|
||||||
|
|
||||||
# Creates a new Redis cache store. |
|
||||||
# |
|
||||||
# Handles four options: :redis block, :redis instance, single :url |
|
||||||
# string, and multiple :url strings. |
|
||||||
# |
|
||||||
# Option Class Result |
|
||||||
# :redis Proc -> options[:redis].call |
|
||||||
# :redis Object -> options[:redis] |
|
||||||
# :url String -> Redis.new(url: …) |
|
||||||
# :url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …]) |
|
||||||
# |
|
||||||
# No namespace is set by default. Provide one if the Redis cache |
|
||||||
# server is shared with other apps: <tt>namespace: 'myapp-cache'</tt>. |
|
||||||
# |
|
||||||
# Compression is enabled by default with a 1kB threshold, so cached |
|
||||||
# values larger than 1kB are automatically compressed. Disable by |
|
||||||
# passing <tt>compress: false</tt> or change the threshold by passing |
|
||||||
# <tt>compress_threshold: 4.kilobytes</tt>. |
|
||||||
# |
|
||||||
# No expiry is set on cache entries by default. Redis is expected to |
|
||||||
# be configured with an eviction policy that automatically deletes |
|
||||||
# least-recently or -frequently used keys when it reaches max memory. |
|
||||||
# See https://redis.io/topics/lru-cache for cache server setup. |
|
||||||
# |
|
||||||
# Race condition TTL is not set by default. This can be used to avoid |
|
||||||
# "thundering herd" cache writes when hot cache entries are expired. |
|
||||||
# See <tt>ActiveSupport::Cache::Store#fetch</tt> for more. |
|
||||||
def initialize(namespace: nil, compress: true, compress_threshold: 1.kilobyte, coder: default_coder, expires_in: nil, race_condition_ttl: nil, error_handler: DEFAULT_ERROR_HANDLER, **redis_options) |
|
||||||
@redis_options = redis_options |
|
||||||
|
|
||||||
@max_key_bytesize = MAX_KEY_BYTESIZE |
|
||||||
@error_handler = error_handler |
|
||||||
|
|
||||||
super namespace: namespace, |
|
||||||
compress: compress, compress_threshold: compress_threshold, |
|
||||||
expires_in: expires_in, race_condition_ttl: race_condition_ttl, |
|
||||||
coder: coder |
|
||||||
end |
|
||||||
|
|
||||||
def redis |
|
||||||
@redis ||= begin |
|
||||||
pool_options = self.class.send(:retrieve_pool_options, redis_options) |
|
||||||
|
|
||||||
if pool_options.any? |
|
||||||
self.class.send(:ensure_connection_pool_added!) |
|
||||||
::ConnectionPool.new(pool_options) { self.class.build_redis(**redis_options) } |
|
||||||
else |
|
||||||
self.class.build_redis(**redis_options) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inspect |
|
||||||
instance = @redis || @redis_options |
|
||||||
"#<#{self.class} options=#{options.inspect} redis=#{instance.inspect}>" |
|
||||||
end |
|
||||||
|
|
||||||
# Cache Store API implementation. |
|
||||||
# |
|
||||||
# Read multiple values at once. Returns a hash of requested keys -> |
|
||||||
# fetched values. |
|
||||||
def read_multi(*names) |
|
||||||
if mget_capable? |
|
||||||
instrument(:read_multi, names, options) do |payload| |
|
||||||
read_multi_mget(*names).tap do |results| |
|
||||||
payload[:hits] = results.keys |
|
||||||
end |
|
||||||
end |
|
||||||
else |
|
||||||
super |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Cache Store API implementation. |
|
||||||
# |
|
||||||
# Supports Redis KEYS glob patterns: |
|
||||||
# |
|
||||||
# h?llo matches hello, hallo and hxllo |
|
||||||
# h*llo matches hllo and heeeello |
|
||||||
# h[ae]llo matches hello and hallo, but not hillo |
|
||||||
# h[^e]llo matches hallo, hbllo, ... but not hello |
|
||||||
# h[a-b]llo matches hallo and hbllo |
|
||||||
# |
|
||||||
# Use \ to escape special characters if you want to match them verbatim. |
|
||||||
# |
|
||||||
# See https://redis.io/commands/KEYS for more. |
|
||||||
# |
|
||||||
# Failsafe: Raises errors. |
|
||||||
def delete_matched(matcher, options = nil) |
|
||||||
instrument :delete_matched, matcher do |
|
||||||
unless String === matcher |
|
||||||
raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}" |
|
||||||
end |
|
||||||
redis.with do |c| |
|
||||||
pattern = namespace_key(matcher, options) |
|
||||||
cursor = "0" |
|
||||||
# Fetch keys in batches using SCAN to avoid blocking the Redis server. |
|
||||||
nodes = c.respond_to?(:nodes) ? c.nodes : [c] |
|
||||||
|
|
||||||
nodes.each do |node| |
|
||||||
begin |
|
||||||
cursor, keys = node.scan(cursor, match: pattern, count: SCAN_BATCH_SIZE) |
|
||||||
node.del(*keys) unless keys.empty? |
|
||||||
end until cursor == "0" |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Cache Store API implementation. |
|
||||||
# |
|
||||||
# Increment a cached value. This method uses the Redis incr atomic |
|
||||||
# operator and can only be used on values written with the :raw option. |
|
||||||
# Calling it on a value not stored with :raw will initialize that value |
|
||||||
# to zero. |
|
||||||
# |
|
||||||
# Failsafe: Raises errors. |
|
||||||
def increment(name, amount = 1, options = nil) |
|
||||||
instrument :increment, name, amount: amount do |
|
||||||
failsafe :increment do |
|
||||||
options = merged_options(options) |
|
||||||
key = normalize_key(name, options) |
|
||||||
|
|
||||||
redis.with do |c| |
|
||||||
c.incrby(key, amount).tap do |
|
||||||
write_key_expiry(c, key, options) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Cache Store API implementation. |
|
||||||
# |
|
||||||
# Decrement a cached value. This method uses the Redis decr atomic |
|
||||||
# operator and can only be used on values written with the :raw option. |
|
||||||
# Calling it on a value not stored with :raw will initialize that value |
|
||||||
# to zero. |
|
||||||
# |
|
||||||
# Failsafe: Raises errors. |
|
||||||
def decrement(name, amount = 1, options = nil) |
|
||||||
instrument :decrement, name, amount: amount do |
|
||||||
failsafe :decrement do |
|
||||||
options = merged_options(options) |
|
||||||
key = normalize_key(name, options) |
|
||||||
|
|
||||||
redis.with do |c| |
|
||||||
c.decrby(key, amount).tap do |
|
||||||
write_key_expiry(c, key, options) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Cache Store API implementation. |
|
||||||
# |
|
||||||
# Removes expired entries. Handled natively by Redis least-recently-/ |
|
||||||
# least-frequently-used expiry, so manual cleanup is not supported. |
|
||||||
def cleanup(options = nil) |
|
||||||
super |
|
||||||
end |
|
||||||
|
|
||||||
# Clear the entire cache on all Redis servers. Safe to use on |
|
||||||
# shared servers if the cache is namespaced. |
|
||||||
# |
|
||||||
# Failsafe: Raises errors. |
|
||||||
def clear(options = nil) |
|
||||||
failsafe :clear do |
|
||||||
if namespace = merged_options(options)[:namespace] |
|
||||||
delete_matched "*", namespace: namespace |
|
||||||
else |
|
||||||
redis.with { |c| c.flushdb } |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Get info from redis servers. |
|
||||||
def stats |
|
||||||
redis.with { |c| c.info } |
|
||||||
end |
|
||||||
|
|
||||||
def mget_capable? # :nodoc: |
|
||||||
set_redis_capabilities unless defined? @mget_capable |
|
||||||
@mget_capable |
|
||||||
end |
|
||||||
|
|
||||||
def mset_capable? # :nodoc: |
|
||||||
set_redis_capabilities unless defined? @mset_capable |
|
||||||
@mset_capable |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
def set_redis_capabilities |
|
||||||
case redis |
|
||||||
when Redis::Distributed |
|
||||||
@mget_capable = true |
|
||||||
@mset_capable = false |
|
||||||
else |
|
||||||
@mget_capable = true |
|
||||||
@mset_capable = true |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Store provider interface: |
|
||||||
# Read an entry from the cache. |
|
||||||
def read_entry(key, **options) |
|
||||||
deserialize_entry(read_serialized_entry(key, **options), **options) |
|
||||||
end |
|
||||||
|
|
||||||
def read_serialized_entry(key, raw: false, **options) |
|
||||||
failsafe :read_entry do |
|
||||||
redis.with { |c| c.get(key) } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def read_multi_entries(names, **options) |
|
||||||
if mget_capable? |
|
||||||
read_multi_mget(*names, **options) |
|
||||||
else |
|
||||||
super |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def read_multi_mget(*names) |
|
||||||
options = names.extract_options! |
|
||||||
options = merged_options(options) |
|
||||||
return {} if names == [] |
|
||||||
raw = options&.fetch(:raw, false) |
|
||||||
|
|
||||||
keys = names.map { |name| normalize_key(name, options) } |
|
||||||
|
|
||||||
values = failsafe(:read_multi_mget, returning: {}) do |
|
||||||
redis.with { |c| c.mget(*keys) } |
|
||||||
end |
|
||||||
|
|
||||||
names.zip(values).each_with_object({}) do |(name, value), results| |
|
||||||
if value |
|
||||||
entry = deserialize_entry(value, raw: raw) |
|
||||||
unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(name, options)) |
|
||||||
results[name] = entry.value |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Write an entry to the cache. |
|
||||||
# |
|
||||||
# Requires Redis 2.6.12+ for extended SET options. |
|
||||||
def write_entry(key, entry, raw: false, **options) |
|
||||||
write_serialized_entry(key, serialize_entry(entry, raw: raw, **options), raw: raw, **options) |
|
||||||
end |
|
||||||
|
|
||||||
def write_serialized_entry(key, payload, raw: false, unless_exist: false, expires_in: nil, race_condition_ttl: nil, **options) |
|
||||||
# If race condition TTL is in use, ensure that cache entries |
|
||||||
# stick around a bit longer after they would have expired |
|
||||||
# so we can purposefully serve stale entries. |
|
||||||
if race_condition_ttl && expires_in && expires_in > 0 && !raw |
|
||||||
expires_in += 5.minutes |
|
||||||
end |
|
||||||
|
|
||||||
modifiers = {} |
|
||||||
if unless_exist || expires_in |
|
||||||
modifiers[:nx] = unless_exist |
|
||||||
modifiers[:px] = (1000 * expires_in.to_f).ceil if expires_in |
|
||||||
end |
|
||||||
|
|
||||||
failsafe :write_entry, returning: false do |
|
||||||
redis.with { |c| c.set key, payload, **modifiers } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def write_key_expiry(client, key, options) |
|
||||||
if options[:expires_in] && client.ttl(key).negative? |
|
||||||
client.expire key, options[:expires_in].to_i |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Delete an entry from the cache. |
|
||||||
def delete_entry(key, options) |
|
||||||
failsafe :delete_entry, returning: false do |
|
||||||
redis.with { |c| c.del key } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Deletes multiple entries in the cache. Returns the number of entries deleted. |
|
||||||
def delete_multi_entries(entries, **_options) |
|
||||||
redis.with { |c| c.del(entries) } |
|
||||||
end |
|
||||||
|
|
||||||
# Nonstandard store provider API to write multiple values at once. |
|
||||||
def write_multi_entries(entries, expires_in: nil, **options) |
|
||||||
if entries.any? |
|
||||||
if mset_capable? && expires_in.nil? |
|
||||||
failsafe :write_multi_entries do |
|
||||||
payload = serialize_entries(entries, **options) |
|
||||||
redis.with do |c| |
|
||||||
c.mapped_mset(payload) |
|
||||||
end |
|
||||||
end |
|
||||||
else |
|
||||||
super |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Truncate keys that exceed 1kB. |
|
||||||
def normalize_key(key, options) |
|
||||||
truncate_key super&.b |
|
||||||
end |
|
||||||
|
|
||||||
def truncate_key(key) |
|
||||||
if key && key.bytesize > max_key_bytesize |
|
||||||
suffix = ":hash:#{ActiveSupport::Digest.hexdigest(key)}" |
|
||||||
truncate_at = max_key_bytesize - suffix.bytesize |
|
||||||
"#{key.byteslice(0, truncate_at)}#{suffix}" |
|
||||||
else |
|
||||||
key |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def deserialize_entry(payload, raw: false, **) |
|
||||||
if raw && !payload.nil? |
|
||||||
Entry.new(payload) |
|
||||||
else |
|
||||||
super(payload) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def serialize_entry(entry, raw: false, **options) |
|
||||||
if raw |
|
||||||
entry.value.to_s |
|
||||||
else |
|
||||||
super(entry, raw: raw, **options) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def serialize_entries(entries, **options) |
|
||||||
entries.transform_values do |entry| |
|
||||||
serialize_entry(entry, **options) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def failsafe(method, returning: nil) |
|
||||||
yield |
|
||||||
rescue ::Redis::BaseError => error |
|
||||||
ActiveSupport.error_reporter&.report(error, handled: true, severity: :warning) |
|
||||||
@error_handler&.call(method: method, exception: error, returning: returning) |
|
||||||
returning |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,183 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
require "active_support/core_ext/string/inflections" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Cache |
|
||||||
module Strategy |
|
||||||
# Caches that implement LocalCache will be backed by an in-memory cache for the |
|
||||||
# duration of a block. Repeated calls to the cache for the same key will hit the |
|
||||||
# in-memory cache for faster access. |
|
||||||
module LocalCache |
|
||||||
autoload :Middleware, "active_support/cache/strategy/local_cache_middleware" |
|
||||||
|
|
||||||
# Class for storing and registering the local caches. |
|
||||||
module LocalCacheRegistry # :nodoc: |
|
||||||
extend self |
|
||||||
|
|
||||||
def cache_for(local_cache_key) |
|
||||||
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {} |
|
||||||
registry[local_cache_key] |
|
||||||
end |
|
||||||
|
|
||||||
def set_cache_for(local_cache_key, value) |
|
||||||
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {} |
|
||||||
registry[local_cache_key] = value |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Simple memory backed cache. This cache is not thread safe and is intended only |
|
||||||
# for serving as a temporary memory cache for a single thread. |
|
||||||
class LocalStore |
|
||||||
def initialize |
|
||||||
@data = {} |
|
||||||
end |
|
||||||
|
|
||||||
def clear(options = nil) |
|
||||||
@data.clear |
|
||||||
end |
|
||||||
|
|
||||||
def read_entry(key) |
|
||||||
@data[key] |
|
||||||
end |
|
||||||
|
|
||||||
def read_multi_entries(keys) |
|
||||||
@data.slice(*keys) |
|
||||||
end |
|
||||||
|
|
||||||
def write_entry(key, entry) |
|
||||||
@data[key] = entry |
|
||||||
true |
|
||||||
end |
|
||||||
|
|
||||||
def delete_entry(key) |
|
||||||
!!@data.delete(key) |
|
||||||
end |
|
||||||
|
|
||||||
def fetch_entry(key) # :nodoc: |
|
||||||
@data.fetch(key) { @data[key] = yield } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Use a local cache for the duration of block. |
|
||||||
def with_local_cache(&block) |
|
||||||
use_temporary_local_cache(LocalStore.new, &block) |
|
||||||
end |
|
||||||
|
|
||||||
# Middleware class can be inserted as a Rack handler to be local cache for the |
|
||||||
# duration of request. |
|
||||||
def middleware |
|
||||||
@middleware ||= Middleware.new( |
|
||||||
"ActiveSupport::Cache::Strategy::LocalCache", |
|
||||||
local_cache_key) |
|
||||||
end |
|
||||||
|
|
||||||
def clear(**options) # :nodoc: |
|
||||||
return super unless cache = local_cache |
|
||||||
cache.clear(options) |
|
||||||
super |
|
||||||
end |
|
||||||
|
|
||||||
def cleanup(**options) # :nodoc: |
|
||||||
return super unless cache = local_cache |
|
||||||
cache.clear |
|
||||||
super |
|
||||||
end |
|
||||||
|
|
||||||
def delete_matched(matcher, options = nil) # :nodoc: |
|
||||||
return super unless cache = local_cache |
|
||||||
cache.clear |
|
||||||
super |
|
||||||
end |
|
||||||
|
|
||||||
def increment(name, amount = 1, **options) # :nodoc: |
|
||||||
return super unless local_cache |
|
||||||
value = bypass_local_cache { super } |
|
||||||
write_cache_value(name, value, raw: true, **options) |
|
||||||
value |
|
||||||
end |
|
||||||
|
|
||||||
def decrement(name, amount = 1, **options) # :nodoc: |
|
||||||
return super unless local_cache |
|
||||||
value = bypass_local_cache { super } |
|
||||||
write_cache_value(name, value, raw: true, **options) |
|
||||||
value |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
def read_serialized_entry(key, raw: false, **options) |
|
||||||
if cache = local_cache |
|
||||||
hit = true |
|
||||||
entry = cache.fetch_entry(key) do |
|
||||||
hit = false |
|
||||||
super |
|
||||||
end |
|
||||||
options[:event][:store] = cache.class.name if hit && options[:event] |
|
||||||
entry |
|
||||||
else |
|
||||||
super |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def read_multi_entries(keys, **options) |
|
||||||
return super unless local_cache |
|
||||||
|
|
||||||
local_entries = local_cache.read_multi_entries(keys) |
|
||||||
missed_keys = keys - local_entries.keys |
|
||||||
|
|
||||||
if missed_keys.any? |
|
||||||
local_entries.merge!(super(missed_keys, **options)) |
|
||||||
else |
|
||||||
local_entries |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def write_serialized_entry(key, payload, **) |
|
||||||
if return_value = super |
|
||||||
local_cache.write_entry(key, payload) if local_cache |
|
||||||
else |
|
||||||
local_cache.delete_entry(key) if local_cache |
|
||||||
end |
|
||||||
return_value |
|
||||||
end |
|
||||||
|
|
||||||
def delete_entry(key, **) |
|
||||||
local_cache.delete_entry(key) if local_cache |
|
||||||
super |
|
||||||
end |
|
||||||
|
|
||||||
def write_cache_value(name, value, **options) |
|
||||||
name = normalize_key(name, options) |
|
||||||
cache = local_cache |
|
||||||
if value |
|
||||||
cache.write_entry(name, serialize_entry(new_entry(value, **options), **options)) |
|
||||||
else |
|
||||||
cache.delete_entry(name) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def local_cache_key |
|
||||||
@local_cache_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, "_").to_sym |
|
||||||
end |
|
||||||
|
|
||||||
def local_cache |
|
||||||
LocalCacheRegistry.cache_for(local_cache_key) |
|
||||||
end |
|
||||||
|
|
||||||
def bypass_local_cache(&block) |
|
||||||
use_temporary_local_cache(nil, &block) |
|
||||||
end |
|
||||||
|
|
||||||
def use_temporary_local_cache(temporary_cache) |
|
||||||
save_cache = LocalCacheRegistry.cache_for(local_cache_key) |
|
||||||
begin |
|
||||||
LocalCacheRegistry.set_cache_for(local_cache_key, temporary_cache) |
|
||||||
yield |
|
||||||
ensure |
|
||||||
LocalCacheRegistry.set_cache_for(local_cache_key, save_cache) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,45 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
require "rack/body_proxy" |
|
||||||
require "rack/utils" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
module Cache |
|
||||||
module Strategy |
|
||||||
module LocalCache |
|
||||||
#-- |
|
||||||
# This class wraps up local storage for middlewares. Only the middleware method should |
|
||||||
# construct them. |
|
||||||
class Middleware # :nodoc: |
|
||||||
attr_reader :name, :local_cache_key |
|
||||||
|
|
||||||
def initialize(name, local_cache_key) |
|
||||||
@name = name |
|
||||||
@local_cache_key = local_cache_key |
|
||||||
@app = nil |
|
||||||
end |
|
||||||
|
|
||||||
def new(app) |
|
||||||
@app = app |
|
||||||
self |
|
||||||
end |
|
||||||
|
|
||||||
def call(env) |
|
||||||
LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new) |
|
||||||
response = @app.call(env) |
|
||||||
response[2] = ::Rack::BodyProxy.new(response[2]) do |
|
||||||
LocalCacheRegistry.set_cache_for(local_cache_key, nil) |
|
||||||
end |
|
||||||
cleanup_on_body_close = true |
|
||||||
response |
|
||||||
rescue Rack::Utils::InvalidParameterError |
|
||||||
[400, {}, []] |
|
||||||
ensure |
|
||||||
LocalCacheRegistry.set_cache_for(local_cache_key, nil) unless |
|
||||||
cleanup_on_body_close |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,961 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
require "active_support/concern" |
|
||||||
require "active_support/descendants_tracker" |
|
||||||
require "active_support/core_ext/array/extract_options" |
|
||||||
require "active_support/core_ext/class/attribute" |
|
||||||
require "active_support/core_ext/string/filters" |
|
||||||
require "active_support/core_ext/object/blank" |
|
||||||
require "thread" |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
# Callbacks are code hooks that are run at key points in an object's life cycle. |
|
||||||
# The typical use case is to have a base class define a set of callbacks |
|
||||||
# relevant to the other functionality it supplies, so that subclasses can |
|
||||||
# install callbacks that enhance or modify the base functionality without |
|
||||||
# needing to override or redefine methods of the base class. |
|
||||||
# |
|
||||||
# Mixing in this module allows you to define the events in the object's |
|
||||||
# life cycle that will support callbacks (via +ClassMethods.define_callbacks+), |
|
||||||
# set the instance methods, procs, or callback objects to be called (via |
|
||||||
# +ClassMethods.set_callback+), and run the installed callbacks at the |
|
||||||
# appropriate times (via +run_callbacks+). |
|
||||||
# |
|
||||||
# By default callbacks are halted by throwing +:abort+. |
|
||||||
# See +ClassMethods.define_callbacks+ for details. |
|
||||||
# |
|
||||||
# Three kinds of callbacks are supported: before callbacks, run before a |
|
||||||
# certain event; after callbacks, run after the event; and around callbacks, |
|
||||||
# blocks that surround the event, triggering it when they yield. Callback code |
|
||||||
# can be contained in instance methods, procs or lambdas, or callback objects |
|
||||||
# that respond to certain predetermined methods. See +ClassMethods.set_callback+ |
|
||||||
# for details. |
|
||||||
# |
|
||||||
# class Record |
|
||||||
# include ActiveSupport::Callbacks |
|
||||||
# define_callbacks :save |
|
||||||
# |
|
||||||
# def save |
|
||||||
# run_callbacks :save do |
|
||||||
# puts "- save" |
|
||||||
# end |
|
||||||
# end |
|
||||||
# end |
|
||||||
# |
|
||||||
# class PersonRecord < Record |
|
||||||
# set_callback :save, :before, :saving_message |
|
||||||
# def saving_message |
|
||||||
# puts "saving..." |
|
||||||
# end |
|
||||||
# |
|
||||||
# set_callback :save, :after do |object| |
|
||||||
# puts "saved" |
|
||||||
# end |
|
||||||
# end |
|
||||||
# |
|
||||||
# person = PersonRecord.new |
|
||||||
# person.save |
|
||||||
# |
|
||||||
# Output: |
|
||||||
# saving... |
|
||||||
# - save |
|
||||||
# saved |
|
||||||
module Callbacks |
|
||||||
extend Concern |
|
||||||
|
|
||||||
included do |
|
||||||
extend ActiveSupport::DescendantsTracker |
|
||||||
class_attribute :__callbacks, instance_writer: false, default: {} |
|
||||||
end |
|
||||||
|
|
||||||
CALLBACK_FILTER_TYPES = [:before, :after, :around] |
|
||||||
|
|
||||||
# Runs the callbacks for the given event. |
|
||||||
# |
|
||||||
# Calls the before and around callbacks in the order they were set, yields |
|
||||||
# the block (if given one), and then runs the after callbacks in reverse |
|
||||||
# order. |
|
||||||
# |
|
||||||
# If the callback chain was halted, returns +false+. Otherwise returns the |
|
||||||
# result of the block, +nil+ if no callbacks have been set, or +true+ |
|
||||||
# if callbacks have been set but no block is given. |
|
||||||
# |
|
||||||
# run_callbacks :save do |
|
||||||
# save |
|
||||||
# end |
|
||||||
# |
|
||||||
#-- |
|
||||||
# |
|
||||||
# As this method is used in many places, and often wraps large portions of |
|
||||||
# user code, it has an additional design goal of minimizing its impact on |
|
||||||
# the visible call stack. An exception from inside a :before or :after |
|
||||||
# callback can be as noisy as it likes -- but when control has passed |
|
||||||
# smoothly through and into the supplied block, we want as little evidence |
|
||||||
# as possible that we were here. |
|
||||||
def run_callbacks(kind) |
|
||||||
callbacks = __callbacks[kind.to_sym] |
|
||||||
|
|
||||||
if callbacks.empty? |
|
||||||
yield if block_given? |
|
||||||
else |
|
||||||
env = Filters::Environment.new(self, false, nil) |
|
||||||
next_sequence = callbacks.compile |
|
||||||
|
|
||||||
# Common case: no 'around' callbacks defined |
|
||||||
if next_sequence.final? |
|
||||||
next_sequence.invoke_before(env) |
|
||||||
env.value = !env.halted && (!block_given? || yield) |
|
||||||
next_sequence.invoke_after(env) |
|
||||||
env.value |
|
||||||
else |
|
||||||
invoke_sequence = Proc.new do |
|
||||||
skipped = nil |
|
||||||
|
|
||||||
while true |
|
||||||
current = next_sequence |
|
||||||
current.invoke_before(env) |
|
||||||
if current.final? |
|
||||||
env.value = !env.halted && (!block_given? || yield) |
|
||||||
elsif current.skip?(env) |
|
||||||
(skipped ||= []) << current |
|
||||||
next_sequence = next_sequence.nested |
|
||||||
next |
|
||||||
else |
|
||||||
next_sequence = next_sequence.nested |
|
||||||
begin |
|
||||||
target, block, method, *arguments = current.expand_call_template(env, invoke_sequence) |
|
||||||
target.send(method, *arguments, &block) |
|
||||||
ensure |
|
||||||
next_sequence = current |
|
||||||
end |
|
||||||
end |
|
||||||
current.invoke_after(env) |
|
||||||
skipped.pop.invoke_after(env) while skipped&.first |
|
||||||
break env.value |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
invoke_sequence.call |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
# A hook invoked every time a before callback is halted. |
|
||||||
# This can be overridden in ActiveSupport::Callbacks implementors in order |
|
||||||
# to provide better debugging/logging. |
|
||||||
def halted_callback_hook(filter, name) |
|
||||||
end |
|
||||||
|
|
||||||
module Conditionals # :nodoc: |
|
||||||
class Value |
|
||||||
def initialize(&block) |
|
||||||
@block = block |
|
||||||
end |
|
||||||
def call(target, value); @block.call(value); end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
module Filters |
|
||||||
Environment = Struct.new(:target, :halted, :value) |
|
||||||
|
|
||||||
class Before |
|
||||||
def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter, name) |
|
||||||
halted_lambda = chain_config[:terminator] |
|
||||||
|
|
||||||
if user_conditions.any? |
|
||||||
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name) |
|
||||||
else |
|
||||||
halting(callback_sequence, user_callback, halted_lambda, filter, name) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name) |
|
||||||
callback_sequence.before do |env| |
|
||||||
target = env.target |
|
||||||
value = env.value |
|
||||||
halted = env.halted |
|
||||||
|
|
||||||
if !halted && user_conditions.all? { |c| c.call(target, value) } |
|
||||||
result_lambda = -> { user_callback.call target, value } |
|
||||||
env.halted = halted_lambda.call(target, result_lambda) |
|
||||||
if env.halted |
|
||||||
target.send :halted_callback_hook, filter, name |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
env |
|
||||||
end |
|
||||||
end |
|
||||||
private_class_method :halting_and_conditional |
|
||||||
|
|
||||||
def self.halting(callback_sequence, user_callback, halted_lambda, filter, name) |
|
||||||
callback_sequence.before do |env| |
|
||||||
target = env.target |
|
||||||
value = env.value |
|
||||||
halted = env.halted |
|
||||||
|
|
||||||
unless halted |
|
||||||
result_lambda = -> { user_callback.call target, value } |
|
||||||
env.halted = halted_lambda.call(target, result_lambda) |
|
||||||
if env.halted |
|
||||||
target.send :halted_callback_hook, filter, name |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
env |
|
||||||
end |
|
||||||
end |
|
||||||
private_class_method :halting |
|
||||||
end |
|
||||||
|
|
||||||
class After |
|
||||||
def self.build(callback_sequence, user_callback, user_conditions, chain_config) |
|
||||||
if chain_config[:skip_after_callbacks_if_terminated] |
|
||||||
if user_conditions.any? |
|
||||||
halting_and_conditional(callback_sequence, user_callback, user_conditions) |
|
||||||
else |
|
||||||
halting(callback_sequence, user_callback) |
|
||||||
end |
|
||||||
else |
|
||||||
if user_conditions.any? |
|
||||||
conditional callback_sequence, user_callback, user_conditions |
|
||||||
else |
|
||||||
simple callback_sequence, user_callback |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions) |
|
||||||
callback_sequence.after do |env| |
|
||||||
target = env.target |
|
||||||
value = env.value |
|
||||||
halted = env.halted |
|
||||||
|
|
||||||
if !halted && user_conditions.all? { |c| c.call(target, value) } |
|
||||||
user_callback.call target, value |
|
||||||
end |
|
||||||
|
|
||||||
env |
|
||||||
end |
|
||||||
end |
|
||||||
private_class_method :halting_and_conditional |
|
||||||
|
|
||||||
def self.halting(callback_sequence, user_callback) |
|
||||||
callback_sequence.after do |env| |
|
||||||
unless env.halted |
|
||||||
user_callback.call env.target, env.value |
|
||||||
end |
|
||||||
|
|
||||||
env |
|
||||||
end |
|
||||||
end |
|
||||||
private_class_method :halting |
|
||||||
|
|
||||||
def self.conditional(callback_sequence, user_callback, user_conditions) |
|
||||||
callback_sequence.after do |env| |
|
||||||
target = env.target |
|
||||||
value = env.value |
|
||||||
|
|
||||||
if user_conditions.all? { |c| c.call(target, value) } |
|
||||||
user_callback.call target, value |
|
||||||
end |
|
||||||
|
|
||||||
env |
|
||||||
end |
|
||||||
end |
|
||||||
private_class_method :conditional |
|
||||||
|
|
||||||
def self.simple(callback_sequence, user_callback) |
|
||||||
callback_sequence.after do |env| |
|
||||||
user_callback.call env.target, env.value |
|
||||||
|
|
||||||
env |
|
||||||
end |
|
||||||
end |
|
||||||
private_class_method :simple |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class Callback # :nodoc:# |
|
||||||
def self.build(chain, filter, kind, options) |
|
||||||
if filter.is_a?(String) |
|
||||||
raise ArgumentError, <<-MSG.squish |
|
||||||
Passing string to define a callback is not supported. See the `.set_callback` |
|
||||||
documentation to see supported values. |
|
||||||
MSG |
|
||||||
end |
|
||||||
|
|
||||||
new chain.name, filter, kind, options, chain.config |
|
||||||
end |
|
||||||
|
|
||||||
attr_accessor :kind, :name |
|
||||||
attr_reader :chain_config, :filter |
|
||||||
|
|
||||||
def initialize(name, filter, kind, options, chain_config) |
|
||||||
@chain_config = chain_config |
|
||||||
@name = name |
|
||||||
@kind = kind |
|
||||||
@filter = filter |
|
||||||
@if = check_conditionals(options[:if]) |
|
||||||
@unless = check_conditionals(options[:unless]) |
|
||||||
end |
|
||||||
|
|
||||||
def merge_conditional_options(chain, if_option:, unless_option:) |
|
||||||
options = { |
|
||||||
if: @if.dup, |
|
||||||
unless: @unless.dup |
|
||||||
} |
|
||||||
|
|
||||||
options[:if].concat Array(unless_option) |
|
||||||
options[:unless].concat Array(if_option) |
|
||||||
|
|
||||||
self.class.build chain, @filter, @kind, options |
|
||||||
end |
|
||||||
|
|
||||||
def matches?(_kind, _filter) |
|
||||||
@kind == _kind && filter == _filter |
|
||||||
end |
|
||||||
|
|
||||||
def duplicates?(other) |
|
||||||
case @filter |
|
||||||
when Symbol |
|
||||||
matches?(other.kind, other.filter) |
|
||||||
else |
|
||||||
false |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Wraps code with filter |
|
||||||
def apply(callback_sequence) |
|
||||||
user_conditions = conditions_lambdas |
|
||||||
user_callback = CallTemplate.build(@filter, self) |
|
||||||
|
|
||||||
case kind |
|
||||||
when :before |
|
||||||
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name) |
|
||||||
when :after |
|
||||||
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config) |
|
||||||
when :around |
|
||||||
callback_sequence.around(user_callback, user_conditions) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def current_scopes |
|
||||||
Array(chain_config[:scope]).map { |s| public_send(s) } |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
EMPTY_ARRAY = [].freeze |
|
||||||
private_constant :EMPTY_ARRAY |
|
||||||
|
|
||||||
def check_conditionals(conditionals) |
|
||||||
return EMPTY_ARRAY if conditionals.blank? |
|
||||||
|
|
||||||
conditionals = Array(conditionals) |
|
||||||
if conditionals.any?(String) |
|
||||||
raise ArgumentError, <<-MSG.squish |
|
||||||
Passing string to be evaluated in :if and :unless conditional |
|
||||||
options is not supported. Pass a symbol for an instance method, |
|
||||||
or a lambda, proc or block, instead. |
|
||||||
MSG |
|
||||||
end |
|
||||||
|
|
||||||
conditionals.freeze |
|
||||||
end |
|
||||||
|
|
||||||
def conditions_lambdas |
|
||||||
@if.map { |c| CallTemplate.build(c, self).make_lambda } + |
|
||||||
@unless.map { |c| CallTemplate.build(c, self).inverted_lambda } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# A future invocation of user-supplied code (either as a callback, |
|
||||||
# or a condition filter). |
|
||||||
module CallTemplate # :nodoc: |
|
||||||
class MethodCall |
|
||||||
def initialize(method) |
|
||||||
@method_name = method |
|
||||||
end |
|
||||||
|
|
||||||
# Return the parts needed to make this call, with the given |
|
||||||
# input values. |
|
||||||
# |
|
||||||
# Returns an array of the form: |
|
||||||
# |
|
||||||
# [target, block, method, *arguments] |
|
||||||
# |
|
||||||
# This array can be used as such: |
|
||||||
# |
|
||||||
# target.send(method, *arguments, &block) |
|
||||||
# |
|
||||||
# The actual invocation is left up to the caller to minimize |
|
||||||
# call stack pollution. |
|
||||||
def expand(target, value, block) |
|
||||||
[target, block, @method_name] |
|
||||||
end |
|
||||||
|
|
||||||
def make_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
target.send(@method_name, &block) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inverted_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
!target.send(@method_name, &block) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class ObjectCall |
|
||||||
def initialize(target, method) |
|
||||||
@override_target = target |
|
||||||
@method_name = method |
|
||||||
end |
|
||||||
|
|
||||||
def expand(target, value, block) |
|
||||||
[@override_target || target, block, @method_name, target] |
|
||||||
end |
|
||||||
|
|
||||||
def make_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
(@override_target || target).send(@method_name, target, &block) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inverted_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
!(@override_target || target).send(@method_name, target, &block) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class InstanceExec0 |
|
||||||
def initialize(block) |
|
||||||
@override_block = block |
|
||||||
end |
|
||||||
|
|
||||||
def expand(target, value, block) |
|
||||||
[target, @override_block, :instance_exec] |
|
||||||
end |
|
||||||
|
|
||||||
def make_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
target.instance_exec(&@override_block) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inverted_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
!target.instance_exec(&@override_block) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class InstanceExec1 |
|
||||||
def initialize(block) |
|
||||||
@override_block = block |
|
||||||
end |
|
||||||
|
|
||||||
def expand(target, value, block) |
|
||||||
[target, @override_block, :instance_exec, target] |
|
||||||
end |
|
||||||
|
|
||||||
def make_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
target.instance_exec(target, &@override_block) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inverted_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
!target.instance_exec(target, &@override_block) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class InstanceExec2 |
|
||||||
def initialize(block) |
|
||||||
@override_block = block |
|
||||||
end |
|
||||||
|
|
||||||
def expand(target, value, block) |
|
||||||
raise ArgumentError unless block |
|
||||||
[target, @override_block || block, :instance_exec, target, block] |
|
||||||
end |
|
||||||
|
|
||||||
def make_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
raise ArgumentError unless block |
|
||||||
target.instance_exec(target, block, &@override_block) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inverted_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
raise ArgumentError unless block |
|
||||||
!target.instance_exec(target, block, &@override_block) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class ProcCall |
|
||||||
def initialize(target) |
|
||||||
@override_target = target |
|
||||||
end |
|
||||||
|
|
||||||
def expand(target, value, block) |
|
||||||
[@override_target || target, block, :call, target, value] |
|
||||||
end |
|
||||||
|
|
||||||
def make_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
(@override_target || target).call(target, value, &block) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def inverted_lambda |
|
||||||
lambda do |target, value, &block| |
|
||||||
!(@override_target || target).call(target, value, &block) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Filters support: |
|
||||||
# |
|
||||||
# Symbols:: A method to call. |
|
||||||
# Procs:: A proc to call with the object. |
|
||||||
# Objects:: An object with a <tt>before_foo</tt> method on it to call. |
|
||||||
# |
|
||||||
# All of these objects are converted into a CallTemplate and handled |
|
||||||
# the same after this point. |
|
||||||
def self.build(filter, callback) |
|
||||||
case filter |
|
||||||
when Symbol |
|
||||||
MethodCall.new(filter) |
|
||||||
when Conditionals::Value |
|
||||||
ProcCall.new(filter) |
|
||||||
when ::Proc |
|
||||||
if filter.arity > 1 |
|
||||||
InstanceExec2.new(filter) |
|
||||||
elsif filter.arity > 0 |
|
||||||
InstanceExec1.new(filter) |
|
||||||
else |
|
||||||
InstanceExec0.new(filter) |
|
||||||
end |
|
||||||
else |
|
||||||
ObjectCall.new(filter, callback.current_scopes.join("_").to_sym) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Execute before and after filters in a sequence instead of |
|
||||||
# chaining them with nested lambda calls, see: |
|
||||||
# https://github.com/rails/rails/issues/18011 |
|
||||||
class CallbackSequence # :nodoc: |
|
||||||
def initialize(nested = nil, call_template = nil, user_conditions = nil) |
|
||||||
@nested = nested |
|
||||||
@call_template = call_template |
|
||||||
@user_conditions = user_conditions |
|
||||||
|
|
||||||
@before = [] |
|
||||||
@after = [] |
|
||||||
end |
|
||||||
|
|
||||||
def before(&before) |
|
||||||
@before.unshift(before) |
|
||||||
self |
|
||||||
end |
|
||||||
|
|
||||||
def after(&after) |
|
||||||
@after.push(after) |
|
||||||
self |
|
||||||
end |
|
||||||
|
|
||||||
def around(call_template, user_conditions) |
|
||||||
CallbackSequence.new(self, call_template, user_conditions) |
|
||||||
end |
|
||||||
|
|
||||||
def skip?(arg) |
|
||||||
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) } |
|
||||||
end |
|
||||||
|
|
||||||
attr_reader :nested |
|
||||||
|
|
||||||
def final? |
|
||||||
!@call_template |
|
||||||
end |
|
||||||
|
|
||||||
def expand_call_template(arg, block) |
|
||||||
@call_template.expand(arg.target, arg.value, block) |
|
||||||
end |
|
||||||
|
|
||||||
def invoke_before(arg) |
|
||||||
@before.each { |b| b.call(arg) } |
|
||||||
end |
|
||||||
|
|
||||||
def invoke_after(arg) |
|
||||||
@after.each { |a| a.call(arg) } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class CallbackChain # :nodoc:# |
|
||||||
include Enumerable |
|
||||||
|
|
||||||
attr_reader :name, :config |
|
||||||
|
|
||||||
def initialize(name, config) |
|
||||||
@name = name |
|
||||||
@config = { |
|
||||||
scope: [:kind], |
|
||||||
terminator: default_terminator |
|
||||||
}.merge!(config) |
|
||||||
@chain = [] |
|
||||||
@callbacks = nil |
|
||||||
@mutex = Mutex.new |
|
||||||
end |
|
||||||
|
|
||||||
def each(&block); @chain.each(&block); end |
|
||||||
def index(o); @chain.index(o); end |
|
||||||
def empty?; @chain.empty?; end |
|
||||||
|
|
||||||
def insert(index, o) |
|
||||||
@callbacks = nil |
|
||||||
@chain.insert(index, o) |
|
||||||
end |
|
||||||
|
|
||||||
def delete(o) |
|
||||||
@callbacks = nil |
|
||||||
@chain.delete(o) |
|
||||||
end |
|
||||||
|
|
||||||
def clear |
|
||||||
@callbacks = nil |
|
||||||
@chain.clear |
|
||||||
self |
|
||||||
end |
|
||||||
|
|
||||||
def initialize_copy(other) |
|
||||||
@callbacks = nil |
|
||||||
@chain = other.chain.dup |
|
||||||
@mutex = Mutex.new |
|
||||||
end |
|
||||||
|
|
||||||
def compile |
|
||||||
@callbacks || @mutex.synchronize do |
|
||||||
final_sequence = CallbackSequence.new |
|
||||||
@callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback| |
|
||||||
callback.apply callback_sequence |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def append(*callbacks) |
|
||||||
callbacks.each { |c| append_one(c) } |
|
||||||
end |
|
||||||
|
|
||||||
def prepend(*callbacks) |
|
||||||
callbacks.each { |c| prepend_one(c) } |
|
||||||
end |
|
||||||
|
|
||||||
protected |
|
||||||
attr_reader :chain |
|
||||||
|
|
||||||
private |
|
||||||
def append_one(callback) |
|
||||||
@callbacks = nil |
|
||||||
remove_duplicates(callback) |
|
||||||
@chain.push(callback) |
|
||||||
end |
|
||||||
|
|
||||||
def prepend_one(callback) |
|
||||||
@callbacks = nil |
|
||||||
remove_duplicates(callback) |
|
||||||
@chain.unshift(callback) |
|
||||||
end |
|
||||||
|
|
||||||
def remove_duplicates(callback) |
|
||||||
@callbacks = nil |
|
||||||
@chain.delete_if { |c| callback.duplicates?(c) } |
|
||||||
end |
|
||||||
|
|
||||||
def default_terminator |
|
||||||
Proc.new do |target, result_lambda| |
|
||||||
terminate = true |
|
||||||
catch(:abort) do |
|
||||||
result_lambda.call |
|
||||||
terminate = false |
|
||||||
end |
|
||||||
terminate |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
module ClassMethods |
|
||||||
def normalize_callback_params(filters, block) # :nodoc: |
|
||||||
type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before |
|
||||||
options = filters.extract_options! |
|
||||||
filters.unshift(block) if block |
|
||||||
[type, filters, options.dup] |
|
||||||
end |
|
||||||
|
|
||||||
# This is used internally to append, prepend and skip callbacks to the |
|
||||||
# CallbackChain. |
|
||||||
def __update_callbacks(name) # :nodoc: |
|
||||||
([self] + self.descendants).reverse_each do |target| |
|
||||||
chain = target.get_callbacks name |
|
||||||
yield target, chain.dup |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Install a callback for the given event. |
|
||||||
# |
|
||||||
# set_callback :save, :before, :before_method |
|
||||||
# set_callback :save, :after, :after_method, if: :condition |
|
||||||
# set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff } |
|
||||||
# |
|
||||||
# The second argument indicates whether the callback is to be run +:before+, |
|
||||||
# +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This |
|
||||||
# means the first example above can also be written as: |
|
||||||
# |
|
||||||
# set_callback :save, :before_method |
|
||||||
# |
|
||||||
# The callback can be specified as a symbol naming an instance method; as a |
|
||||||
# proc, lambda, or block; or as an object that responds to a certain method |
|
||||||
# determined by the <tt>:scope</tt> argument to +define_callbacks+. |
|
||||||
# |
|
||||||
# If a proc, lambda, or block is given, its body is evaluated in the context |
|
||||||
# of the current object. It can also optionally accept the current object as |
|
||||||
# an argument. |
|
||||||
# |
|
||||||
# Before and around callbacks are called in the order that they are set; |
|
||||||
# after callbacks are called in the reverse order. |
|
||||||
# |
|
||||||
# Around callbacks can access the return value from the event, if it |
|
||||||
# wasn't halted, from the +yield+ call. |
|
||||||
# |
|
||||||
# ===== Options |
|
||||||
# |
|
||||||
# * <tt>:if</tt> - A symbol or an array of symbols, each naming an instance |
|
||||||
# method or a proc; the callback will be called only when they all return |
|
||||||
# a true value. |
|
||||||
# |
|
||||||
# If a proc is given, its body is evaluated in the context of the |
|
||||||
# current object. It can also optionally accept the current object as |
|
||||||
# an argument. |
|
||||||
# * <tt>:unless</tt> - A symbol or an array of symbols, each naming an |
|
||||||
# instance method or a proc; the callback will be called only when they |
|
||||||
# all return a false value. |
|
||||||
# |
|
||||||
# If a proc is given, its body is evaluated in the context of the |
|
||||||
# current object. It can also optionally accept the current object as |
|
||||||
# an argument. |
|
||||||
# * <tt>:prepend</tt> - If +true+, the callback will be prepended to the |
|
||||||
# existing chain rather than appended. |
|
||||||
def set_callback(name, *filter_list, &block) |
|
||||||
type, filters, options = normalize_callback_params(filter_list, block) |
|
||||||
|
|
||||||
self_chain = get_callbacks name |
|
||||||
mapped = filters.map do |filter| |
|
||||||
Callback.build(self_chain, filter, type, options) |
|
||||||
end |
|
||||||
|
|
||||||
__update_callbacks(name) do |target, chain| |
|
||||||
options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) |
|
||||||
target.set_callbacks name, chain |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Skip a previously set callback. Like +set_callback+, <tt>:if</tt> or |
|
||||||
# <tt>:unless</tt> options may be passed in order to control when the |
|
||||||
# callback is skipped. |
|
||||||
# |
|
||||||
# class Writer < PersonRecord |
|
||||||
# attr_accessor :age |
|
||||||
# skip_callback :save, :before, :saving_message, if: -> { age > 18 } |
|
||||||
# end |
|
||||||
# |
|
||||||
# When if option returns true, callback is skipped. |
|
||||||
# |
|
||||||
# writer = Writer.new |
|
||||||
# writer.age = 20 |
|
||||||
# writer.save |
|
||||||
# |
|
||||||
# Output: |
|
||||||
# - save |
|
||||||
# saved |
|
||||||
# |
|
||||||
# When if option returns false, callback is NOT skipped. |
|
||||||
# |
|
||||||
# young_writer = Writer.new |
|
||||||
# young_writer.age = 17 |
|
||||||
# young_writer.save |
|
||||||
# |
|
||||||
# Output: |
|
||||||
# saving... |
|
||||||
# - save |
|
||||||
# saved |
|
||||||
# |
|
||||||
# An <tt>ArgumentError</tt> will be raised if the callback has not |
|
||||||
# already been set (unless the <tt>:raise</tt> option is set to <tt>false</tt>). |
|
||||||
def skip_callback(name, *filter_list, &block) |
|
||||||
type, filters, options = normalize_callback_params(filter_list, block) |
|
||||||
|
|
||||||
options[:raise] = true unless options.key?(:raise) |
|
||||||
|
|
||||||
__update_callbacks(name) do |target, chain| |
|
||||||
filters.each do |filter| |
|
||||||
callback = chain.find { |c| c.matches?(type, filter) } |
|
||||||
|
|
||||||
if !callback && options[:raise] |
|
||||||
raise ArgumentError, "#{type.to_s.capitalize} #{name} callback #{filter.inspect} has not been defined" |
|
||||||
end |
|
||||||
|
|
||||||
if callback && (options.key?(:if) || options.key?(:unless)) |
|
||||||
new_callback = callback.merge_conditional_options(chain, if_option: options[:if], unless_option: options[:unless]) |
|
||||||
chain.insert(chain.index(callback), new_callback) |
|
||||||
end |
|
||||||
|
|
||||||
chain.delete(callback) |
|
||||||
end |
|
||||||
target.set_callbacks name, chain |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Remove all set callbacks for the given event. |
|
||||||
def reset_callbacks(name) |
|
||||||
callbacks = get_callbacks name |
|
||||||
|
|
||||||
self.descendants.each do |target| |
|
||||||
chain = target.get_callbacks(name).dup |
|
||||||
callbacks.each { |c| chain.delete(c) } |
|
||||||
target.set_callbacks name, chain |
|
||||||
end |
|
||||||
|
|
||||||
set_callbacks(name, callbacks.dup.clear) |
|
||||||
end |
|
||||||
|
|
||||||
# Define sets of events in the object life cycle that support callbacks. |
|
||||||
# |
|
||||||
# define_callbacks :validate |
|
||||||
# define_callbacks :initialize, :save, :destroy |
|
||||||
# |
|
||||||
# ===== Options |
|
||||||
# |
|
||||||
# * <tt>:terminator</tt> - Determines when a before filter will halt the |
|
||||||
# callback chain, preventing following before and around callbacks from |
|
||||||
# being called and the event from being triggered. |
|
||||||
# This should be a lambda to be executed. |
|
||||||
# The current object and the result lambda of the callback will be provided |
|
||||||
# to the terminator lambda. |
|
||||||
# |
|
||||||
# define_callbacks :validate, terminator: ->(target, result_lambda) { result_lambda.call == false } |
|
||||||
# |
|
||||||
# In this example, if any before validate callbacks returns +false+, |
|
||||||
# any successive before and around callback is not executed. |
|
||||||
# |
|
||||||
# The default terminator halts the chain when a callback throws +:abort+. |
|
||||||
# |
|
||||||
# * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after |
|
||||||
# callbacks should be terminated by the <tt>:terminator</tt> option. By |
|
||||||
# default after callbacks are executed no matter if callback chain was |
|
||||||
# terminated or not. This option has no effect if <tt>:terminator</tt> |
|
||||||
# option is set to +nil+. |
|
||||||
# |
|
||||||
# * <tt>:scope</tt> - Indicates which methods should be executed when an |
|
||||||
# object is used as a callback. |
|
||||||
# |
|
||||||
# class Audit |
|
||||||
# def before(caller) |
|
||||||
# puts 'Audit: before is called' |
|
||||||
# end |
|
||||||
# |
|
||||||
# def before_save(caller) |
|
||||||
# puts 'Audit: before_save is called' |
|
||||||
# end |
|
||||||
# end |
|
||||||
# |
|
||||||
# class Account |
|
||||||
# include ActiveSupport::Callbacks |
|
||||||
# |
|
||||||
# define_callbacks :save |
|
||||||
# set_callback :save, :before, Audit.new |
|
||||||
# |
|
||||||
# def save |
|
||||||
# run_callbacks :save do |
|
||||||
# puts 'save in main' |
|
||||||
# end |
|
||||||
# end |
|
||||||
# end |
|
||||||
# |
|
||||||
# In the above case whenever you save an account the method |
|
||||||
# <tt>Audit#before</tt> will be called. On the other hand |
|
||||||
# |
|
||||||
# define_callbacks :save, scope: [:kind, :name] |
|
||||||
# |
|
||||||
# would trigger <tt>Audit#before_save</tt> instead. That's constructed |
|
||||||
# by calling <tt>#{kind}_#{name}</tt> on the given instance. In this |
|
||||||
# case "kind" is "before" and "name" is "save". In this context +:kind+ |
|
||||||
# and +:name+ have special meanings: +:kind+ refers to the kind of |
|
||||||
# callback (before/after/around) and +:name+ refers to the method on |
|
||||||
# which callbacks are being defined. |
|
||||||
# |
|
||||||
# A declaration like |
|
||||||
# |
|
||||||
# define_callbacks :save, scope: [:name] |
|
||||||
# |
|
||||||
# would call <tt>Audit#save</tt>. |
|
||||||
# |
|
||||||
# ===== Notes |
|
||||||
# |
|
||||||
# +names+ passed to +define_callbacks+ must not end with |
|
||||||
# <tt>!</tt>, <tt>?</tt> or <tt>=</tt>. |
|
||||||
# |
|
||||||
# Calling +define_callbacks+ multiple times with the same +names+ will |
|
||||||
# overwrite previous callbacks registered with +set_callback+. |
|
||||||
def define_callbacks(*names) |
|
||||||
options = names.extract_options! |
|
||||||
|
|
||||||
names.each do |name| |
|
||||||
name = name.to_sym |
|
||||||
|
|
||||||
([self] + self.descendants).each do |target| |
|
||||||
target.set_callbacks name, CallbackChain.new(name, options) |
|
||||||
end |
|
||||||
|
|
||||||
module_eval <<-RUBY, __FILE__, __LINE__ + 1 |
|
||||||
def _run_#{name}_callbacks(&block) |
|
||||||
run_callbacks #{name.inspect}, &block |
|
||||||
end |
|
||||||
|
|
||||||
def self._#{name}_callbacks |
|
||||||
get_callbacks(#{name.inspect}) |
|
||||||
end |
|
||||||
|
|
||||||
def self._#{name}_callbacks=(value) |
|
||||||
set_callbacks(#{name.inspect}, value) |
|
||||||
end |
|
||||||
|
|
||||||
def _#{name}_callbacks |
|
||||||
__callbacks[#{name.inspect}] |
|
||||||
end |
|
||||||
RUBY |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
protected |
|
||||||
def get_callbacks(name) # :nodoc: |
|
||||||
__callbacks[name.to_sym] |
|
||||||
end |
|
||||||
|
|
||||||
def set_callbacks(name, callbacks) # :nodoc: |
|
||||||
unless singleton_class.method_defined?(:__callbacks, false) |
|
||||||
self.__callbacks = __callbacks.dup |
|
||||||
end |
|
||||||
self.__callbacks[name.to_sym] = callbacks |
|
||||||
self.__callbacks |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,65 +0,0 @@ |
|||||||
# frozen_string_literal: true |
|
||||||
|
|
||||||
module ActiveSupport |
|
||||||
class CodeGenerator # :nodoc: |
|
||||||
class MethodSet |
|
||||||
METHOD_CACHES = Hash.new { |h, k| h[k] = Module.new } |
|
||||||
|
|
||||||
def initialize(namespace) |
|
||||||
@cache = METHOD_CACHES[namespace] |
|
||||||
@sources = [] |
|
||||||
@methods = {} |
|
||||||
end |
|
||||||
|
|
||||||
def define_cached_method(name, as: name) |
|
||||||
name = name.to_sym |
|
||||||
as = as.to_sym |
|
||||||
@methods.fetch(name) do |
|
||||||
unless @cache.method_defined?(as) |
|
||||||
yield @sources |
|
||||||
end |
|
||||||
@methods[name] = as |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def apply(owner, path, line) |
|
||||||
unless @sources.empty? |
|
||||||
@cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line) |
|
||||||
end |
|
||||||
@methods.each do |name, as| |
|
||||||
owner.define_method(name, @cache.instance_method(as)) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class << self |
|
||||||
def batch(owner, path, line) |
|
||||||
if owner.is_a?(CodeGenerator) |
|
||||||
yield owner |
|
||||||
else |
|
||||||
instance = new(owner, path, line) |
|
||||||
result = yield instance |
|
||||||
instance.execute |
|
||||||
result |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def initialize(owner, path, line) |
|
||||||
@owner = owner |
|
||||||
@path = path |
|
||||||
@line = line |
|
||||||
@namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) } |
|
||||||
end |
|
||||||
|
|
||||||
def define_cached_method(name, namespace:, as: name, &block) |
|
||||||
@namespaces[namespace].define_cached_method(name, as: as, &block) |
|
||||||
end |
|
||||||
|
|
||||||
def execute |
|
||||||
@namespaces.each_value do |method_set| |
|
||||||
method_set.apply(@owner, @path, @line - 1) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue