Hi,
From time to time, it is necessary to modify the gem dependencies we ship. For example, it is good idea to remove the Mac/Windows specific dependencies from Listen gem or sometimes it is necessary to relax some gem dependency. Historically, we did that using sed or applying patches. I don't think neither is optimal solution. So lately, I was thinking about introducing macros to achieve this.
I am thinking about two macros ATM and here is their implementation:
```
%global gemspec_add_runtime_dependency() \ read -d '' add_runtime_dependency_script << 'EOR' || : \ options = %w(%{*}) \ name = options.shift \ version = [options.join(' ')] \ spec = Gem::Specification.load('.%{gem_spec}') \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write '.%{gem_spec}', spec.to_ruby \ EOR\ echo "$add_runtime_dependency_script" | ruby\ %{nil}
%global gemspec_remove_runtime_dependency() \ ruby \\ -e "name = '%{1}'" \\ -e "spec = Gem::Specification.load('.%{gem_spec}')" \\ -e "spec.dependencies.reject! { |d| d.type == :runtime && d.name == name }" \\ -e "File.write '.%{gem_spec}', spec.to_ruby" \ %{nil}
```
and you can use them as:
```
%gemspec_remove_runtime_dependency fog-dynect %gemspec_add_runtime_dependency fog-dynect ~> 10.0 %gemspec_add_runtime_dependency fog-dynect >= 10.1
```
As you can see, both are using a bit different way of implementation. Let me discuss the details.
The 'gemspec_remove_runtime_dependency' is using bunch of '-e' parameters to specify the code. The advantage of this approach is, that the build output log contains traces of the precise command which was used, e.g.:
```
+ ruby -e 'name = '''fog-dynect'''' -e 'spec = Gem::Specification.load('''./usr/share/gems/specifications/fog-1.38.0.gemspec''')' -e 'spec.dependencies.reject! { |d| d.type == :runtime && d.name == name }' -e 'File.write '''./usr/share/gems/specifications/fog-1.38.0.gemspec''', spec.to_ruby'
```
This is helpful, but the output is not very nice and the implementation is polluted with a lot of noise.
The other approach used in 'gemspec_add_runtime_dependency' puts the entire script into environment variable and then pipes it into the ruby. The log output looks like:
```
+ read -d '' add_runtime_dependency_script + : + echo 'options = %w(fog-dynect >= 10.1) name = options.shift version = [options.join(''' ''')] spec = Gem::Specification.load('''./usr/share/gems/specifications/fog-1.38.0.gemspec''')
dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } if dep dep.requirement.concat version else spec.add_runtime_dependency name, version end File.write '''./usr/share/gems/specifications/fog-1.38.0.gemspec''', spec.to_ruby' + ruby
```
Is this actually useful? Of course, the script could be piped directly into ruby without the env variable magic, but the output is then reduced just to:
```
+ ruby
```
which is not helpful at all (but could be improved by some hint as "adding dependency ....").
So what is you opinion on usefulness of these macros and on the implementation? What is the preferred way for you?
BTW this is first draft of the macros. I am going to try second implementation, which will probably need to use a bit different syntax for macro calls, but it might replace the 3 lines usage example above with 2 lines version:
```
%gemspec_remove_runtime_dependency -n fog-dynect %gemspec_add_runtime_dependency -n fog-dynect ['~> 10.0', '>= 10.1']
```
Please share your thoughts on this topic.
Vít
Dne 15.9.2016 v 10:06 Vít Ondruch napsal(a):
BTW this is first draft of the macros. I am going to try second implementation, which will probably need to use a bit different syntax for macro calls, but it might replace the 3 lines usage example above with 2 lines version:
%gemspec_remove_runtime_dependency -n fog-dynect %gemspec_add_runtime_dependency -n fog-dynect ['~> 10.0', '>= 10.1']
As I promised, this is implementation with the '-n' parameter:
``` %define gemspec_add_runtime_dependency(n:) \ read -d '' add_runtime_dependency_script << 'EOR' || : \ name = '%{-n*}' \ version = %{*} \ spec = Gem::Specification.load('.%{gem_spec}') \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write '.%{gem_spec}', spec.to_ruby \ EOR\ echo "$add_runtime_dependency_script" | ruby \ %{nil}
```
It is a bit more flexible, since what is following behind the name of the dependency is pasted directly into Ruby code, so either ```['~> 10.0', '>= 10.1']``` or '~> 10.0' are viable options. IOW, it must be valid ruby code, otherwise the script bails out with error. E.g. for
``` %gemspec_add_runtime_dependency -n fog-dynect ~> 10.0 ```
the following error is reported:
``` + read -d '' add_runtime_dependency_script + : + echo 'name = '''fog-dynect''' version = ~> 10.0 spec = Gem::Specification.load('''./usr/share/gems/specifications/fog-1.38.0.gemspec''')
dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } if dep dep.requirement.concat version else spec.add_runtime_dependency name, version end File.write '''./usr/share/gems/specifications/fog-1.38.0.gemspec''', spec.to_ruby' + ruby -:2: syntax error, unexpected '>' version = ~> 10.0 ^ ```
Vít
Both approaches allows code injection, such as:
``` %gemspec_add_runtime_dependency -n fog-dynect ['~> 10.0', '>= 10.1.1']; puts requirements ```
But I don't consider this harmful ....
Vít
----- Original Message -----
From: "Vít Ondruch" vondruch@redhat.com To: ruby-sig@lists.fedoraproject.org Sent: Thursday, September 15, 2016 2:00:59 PM Subject: Re: Macros to modify gem dependencies
Dne 15.9.2016 v 10:06 Vít Ondruch napsal(a):
BTW this is first draft of the macros. I am going to try second implementation, which will probably need to use a bit different syntax for macro calls, but it might replace the 3 lines usage example above with 2 lines version:
%gemspec_remove_runtime_dependency -n fog-dynect %gemspec_add_runtime_dependency -n fog-dynect ['~> 10.0', '>= 10.1']
The above gives me strange result in gemspec
``` s.add_runtime_dependency(%q<fog-dynect>, [">= 10.1", ">= 10.1", "~> 10.0"])
```
However,
``` %gemspec_add_dep -n fog-dynect '~> 10.0'
```
results in
``` s.add_dependency(%q<fog-dynect>, [">= 10.1", "~> 10.0"])
```
Which I consider correct for the first example.
Also, using the notation below does not produce expected result
``` %gemspec_remove_dep fog-dynect %gemspec_add_dep -n fog-dynect '~> 10.0' %gemspec_add_dep -n fog-dynect '>= 10.1'
```
=>
``` s.add_dependency(%q<fog-dynect>, ["~> 10.0"])
```
FTR, in case of the non-named-variable-macro version (without '-n') the result is correct.
As I promised, this is implementation with the '-n' parameter:
%define gemspec_add_runtime_dependency(n:) \ read -d '' add_runtime_dependency_script << 'EOR' || : \ name = '%{-n*}' \ version = %{*} \ spec = Gem::Specification.load('.%{gem_spec}') \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write '.%{gem_spec}', spec.to_ruby \ EOR\ echo "$add_runtime_dependency_script" | ruby \ %{nil}
The above can be also written as
``` %define gemspec_add_dep(n:) \ echo ' \ name = %q<%{-n*}> \ version = %{*} \ spec = Gem::Specification.load(%q<.%{gem_spec}>) \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write %q<.%{gem_spec}>, spec.to_ruby \ ' | ruby %{nil}
```
I was not sure whether I could use double quotes instead of single ones
``` echo " \
...
" | ruby
```
therefore I have used the %q< ... > notation in the ruby code instead.
It is a bit more flexible, since what is following behind the name of the dependency is pasted directly into Ruby code, so either ```['~> 10.0', '>= 10.1']``` or '~> 10.0' are viable options. IOW, it must be valid ruby code, otherwise the script bails out with error. E.g. for
%gemspec_add_runtime_dependency -n fog-dynect ~> 10.0
the following error is reported:
+ read -d '' add_runtime_dependency_script + : + echo 'name = '\''fog-dynect'\'' version = ~> 10.0 spec = Gem::Specification.load('\''./usr/share/gems/specifications/fog-1.38.0.gemspec'\'') dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } if dep dep.requirement.concat version else spec.add_runtime_dependency name, version end File.write '\''./usr/share/gems/specifications/fog-1.38.0.gemspec'\'', spec.to_ruby' + ruby -:2: syntax error, unexpected '>' version = ~> 10.0 ^
Vít _______________________________________________ ruby-sig mailing list ruby-sig@lists.fedoraproject.org https://lists.fedoraproject.org/admin/lists/ruby-sig@lists.fedoraproject.org
Pavel Valena Associate Software Engineer Brno, Czech Republic
RED HAT | TRIED. TESTED. TRUSTED. All of the airlines in the Fortune Global 500 rely on Red Hat. Find out why at Trusted | Red Hat
Dne 15.9.2016 v 20:12 Pavel Valena napsal(a):
----- Original Message -----
From: "Vít Ondruch" vondruch@redhat.com To: ruby-sig@lists.fedoraproject.org Sent: Thursday, September 15, 2016 2:00:59 PM Subject: Re: Macros to modify gem dependencies
Dne 15.9.2016 v 10:06 Vít Ondruch napsal(a):
BTW this is first draft of the macros. I am going to try second implementation, which will probably need to use a bit different syntax for macro calls, but it might replace the 3 lines usage example above with 2 lines version:
%gemspec_remove_runtime_dependency -n fog-dynect %gemspec_add_runtime_dependency -n fog-dynect ['~> 10.0', '>= 10.1']
The above gives me strange result in gemspec
s.add_runtime_dependency(%q<fog-dynect>, [">= 10.1", ">= 10.1", "~> 10.0"])
Unless you fixed "gemspec_remove_runtime_dependency" by yourself, it does not support the -n parameter yet, hence the dependency is not cleaned up prior adding new dependencies.
However,
%gemspec_add_dep -n fog-dynect '~> 10.0'
results in
s.add_dependency(%q<fog-dynect>, [">= 10.1", "~> 10.0"])
Which I consider correct for the first example.
Also, using the notation below does not produce expected result
%gemspec_remove_dep fog-dynect %gemspec_add_dep -n fog-dynect '~> 10.0' %gemspec_add_dep -n fog-dynect '>= 10.1'
=>
s.add_dependency(%q<fog-dynect>, ["~> 10.0"])
FTR, in case of the non-named-variable-macro version (without '-n') the result is correct.
As I promised, this is implementation with the '-n' parameter:
%define gemspec_add_runtime_dependency(n:) \ read -d '' add_runtime_dependency_script << 'EOR' || : \ name = '%{-n*}' \ version = %{*} \ spec = Gem::Specification.load('.%{gem_spec}') \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write '.%{gem_spec}', spec.to_ruby \ EOR\ echo "$add_runtime_dependency_script" | ruby \ %{nil}
The above can be also written as
%define gemspec_add_dep(n:) \ echo ' \ name = %q<%{-n*}> \ version = %{*} \ spec = Gem::Specification.load(%q<.%{gem_spec}>) \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write %q<.%{gem_spec}>, spec.to_ruby \ ' | ruby %{nil}
Yes, you can write it like this, but you have to be careful about the usage later, e.g. the example you have used above:
``` %gemspec_add_dep -n fog-dynect '~> 10.0' ```
is probably reason for the issues you have described. If checked the log output correctly, you would see following output:
``` + echo ' name = %q<fog-dynect> version = ~' /var/tmp/rpm-tmp.4CWGoP: line 71: 10.0 spec = Gem::Specification.load(%q<./usr/share/gems/specifications/fog-1.38.0.gemspec>)
dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } if dep dep.requirement.concat version else spec.add_runtime_dependency name, version end File.write %q<./usr/share/gems/specifications/fog-1.38.0.gemspec>, spec.to_ruby : No such file or directory + ruby
```
The correct usage for this would be:
``` %gemspec_add_dep -n fog-dynect "~> 10.0" ```
IOW please note the single vs double quotes ...
Vít
----- Original Message -----
From: "Vít Ondruch" vondruch@redhat.com To: ruby-sig@lists.fedoraproject.org Sent: Friday, September 16, 2016 9:52:10 AM Subject: Re: Macros to modify gem dependencies
Dne 15.9.2016 v 20:12 Pavel Valena napsal(a):
----- Original Message -----
From: "Vít Ondruch" vondruch@redhat.com To: ruby-sig@lists.fedoraproject.org Sent: Thursday, September 15, 2016 2:00:59 PM Subject: Re: Macros to modify gem dependencies
Dne 15.9.2016 v 10:06 Vít Ondruch napsal(a):
BTW this is first draft of the macros. I am going to try second implementation, which will probably need to use a bit different syntax for macro calls, but it might replace the 3 lines usage example above with 2 lines version:
%gemspec_remove_runtime_dependency -n fog-dynect %gemspec_add_runtime_dependency -n fog-dynect ['~> 10.0', '>= 10.1']
The above gives me strange result in gemspec
s.add_runtime_dependency(%q<fog-dynect>, [">= 10.1", ">= 10.1", "~> 10.0"])
Unless you fixed "gemspec_remove_runtime_dependency" by yourself, it does not support the -n parameter yet, hence the dependency is not cleaned up prior adding new dependencies.
I have used the version of remove without '-n'. This should be ok, AFAIK.
However,
%gemspec_add_dep -n fog-dynect '~> 10.0'
results in
s.add_dependency(%q<fog-dynect>, [">= 10.1", "~> 10.0"])
Which I consider correct for the first example.
Also, using the notation below does not produce expected result
%gemspec_remove_dep fog-dynect %gemspec_add_dep -n fog-dynect '~> 10.0' %gemspec_add_dep -n fog-dynect '>= 10.1'
=>
s.add_dependency(%q<fog-dynect>, ["~> 10.0"])
FTR, in case of the non-named-variable-macro version (without '-n') the result is correct.
As I promised, this is implementation with the '-n' parameter:
%define gemspec_add_runtime_dependency(n:) \ read -d '' add_runtime_dependency_script << 'EOR' || : \ name = '%{-n*}' \ version = %{*} \ spec = Gem::Specification.load('.%{gem_spec}') \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write '.%{gem_spec}', spec.to_ruby \ EOR\ echo "$add_runtime_dependency_script" | ruby \ %{nil}
The above can be also written as
%define gemspec_add_dep(n:) \ echo ' \ name = %q<%{-n*}> \ version = %{*} \ spec = Gem::Specification.load(%q<.%{gem_spec}>) \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write %q<.%{gem_spec}>, spec.to_ruby \ ' | ruby %{nil}
Yes, you can write it like this, but you have to be careful about the usage later, e.g. the example you have used above:
%gemspec_add_dep -n fog-dynect '~> 10.0'
is probably reason for the issues you have described. If checked the log output correctly, you would see following output:
I have used your original code while getting that error. The results should be completely same- I have done some tests and I haven't found any results which differ.
Especially the single quotes do not cause any problems AFAIK.
+ echo ' name = %q<fog-dynect> version = ~' /var/tmp/rpm-tmp.4CWGoP: line 71: 10.0 spec = Gem::Specification.load(%q<./usr/share/gems/specifications/fog-1.38.0.gemspec>) dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } if dep dep.requirement.concat version else spec.add_runtime_dependency name, version end File.write %q<./usr/share/gems/specifications/fog-1.38.0.gemspec>, spec.to_ruby : No such file or directory + ruby
The correct usage for this would be:
%gemspec_add_dep -n fog-dynect "~> 10.0"
IOW please note the single vs double quotes ...
Vít
ruby-sig mailing list ruby-sig@lists.fedoraproject.org https://lists.fedoraproject.org/admin/lists/ruby-sig@lists.fedoraproject.org
</snip>
is probably reason for the issues you have described. If checked the log output correctly, you would see following output:
As Vít has pointed out to me, I have done the tests while I did not comment out the macros properly, which led to invalid results. Sorry for misleading info.
P.
I have used your original code while getting that error. The results should be completely same- I have done some tests and I haven't found any results which differ.
Especially the single quotes do not cause any problems AFAIK.
+ echo ' name = %q<fog-dynect> version = ~' /var/tmp/rpm-tmp.4CWGoP: line 71: 10.0 spec = Gem::Specification.load(%q<./usr/share/gems/specifications/fog-1.38.0.gemspec>) dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } if dep dep.requirement.concat version else spec.add_runtime_dependency name, version end File.write %q<./usr/share/gems/specifications/fog-1.38.0.gemspec>, spec.to_ruby : No such file or directory + ruby
The correct usage for this would be:
%gemspec_add_dep -n fog-dynect "~> 10.0"
IOW please note the single vs double quotes ...
Vít
ruby-sig mailing list ruby-sig@lists.fedoraproject.org https://lists.fedoraproject.org/admin/lists/ruby-sig@lists.fedoraproject.org
Hi,
for inspiration: maven packages are using these macros:
%pom_add_dep %pom_add_plugin %pom_remove_dep %pom_remove_plugin
What about similar shorter names for gems?:
%gemspec_add_dep %gemspec_remove_dep
Just an idea. There wouldn't be clear the macros are changing runtime dependency...
Frantisek
Vít Ondruch píše v Čt 15. 09. 2016 v 10:06 +0200:
Hi,
From time to time, it is necessary to modify the gem dependencies we ship. For example, it is good idea to remove the Mac/Windows specific dependencies from Listen gem or sometimes it is necessary to relax some gem dependency. Historically, we did that using sed or applying patches. I don't think neither is optimal solution. So lately, I was thinking about introducing macros to achieve this.
I am thinking about two macros ATM and here is their implementation:
%global gemspec_add_runtime_dependency() \ read -d '' add_runtime_dependency_script << 'EOR' || : \ options = %w(%{*}) \ name = options.shift \ version = [options.join(' ')] \ spec = Gem::Specification.load('.%{gem_spec}') \ dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } \ if dep \ dep.requirement.concat version \ else \ spec.add_runtime_dependency name, version \ end \ File.write '.%{gem_spec}', spec.to_ruby \ EOR\ echo "$add_runtime_dependency_script" | ruby\ %{nil} %global gemspec_remove_runtime_dependency() \ ruby \\\ -e "name = '%{1}'" \\\ -e "spec = Gem::Specification.load('.%{gem_spec}')" \\\ -e "spec.dependencies.reject! { |d| d.type == :runtime && d.name == name }" \\\ -e "File.write '.%{gem_spec}', spec.to_ruby" \ %{nil}
and you can use them as:
%gemspec_remove_runtime_dependency fog-dynect %gemspec_add_runtime_dependency fog-dynect ~> 10.0 %gemspec_add_runtime_dependency fog-dynect >= 10.1
As you can see, both are using a bit different way of implementation. Let me discuss the details.
The 'gemspec_remove_runtime_dependency' is using bunch of '-e' parameters to specify the code. The advantage of this approach is, that the build output log contains traces of the precise command which was used, e.g.:
+ ruby -e 'name = '\''fog-dynect'\''' -e 'spec = Gem::Specification.load('\''./usr/share/gems/specifications/fog- 1.38.0.gemspec'\'')' -e 'spec.dependencies.reject! { |d| d.type == :runtime && d.name == name }' -e 'File.write '\''./usr/share/gems/specifications/fog-1.38.0.gemspec'\'', spec.to_ruby'
This is helpful, but the output is not very nice and the implementation is polluted with a lot of noise.
The other approach used in 'gemspec_add_runtime_dependency' puts the entire script into environment variable and then pipes it into the ruby. The log output looks like:
+ read -d '' add_runtime_dependency_script + : + echo 'options = %w(fog-dynect >= 10.1) name = options.shift version = [options.join('\'' '\'')] spec = Gem::Specification.load('\''./usr/share/gems/specifications/fog- 1.38.0.gemspec'\'') dep = spec.dependencies.detect { |d| d.type == :runtime && d.name == name } if dep dep.requirement.concat version else spec.add_runtime_dependency name, version end File.write '\''./usr/share/gems/specifications/fog- 1.38.0.gemspec'\'', spec.to_ruby' + ruby
Is this actually useful? Of course, the script could be piped directly into ruby without the env variable magic, but the output is then reduced just to:
+ ruby
which is not helpful at all (but could be improved by some hint as "adding dependency ....").
So what is you opinion on usefulness of these macros and on the implementation? What is the preferred way for you?
BTW this is first draft of the macros. I am going to try second implementation, which will probably need to use a bit different syntax for macro calls, but it might replace the 3 lines usage example above with 2 lines version:
%gemspec_remove_runtime_dependency -n fog-dynect %gemspec_add_runtime_dependency -n fog-dynect ['~> 10.0', '>= 10.1']
Please share your thoughts on this topic.
Vít
ruby-sig mailing list ruby-sig@lists.fedoraproject.org https://lists.fedoraproject.org/admin/lists/ruby-sig@lists.fedoraproj ect.org
Dne 15.9.2016 v 14:53 František Dvořák napsal(a):
Hi,
for inspiration: maven packages are using these macros:
%pom_add_dep %pom_add_plugin %pom_remove_dep %pom_remove_plugin
What about similar shorter names for gems?:
%gemspec_add_dep %gemspec_remove_dep
Just an idea. There wouldn't be clear the macros are changing runtime dependency...
You are right, the shorter version might be better.
Thinking about the runtime part, is it actually relevant information? Will we ever change development dependency? If yes, may be something like additional '-d' option would be better ...
Thx for the feedback!
Vít
tl;dr
I updated the macros and here are some highlights:
* The macro names were shorten according to František's suggestion and I added the -d flag in case you want to work with development dependencies. * By default, they work on ./%{gem_name}.spec, i.e. the unpacked .gemspec or you can specify custom path via -s parameter * The -g parameter now specifies the name of the dependency * The remaining options should be something which can be handled by Ruby and they should specify the version(s) (see the examples bellow). * When removing the dependency, the -g parameter specifying the dependency name must always be found in the .gemspec otherwise the macro fails. This makes sure that if something is changed in the .gemspec, it will be brought to your attention. * For similar reasons, if you optionally specify the precise versions, they have to be available in .gemspec, otherwise the remove macro fails.
So here is the latest version of the macros:
``` # The 'read' command not essential, but it is usefull to make the sript # appear in build log.
# Add dependency named gem with requirements to .gemspec. It adds runtime # dependency by default. # -g<gem> Specifies name of the gem dependency. # -s<gemspec_file> Overrides the default .gemspec location. # -d Add development dependecy. # # The remaining arguments are expected to by requirements and should be # valid Ruby code. %define gemspec_add_dep(g:s:d) \ read -d '' gemspec_add_dep_script << 'EOR' || : \ gemspec_file = '%{-s*}%{!?-s:./%{gem_name}.spec}' \ \ name = '%{-g*}' \ requirements = %{*}%{!?1:nil} \ \ type = :%{!?-d:runtime}%{?-d:development} \ \ spec = Gem::Specification.load(gemspec_file) \ abort("#{gemspec_file} is not accessible.") unless spec \ \ dep = spec.dependencies.detect { |d| d.type == type && d.name == name } \ if dep \ dep.requirement.concat requirements \ else \ spec.public_send "add_#{type}_dependency", name, requirements \ end \ File.write gemspec_file, spec.to_ruby \ EOR\ echo "$gemspec_add_dep_script" | ruby \ unset -v gemspec_add_dep_script \ %{nil}
# Remove dependency named gem with requirements to .gemspec. It adds runtime # dependency by default. # -g<gem> Specifies name of the gem dependency. # -s<gemspec_file> Overrides the default .gemspec location. # -d Remove development dependecy. # # If remaing arguments specify some version requirements, the macro fails if # these specific requirements can't be removed. %define gemspec_remove_dep(g:s:d) \ read -d '' gemspec_remove_dep_script << 'EOR' || : \ gemspec_file = '%{-s*}%{!?-s:./%{gem_name}.spec}' \ \ name = '%{-g*}' \ requirements = %{*}%{!?1:nil} \ \ type = :%{!?-d:runtime}%{?-d:development} \ \ spec = Gem::Specification.load(gemspec_file) \ abort("#{gemspec_file} is not accessible.") unless spec \ \ dep = spec.dependencies.detect { |d| d.type == type && d.name == name } \ if dep \ if requirements \ requirements = Gem::Requirement.create(requirements).requirements \ requirements.each do |r| \ unless dep.requirement.requirements.reject! { |dependency_requirements| dependency_requirements == r } \ abort("Requirement '#{r.first} #{r.last}' for dependency '#{name}' was not found!") \ end \ end \ else \ dep = spec.dependencies.delete dep \ end \ else \ abort("Dependency '#{name}' was not found!") \ end \ File.write '.%{gem_spec}', spec.to_ruby \ EOR\ echo "$gemspec_remove_dep_script" | ruby \ unset -v gemspec_remove_dep_script \ %{nil}
```
You can used them as follows:
``` %gemspec_add_dep -s ./usr/share/gems/specifications/fog-1.38.0.gemspec -g fog-dynect ['~> 10.0', '>= 10.1.1'] %gemspec_remove_dep -s ./usr/share/gems/specifications/fog-1.38.0.gemspec -g fog-dynect '~> 10.0' %gemspec_add_dep -s ./usr/share/gems/specifications/fog-1.38.0.gemspec -g fog-dynect '~> 10.0' %gemspec_remove_dep -s ./usr/share/gems/specifications/fog-1.38.0.gemspec -g fog-dynect ```
Vít
ruby-sig@lists.fedoraproject.org