它能做什么:
from = source.next_revision(current_revision)
source
是对您的源代码的引用,从您的 SCM(git、svn 等)可以看出。这设置from
为(本质上)源代码的当前部署版本。
capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l")
capture
意思是“在 shell 中执行这个命令,并返回它的输出”。有问题的命令引用了对您的源的更改日志,将部署的版本与当前版本进行比较(将资产所在的路径指定为“重要”的路径),并将其传递到字数统计工具 ( wc -l
)。该-l
选项意味着它返回输出中行数的计数。因此,输出(由 返回capture
)是在这两个版本之间发生更改的文件名的数量。
如果该数字为零,则任何指定路径中的文件都没有更改,因此我们跳过预编译。
为什么它不起作用:
我不知道。代码本身似乎没有任何问题 - 它或多或少与我使用的代码段相同。您可以检查以下几件事:
Capistrano 是否知道您正在使用资产管道?检查您的 Capfile。如果你没有load 'deploy/assets'
,部署甚至不会考虑编译你的资产。
事实上,您是否启用了资产管道?检查 application.rbconfig.assets.enabled = true
您是否指定了不正确的资产路径?该代码正在检查 和 中的vendor/assets/
更改app/assets/
。如果您的资产位于其他地方(lib/assets
例如 ),它们将不会被注意到。(如果是这种情况,您可以更改该行以包含正确的路径。
事实上,自上次部署以来,您是否更改了任何资产?我建议绕过检查更改资产并强制预编译运行一次,然后重新打开检查并看到问题神奇地自行解决。在下面的示例中,设置force_precompile = true
可以做到这一点。
我用什么:
这是我目前使用的版本。这可能会有所帮助。或不。与原作的变化:
- 一种更易读的方式来指定资产路径(如果您使用它,请记住设置
asset_locations
为您的资产所在的位置)
- 一种强制预编译运行的简单方法(设置
force_precompile=true
为尝试运行检查,但无论如何都运行预编译)
- 无论预编译是否运行,它都会打印出计数。我很高兴获得一些输出以确保检查正在运行。
- 如果在尝试比较文件时发生错误(例如,在全新项目中经常发生),它会打印错误但无论如何都会运行预编译。
.
namespace :assets do
task :precompile, :roles => :web, :except => { :no_release => true } do
# Check if assets have changed. If not, don't run the precompile task - it takes a long time.
force_compile = false
changed_asset_count = 0
begin
from = source.next_revision(current_revision)
asset_locations = 'app/assets/ lib/assets vendor/assets'
changed_asset_count = capture("cd #{latest_release} && #{source.local.log(from)} #{asset_locations} | wc -l").to_i
rescue Exception => e
logger.info "Error: #{e}, forcing precompile"
force_compile = true
end
if changed_asset_count > 0 || force_compile
logger.info "#{changed_asset_count} assets have changed. Pre-compiling"
run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
else
logger.info "#{changed_asset_count} assets have changed. Skipping asset pre-compilation"
end
end
end