[Rubygems-developers] Overhaul of specification.rb

Gavin Sinclair gsinclair at soyabean.com.au
Sun Aug 1 10:56:53 EDT 2004


I've done a lot of work on specification.rb.  The motivation was to
organise the code a bit better, and give special treatment to all
gemspec attributes to prevent repitition.  I wanted to add
'library_stubs' and 'test_files' attributes, and deprecate
'test_suite_file', but also to ensure that the overall code was
written and tested well.

Here's the relevant part of the ChangeLog:

    2004-08-01  Gavin Sinclair  <gsinclair at soyabean.com.au>

        * lib/rubygems/specification.rb:
          - (Re)defined class methods: attribute, attributes,
            required_attribute, read_only, overwrite_accessor.  @@attributes
            contains a list of attribute names and default values.  This
            allows higher-level specification of gemspec attributes, and the
            handling of them in a DRY fashion.

          - to_yaml_properties now includes all properties, to ensure
            correct deserialization of a Gem::Specification object.

          - #to_ruby and #to_yaml_properties rewritten to use @@attributes

          - Introduced 'specification_version' attribute and three constants:
            SPECIFICATION_VERSION_HISTORY.  This allows us to track changes to
            the spec format.

          - Refactored several "helper" methods, using the new class method
            'attribute_alias_singular', which provides a "singular" alias for
            a "plural" attribute (e.g. require_path and require_paths).

          - All gemspec attributes now defined in a uniform fashion, which
            implies that they all have valid instance variables on
            initialization.  Previously, some attributes were lazily

          - Introduced attribute 'library_stubs', to allow the specification
            of several stub files.  (That feature not implemented, though.)

          - Introduced attribute 'test_files' and deprecated 'test_suite_file'.

          - Provided #warn_deprecated stub of a method, but don't know what to
            do with it.

          - Deprecated #has_test_suite? in favour of (new) #has_unit_tests?

          - Used overwrite_accessor to provide special behaviour for the
            setting of some attributes.

          - The 'date' attribute is now a Date object.  We don't need high
            resolution, and Time objects, being system-dependent, are not nice
            to deal with.

          - Various code style changes.

          - Summary: uniform treatment of gemspec attributes; reduced code by
            refactoring; 'test_suite_file' deprecated for 'test_files';
            'library_stubs' introduced; spec versioning introduced.

        * test/test_specification.rb: several new tests: _singular_attributes,
          _deprecated_attributes, _defaults, _to_{yaml,ruby}_and_back,
          _directly_setting_dependencies_doesnt_work, and more.  Plus a new
          class to give Specification a more thorough workout (TestSpecificationComplex).

Sorry about the massive amount all at once :)

Discussion points:

 * Should Specification#initialize call #normalize at the end?  I'd
   like it to.

 * Two tests are failing at the moment, both in test_format.rb.  They
   don't seem critical, and are probably related to the data they
   load, which I'm loath to touch because it's testing the old format.
   So I'm not sure if or how the test should change.

 * Need to test the specification versioning mechanism, but first we
   need some discussion on whether this mechanism is worthwhile, how
   it "works", and how to inter-operate with older gemspecs.

 * Is there a desire for warning about the use of deprecated
   attributes, and is there a sensible way to do it?  We'd want to
   warn only when building a gem (if at all).

 * The change that reads
          - to_yaml_properties now includes all properties, to ensure
            correct deserialization of a Gem::Specification object.
   is kind of annoying.  Is there a way to properly initialize objects
   when they are being deserialized from YAML?

 * Please check the block of code beginning at line 205.  There's a
   comment, and some code, both of which predate my changes, but I
   don't think they match, and I don't know what the correct behaviour
   should be.


More information about the Rubygems-developers mailing list