File: documentation.rb

package info (click to toggle)
ruby-shoulda-matchers 7.0.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,652 kB
  • sloc: ruby: 34,046; sh: 280; makefile: 9
file content (218 lines) | stat: -rw-r--r-- 6,137 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
require 'shoulda/matchers/version'
require 'erb'

module Shoulda
  module Matchers
    module DocumentationTasks
      extend Rake::DSL

      def self.create # rubocop:disable Metrics/MethodLength
        publisher = DocumentationPublisher.new

        namespace :docs do
          file DocumentationPublisher.gh_pages_dir do
            publisher.create_reference_to_gh_pages_branch
          end

          file DocumentationPublisher.docs_dir =>
            DocumentationPublisher.gh_pages_dir

          task setup: DocumentationPublisher.docs_dir do
            publisher.reset_repo_directory
          end

          desc 'Generate docs for a particular version'
          task :generate, [:version, :latest_version] => :setup do |_t, args|
            unless args.version
              raise ArgumentError, 'Missing version'
            end

            unless args.latest_version
              raise ArgumentError, 'Missing latest_version'
            end

            publisher.generate_docs_for(
              args.version,
              latest_version: args.latest_version,
            )
          end

          desc 'Watch source files for this project for changes and'\
            ' autogenerate docs accordingly'
          task :autogenerate do
            require 'fssm'

            project_directory = File.expand_path("#{File.dirname(__FILE__)}/..")

            regenerate_docs = proc do
              print 'Regenerating docs... '
              if system('bundle exec yard doc &>/dev/null')
                puts 'done!'
              else
                print "\nCould not regenerate docs!!"
              end
            end

            regenerate_docs.call

            puts 'Waiting for documentation files to change...'

            FSSM.monitor do
              path project_directory do
                glob '{README.md,CHANGELOG.md,.yardopts,docs/**/*.md,'\
                  'doc_config/yard/**/*.{rb,js,css,erb},lib/**/*.rb}'
                create(&regenerate_docs)
                update(&regenerate_docs)
              end
            end
          end

          desc 'Generate docs for a particular version and push them to GitHub'
          task :publish, [:version, :latest_version] => :setup do |_t, args|
            unless args.version
              raise ArgumentError, 'Missing version'
            end

            unless args.latest_version
              raise ArgumentError, 'Missing latest_version'
            end

            publisher.generate_docs_for(
              args.version,
              latest_version: args.latest_version,
            )
            publisher.publish_docs_for(
              args.version,
              latest_version: args.latest_version,
            )
          end

          desc 'Generate docs for version'\
            " #{DocumentationPublisher.current_version} and push them to GitHub"
          task publish_latest: :setup do
            publisher.publish_latest_version
          end
        end
      end
    end

    class DocumentationPublisher
      CURRENT_VERSION = Shoulda::Matchers::VERSION
      GITHUB_USERNAME = 'thoughtbot'.freeze
      # GITHUB_USERNAME = 'mcmire'
      GH_PAGES_DIR = ".#{GITHUB_USERNAME}-gh-pages".freeze
      DOCS_DIR = "#{GH_PAGES_DIR}/docs".freeze

      def self.current_version
        CURRENT_VERSION
      end

      def self.gh_pages_dir
        GH_PAGES_DIR
      end

      def self.docs_dir
        DOCS_DIR
      end

      def create_reference_to_gh_pages_branch
        system "git clone git@github.com:#{GITHUB_USERNAME}"\
          "/shoulda-matchers.git #{GH_PAGES_DIR} --branch gh-pages"
      end

      def reset_repo_directory
        within_gh_pages_dir do
          system 'git fetch origin'
          system 'git reset --hard origin/gh-pages'
        end
      end

      def generate_docs_for(version, options = {})
        ref = determine_ref_from(version)

        system "rm -rf #{DOCS_DIR}/#{ref}"
        system "bundle exec yard -o #{DOCS_DIR}/#{ref}"

        add_version_to_index_page_for(ref, version)

        within_docs_dir do
          system "git add #{ref}"
        end

        if options[:latest_version]
          generate_file_that_redirects_to_latest_version(
            options[:latest_version],
          )
        end
      end

      def publish_docs_for(version, _options = {})
        message = build_commit_message(version)

        within_gh_pages_dir do
          system 'git clean -f'
          system "git commit -m '#{message}'"
          system 'git push origin gh-pages'
        end
      end

      def publish_latest_version
        version = Gem::Version.new(CURRENT_VERSION)
        options = {}

        unless version.prerelease?
          options[:latest_version] = version.to_s
        end

        generate_docs_for(CURRENT_VERSION, options)
        publish_docs_for(CURRENT_VERSION, options)
      end

      private

      def add_version_to_index_page_for(ref, version)
        within_docs_dir do
          filename = "#{ref}/index.html"
          content = File.read(filename)
          content.sub!(
            %r{<h1>shoulda-matchers.+</h1>},
            "<h1>shoulda-matchers (#{version})</h1>",
          )
          File.open(filename, 'w') {|f| f.write(content) }
        end
      end

      def generate_file_that_redirects_to_latest_version(version)
        ref = determine_ref_from(version)
        locals = { ref:, github_username: GITHUB_USERNAME }

        erb = ERB.new(File.read('doc_config/gh-pages/index.html.erb'))

        within_docs_dir do
          File.open('index.html', 'w') { |f| f.write(erb.result(binding)) }
          system 'git add index.html'
        end
      end

      def determine_ref_from(version)
        if version =~ /^\d+\.\d+\.\d+/
          "v#{version}"
        else
          version
        end
      end

      def build_commit_message(version)
        "Regenerated docs for version #{version}"
      end

      def within_gh_pages_dir(&block)
        Dir.chdir(GH_PAGES_DIR, &block)
      end

      def within_docs_dir(&block)
        Dir.chdir(DOCS_DIR, &block)
      end
    end
  end
end