diff --git a/Rakefile b/Rakefile index 7838b6209d3562a78c37ba58a6f99dcd62528aa9..4bc8a534db5cde5c4e297adce19a8caba647e22a 100644 --- a/Rakefile +++ b/Rakefile @@ -233,6 +233,10 @@ task :sdk => :sass do "--output", OUT_DIR, "--config", "#{SDK_DIR}/extjs/docs/config.json", "--examples-base-url", "extjs-build/examples/", + "--old-version", "2.3.0:compare/ext23", + "--old-version", "3.4.0:compare/ext34", + "--old-version", "4.0.7:compare/ext407", + "--old-version", "4.1.1", "--seo", "--tests" ) diff --git a/lib/jsduck/app.rb b/lib/jsduck/app.rb index 001ca607c4227c6cc09baa5b81df1e8787384b6c..822560271e02597bfa216953a5f7e5ab37e24bc3 100644 --- a/lib/jsduck/app.rb +++ b/lib/jsduck/app.rb @@ -11,6 +11,7 @@ require 'jsduck/logger' require 'jsduck/assets' require 'jsduck/json_duck' require 'jsduck/io' +require 'jsduck/old_versions' require 'jsduck/lint' require 'jsduck/template_dir' require 'jsduck/class_writer' @@ -46,6 +47,7 @@ module JsDuck result = aggregate(parsed_files) @relations = filter_classes(result) InheritDoc.new(@relations).resolve_all + OldVersions.import(@opts.old_versions, @relations) Lint.new(@relations).run # Initialize guides, videos, examples, ... diff --git a/lib/jsduck/old_versions.rb b/lib/jsduck/old_versions.rb new file mode 100644 index 0000000000000000000000000000000000000000..4a2d4909012e7febc930fdb684a8e95ab51c0b97 --- /dev/null +++ b/lib/jsduck/old_versions.rb @@ -0,0 +1,71 @@ +require 'jsduck/json_duck' +require 'jsduck/null_object' + +module JsDuck + + # Reads in JSDuck exports of different versions of docs. + module OldVersions + module_function + + # Loads in exported docs and generates @since tags based on that data. + def import(versions, relations) + generate_since_tags(read_all(versions), relations) + end + + # Reads in data for all versions, returning array of + # version/class-data pairs. We don't use a hash to preserve the + # order of versions (from oldest to newest). + def read_all(versions) + versions.map do |ver| + { + :version => ver[:version], + :classes => ver[:path] ? read(ver[:path]) : current_version, + } + end + end + + def current_version + NullObject.new(:[] => {}) + end + + # Reads in data from all .json files in directory + def read(path) + classes = {} + Dir[path + "/*.json"].each do |filename| + json = JsonDuck.read(filename) + classes[json["name"]] = members_id_index(json) + end + classes + end + + # creates index of all class members + def members_id_index(json) + index = {} + ["members", "statics"].each do |group_name| + json[group_name].each_pair do |tagname, members| + members.each do |m| + index[m["id"]] = true + end + end + end + index + end + + # Using the imported versions data, adds @since tags to all + # classes/members. + def generate_since_tags(versions, relations) + relations.each do |cls| + cls[:meta][:since] = available_since(versions, cls[:name]) + end + end + + # Returns name of the version since which the class is available + def available_since(versions, class_name) + versions.each do |ver| + return ver[:version] if ver[:classes][class_name] + end + end + + end + +end diff --git a/lib/jsduck/options.rb b/lib/jsduck/options.rb index 0f1057176d119f251e401b5cfeec7c1cd5e947e5..22a9678206cfdf0d46fd166ad657cbcb1025e70d 100644 --- a/lib/jsduck/options.rb +++ b/lib/jsduck/options.rb @@ -44,6 +44,7 @@ module JsDuck attr_accessor :local_storage_db attr_accessor :touch_examples_ui attr_accessor :ext_namespaces + attr_accessor :old_versions def initialize @input_files = [] @@ -112,6 +113,7 @@ module JsDuck @local_storage_db = "docs" @touch_examples_ui = false @ext_namespaces = ["Ext"] + @old_versions = [] # enable all warnings except :link_auto Logger.instance.set_warning(:all, true) @@ -360,6 +362,16 @@ module JsDuck @ext_namespaces = ns end + opts.on('--old-version=VERSION:PATH', + "Path to exported docs of specified version.", + "For the current version, leave the path portion off.", " ") do |v| + if v =~ /\A(.*?):(.*)\Z/ + @old_versions << {:version => $1, :path => canonical($2)} + else + @old_versions << {:version => v} + end + end + opts.on('--config=PATH', "Loads config options from JSON file.", " ") do |path| path = canonical(path) diff --git a/lib/jsduck/tag/since.rb b/lib/jsduck/tag/since.rb new file mode 100644 index 0000000000000000000000000000000000000000..5e4aa243615a834911f50830d33dbe7e81cc425d --- /dev/null +++ b/lib/jsduck/tag/since.rb @@ -0,0 +1,26 @@ +require "jsduck/meta_tag" +require "jsduck/logger" + +module JsDuck::Tag + # Implementation of @since tag. + class Since < JsDuck::MetaTag + def initialize + @name = "since" + @key = :since + end + + def to_value(contents) + if contents.length > 1 + JsDuck::Logger.instance.warn(nil, "Only one @since tag allowed per class/member.") + end + contents[0] + end + + def to_html(version) + <<-EOHTML +

Available since: #{version}

+ EOHTML + end + end +end + diff --git a/spec/old_versions_spec.rb b/spec/old_versions_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..2c3325779c6c2c6419c83c412590efb8f6df2970 --- /dev/null +++ b/spec/old_versions_spec.rb @@ -0,0 +1,42 @@ +require "jsduck/old_versions" + +describe "JsDuck::OldVersions#generate_since_tags" do + + before do + @versions = [ + { + :version => "1.0", :classes => { + "VeryOldClass" => {}, + }, + }, + { + :version => "2.0", :classes => { + "VeryOldClass" => {}, + "OldClass" => {}, + }, + }, + { + :version => "3.0", :classes => JsDuck::OldVersions.current_version + } + ] + @relations = [ + {:name => "VeryOldClass", :meta => {}}, + {:name => "OldClass", :meta => {}}, + {:name => "NewClass", :meta => {}}, + ] + JsDuck::OldVersions.generate_since_tags(@versions, @relations) + end + + it "adds @since 1.0 to VeryOldClass" do + @relations[0][:meta][:since].should == "1.0" + end + + it "adds @since 2.0 to OldClass" do + @relations[1][:meta][:since].should == "2.0" + end + + it "adds @since 3.0 to NewClass" do + @relations[2][:meta][:since].should == "3.0" + end + +end