My podspec file looks something like:
Pod::Spec.new do |s|
s.name = "MyLib"
s.version = "5.0.0"
...
s.resource_bundles = {'MyBundle' => ["sdk-ios/publickey/prod/ios-5.0.0/somebinary.bin"]}
end
I am picking some binary file and putting it in the resource bundle. There is a separate binary file for each version and is kept in a folder the name of which goes by the version. Now while releasing the new version, instead of making changes at two places - namely s.version and s.resources, is there a way I can use s.version in the value of s.resources? Something like:
s.resource_bundles = {'MyBundle' => ["sdk-ios/publickey/prod/ios-${s.version.to_s}/somebinary.bin"]}
You need to be using # instead of $:
s.resource_bundles = {'MyBundle' => ["sdk-ios/publickey/prod/ios-#{s.version}/somebinary.bin"]}
Related
Trying to lint a local pod spec
$ pod spec lint MyPod.podspec
I'm getting
[!] Attempt to read non existent folder /private/tmp/CocoaPods/Lint/Pods/MyPod.
I checked /private/tmp/CocoaPods/Lint/Pods/ where I didn't find my podspec indeed,
but I found it in /private/tmp/CocoaPods/Lint/Pods/Local Podspecs/
What can cause this and/or how can I debug ?
For info here is my pod spec
Pod::Spec.new do |s|
s.name = "MyPod"
s.version = "0.0.1"
s.summary = "A pretty cool pod"
s.author = { "Me" => "me#home.net" }
s.license = 'MIT'
s.homepage = "http://www.mypod.net"
s.source = { :path => "." }
s.source_files = '*.{h,m}'
s.platform = :ios, '6.0'
s.requires_arc = true
end
:path seems to cause the trouble, :git works
In my case it was caused by commented s.source line as I was testing it before with local podspec and sources. When you'll commit your podspec to the repo make sure to run pod repo update
This can also happen if you have not yet pushed your podspec's targeted tags to your origin/repo. I assume the same might also be true if you are targeting a non-existent git, branch, etc.
I am using ruby version 2.0.0 , I made some custom logo in text file named logo.txt like this:
_____
| |
|_____|
|
|
|
Now i made a gem with name of "custom" and placed this file under lib/logo.txt . Now i wants to print this file in my script under ruby gem so i wrote in this way.
file = File.open("lib/logo.txt")
contents = file.read
puts "#{contents}"
But above code produce errors, like:
/usr/local/rvm/rubies/ruby-2.0.0-p451/lib/ruby/gems/2.0.0/gems/custom-0.0.1/lib/custom/custom.rb:1551:in `initialize': No such file or directory - lib/logo.txt (Errno::ENOENT)
I include this logo.txt file in gemspec as per below:
Gem::Specification.new do |s|
s.name = "custom"
s.version = VERSION
s.author = "Custom Wear"
s.email = "custom#custom.com"
s.homepage = "http://custom.com"
s.summary = "custom wera"
s.description = File.read(File.join(File.dirname(__FILE__), 'README'))
s.license = 'ALL RIGHTS RESERVED'
s.files = [""lib/custom.rb", "lib/custom/custom.rb", "lib/custom /version.rb","lib/logo.txt"]
s.test_files = Dir["spec/**/*"]
s.executables = [ 'custom' ]
s.require_paths << 'lib/'
The file is opened relative to the current working directory, unless you specify the full path.
In order to avoid hard-coding full paths, you can get the full path of the current file from Ruby using __FILE__. In fact you can see in the custom.gemspec file something very similar going on:
File.join( File.dirname(__FILE__), 'README')
I think you can get to your logo file like this:
logo_path = File.join( File.dirname(__FILE__), '../logo.txt' )
file = File.open( logo_path )
In Ruby 2.0, you also have __dir__ (which can replace File.dirname(__FILE__)) but that would not be compatible with Ruby 1.9. Generally you are safer using backward-compatible syntax in gems in case you are not sure what someone has when they run your library.
I am working on an HTML5/JavaScript app with Ruby packaging to be used on multiple platforms including a dash display unit on a car. The code base is the same across platforms except for a single wrapper file that houses all of the API-specific calls for a single platform: i.e. "sdk.web.js" or "sdk.car.js".
I'm hoping to modify the current PackageTask to allow an input for a target platform. Depending on the target, I want the corresponding wrapper file to be renamed to "sdk.js" and included in the package, disregarding the rest to keep the zip archive as small as possible.
From terminal, I want to say something like:
rake target "web"
which would put together a package including "sdk.web.js" renamed "sdk.js". Anyone know if this is possible, and how I would modify my existing RakeFile (below) in order to accomplish this?
require 'fileutils'
require 'rake/packagetask'
VERSION = ""
task :default => [:package]
def parse_version(filename)
f = File.open(filename, "rb")
contents = f.read
m = contents.match('var version = "([0-9.]+)";')
if m
return m[1]
else
return nil
end
end
desc "Package up the app into a zip file"
Rake::PackageTask.new("myApp") do |p|
p.version = parse_version("js/application.js")
p.need_zip = true
p.package_files = FileList["*", "**/*"]
p.package_files.exclude(".git", "pkg/*", "Rakefile", ".rvmrc", "Gemfile", "Gemfile.lock", ".project", ".settings", ".gitignore", "data/store/*", "docs", "docs/*")
end
In general, you can pass arguments to rake tasks. See for instance this page.
However, you don't have access to the package task from PackageTask. A solution would be to define your own packaging task which would add the right js script and then invoke package manually. For instance (untested):
Rake::PackageTask.new("myApp") do |p|
[snip]
p.package_files << "sdk.js"
end
task 'custom_packaging', :sdk do |t, args|
# Copy the right file to sdk.js
FileUtils.cp_f "sdk.#{args[:sdk]}.js", "sdk.js"
Rake::Task["package"].invoke
end
I've always used git to determine which files should go into the gem package:
gem.files = `git ls-files`.split "\n"
Unfortunately, this approach has recently proved to be inappropriate. I need a self-contained, pure-Ruby solution.
My first idea was to simply glob the entire directory, but that alone is likely to include unwanted files. So, after researching the problem, I came up with this:
# example.gemspec
directory = File.dirname File.expand_path __FILE__
dotfiles = %w(.gitignore .rvmrc)
ignore_file = '.gitignore'
file_list = []
Dir.chdir directory do
ignored = File.readlines(ignore_file).map(&:chomp).reject { |glob| glob =~ /\A(#|\s*\z)/ }
file_list.replace Dir['**/**'] + dotfiles
file_list.delete_if do |file|
File.directory?(file) or ignored.any? { |glob| File.fnmatch? glob, file }
end
end
# Later...
gem.files = file_list
That seems a bit complex for a gemspec. It also does not fully support gitignore's pattern format. It currently seems to work but I'd rather not run into problems later.
Is there a simpler but robust way to compute the gem's list of files? Most gems apparently use git ls-files, and the ones that don't either use a solution similar to mine or specify the files manually.
Hi,
You can list all files of your project with pure Ruby:
gem.files = Dir['**/*'].keep_if { |file| File.file?(file) }
Or you can do it manually, this solution is used by Ruby on Rails gems:
gem.files = Dir['lib/**/*'] + %w(.yardopts Gemfile LICENSE README.md Rakefile my_gem.gemspec)
With Rake
The easiest solution depending on rake to list all files from a directory, but exclude everything in the .gitignore file:
require 'rake/file_list'
Rake::FileList['**/*'].exclude(*File.read('.gitignore').split)
RubyGems
Official rubygems solution, list and exclude manually:
require 'rake'
spec.files = FileList['lib/*.rb',
'bin/*',
'[A-Z]*',
'test/*'].to_a
# or without Rake...
spec.files = Dir['lib/*.rb'] + Dir['bin/*']
spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
spec.files.reject! { |fn| fn.include? "CVS" }
Bundler
Bundler solution, list manually:
s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
Note: rejecting directories is useless as gem will ignore them by default.
Vagrant
Vagrant solution to mimic git ls-files and taking care of .gitignore in pure ruby:
# The following block of code determines the files that should be included
# in the gem. It does this by reading all the files in the directory where
# this gemspec is, and parsing out the ignored files from the gitignore.
# Note that the entire gitignore(5) syntax is not supported, specifically
# the "!" syntax, but it should mostly work correctly.
root_path = File.dirname(__FILE__)
all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
all_files.reject! { |file| file.start_with?("website/") }
all_files.reject! { |file| file.start_with?("test/") }
gitignore_path = File.join(root_path, ".gitignore")
gitignore = File.readlines(gitignore_path)
gitignore.map! { |line| line.chomp.strip }
gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
unignored_files = all_files.reject do |file|
# Ignore any directories, the gemspec only cares about files
next true if File.directory?(file)
# Ignore any paths that match anything in the gitignore. We do
# two tests here:
#
# - First, test to see if the entire path matches the gitignore.
# - Second, match if the basename does, this makes it so that things
# like '.DS_Store' will match sub-directories too (same behavior
# as git).
#
gitignore.any? do |ignore|
File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
end
end
Pathspec
Using pathspec gem Match Path Specifications, such as .gitignore, in Ruby!
See https://github.com/highb/pathspec-ruby
References
Ref:
Bundler
Vagrant
RubyGems
Rake easy solution
I'm struggling with getting rubyzip to append directories to a zipoutputstream. (I want the output stream so I can send it from a rails controller). My code follows this example:
http://info.michael-simons.eu/2008/01/21/using-rubyzip-to-create-zip-files-on-the-fly/
When modified to include directories in the list of files to add I get the following error:
Any help would be greatly appreciated.
UPDATE
After trying a number of solutions I had best success with zipruby which has a clean api and good examples: http://zipruby.rubyforge.org/.
Zip::ZipFile.open(path, Zip::ZipFile::CREATE) do |zip|
songs.each do |song|
zip.add "record/#{song.title.parameterize}.mp3", song.file.to_file.path
end
end
OOOOOuuuhh...you DEFINITELY want ZIPPY. It's a Rails plugin that abstracts a lot of the complexity in rubyzip, and lets you create what you're talking about, including directories (from what I recall).
Here you go:
http://github.com/toretore/zippy
And direct from the zippy site:
Example controller:
def show
#gallery = Gallery.find(params[:id])
respond_to do |format|
format.html
format.zip
end
end
Example view:
zip['description.txt'] = #gallery.description
#gallery.photos.each do |photo|
zip["photo_#{photo.id}.png"] = File.open(photo.url)
end
edit: Amending per user comment:
Hmm...the whole objective of using Zippy is to make it a whole lot easier to use ruby zip.
Ya might want to take a second (or first) look...
Here's how to make a directory with directories:
some_var = Zippy.open('awsum.zip') do |zip|
%w{dir_a dir_b dir_c diri}.each do |dir|
zip["bin/#{dir}/"]
end
end
...
send_file some_var, :file_name => ...
Zippy will work for this. There may be a more cool way to do this but since there are essentially no docs, here's what I came up with for recursively copying directories with Zippy in a Rakefile. This Rakefile is used in a Rails environment so I put gem requirements in my Gemfile:
#Gemfile
source 'http://rubygems.org'
gem 'rails'
gem 'zippy'
And this is the Rakefile
#Rakefile
def add_file( zippyfile, dst_dir, f )
zippyfile["#{dst_dir}/#{f}"] = File.open(f)
end
def add_dir( zippyfile, dst_dir, d )
glob = "#{d}/**/*"
FileList.new( glob ).each { |f|
if (File.file?(f))
add_file zippyfile, dst_dir, f
end
}
end
task :myzip do
Zippy.create 'my.zip' do |z|
add_dir z, 'my', 'app'
add_dir z, 'my', 'config'
#...
add_file z, 'my', 'config.ru'
add_file z, 'my', 'Gemfile'
#...
end
end
Now I can use it like this:
C:\> cd my
C:\my> rake myzip
and it will produce my.zip which contains an inner directory called 'my' with copies of selected files and directories.
I was able to get directories working with the same ZipOutputStream used in the original article.
All I had to do was add the directory when calling zos.put_next_entry.
For example:
require 'zip/zip'
require 'zip/zipfilesystem'
t = Tempfile.new("some-weird-temp-file-basename-#{request.remote_ip}")
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive.
Zip::ZipOutputStream.open(t.path) do |zos|
some_file_list.each do |file|
# Create a new entry with some arbitrary name
zos.put_next_entry("myfolder/some-funny-name.jpg") # Added myfolder/
# Add the contents of the file, don't read the stuff linewise if its binary, instead use direct IO
zos.print IO.read(file.path)
end
end
# End of the block automatically closes the file.
# Send it using the right mime type, with a download window and some nice file name.
send_file t.path, :type => 'application/zip', :disposition => 'attachment', :filename => "some-brilliant-file-name.zip"
# The temp file will be deleted some time...
t.close
I just changed zos.put_next_entry('some-funny-name.jpg') to zos.put_next_entry('myfolder/some-funny-name.jpg'), and the resulting zipfile had a nested folder called myfolder that contained the files.