cutting_edge 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/Gemfile +10 -0
 - data/LICENSE +674 -0
 - data/README.md +95 -0
 - data/Rakefile +159 -0
 - data/bin/cutting_edge +72 -0
 - data/cutting_edge.gemspec +57 -0
 - data/lib/cutting_edge.rb +3 -0
 - data/lib/cutting_edge/app.rb +77 -0
 - data/lib/cutting_edge/badge.rb +46 -0
 - data/lib/cutting_edge/langs.rb +123 -0
 - data/lib/cutting_edge/langs/python.rb +102 -0
 - data/lib/cutting_edge/langs/ruby.rb +47 -0
 - data/lib/cutting_edge/langs/rust.rb +68 -0
 - data/lib/cutting_edge/repo.rb +67 -0
 - data/lib/cutting_edge/versions.rb +46 -0
 - data/lib/cutting_edge/workers/badge.rb +22 -0
 - data/lib/cutting_edge/workers/dependency.rb +100 -0
 - data/lib/cutting_edge/workers/helpers.rb +24 -0
 - data/spec/langs/python_spec.rb +89 -0
 - data/spec/langs/rust_spec.rb +81 -0
 - data/spec/spec_helper.rb +111 -0
 - metadata +191 -0
 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,95 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            [](https://travis-ci.org/repotag/cutting_edge)
         
     | 
| 
      
 2 
     | 
    
         
            +
            [](https://coveralls.io/github/repotag/cutting_edge?branch=master)
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # CuttingEdge
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            ## Sinatra App
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            * start the app with `bundle exec ruby lib/app.rb`
         
     | 
| 
      
 9 
     | 
    
         
            +
            * Runs on http://localhost:4567
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Routes under `/source/org/name`
         
     | 
| 
      
 11 
     | 
    
         
            +
              * For example: http://localhost:4567/github/gollum/gollum/info
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ## DependencyWorker
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            The DependencyWorker currently performs the following actions:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            * Fetch gemfile and gemspec for a given Gem
         
     | 
| 
      
 18 
     | 
    
         
            +
              * Currently, the `GithubGem` class specifies the needed information for a gem hosted on github, ditto for the `GitlabGem` class for gitlab.
         
     | 
| 
      
 19 
     | 
    
         
            +
              * These are subclasses of `RepositoryGem`.
         
     | 
| 
      
 20 
     | 
    
         
            +
            * Parse both files for dependency requirements
         
     | 
| 
      
 21 
     | 
    
         
            +
              * Does not bork if either of the files could not be retrieved.
         
     | 
| 
      
 22 
     | 
    
         
            +
            * Determine the latest version for each required gem
         
     | 
| 
      
 23 
     | 
    
         
            +
              * By querying rubygems for a version of the gem `>= 0`.
         
     | 
| 
      
 24 
     | 
    
         
            +
            * Generate a Hash of results of the following form:
         
     | 
| 
      
 25 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 26 
     | 
    
         
            +
            {:gemspec=>
         
     | 
| 
      
 27 
     | 
    
         
            +
              {:outdated_major=>
         
     | 
| 
      
 28 
     | 
    
         
            +
                [{:name=>"kramdown",
         
     | 
| 
      
 29 
     | 
    
         
            +
                  :required=>"~> 1.9.0",
         
     | 
| 
      
 30 
     | 
    
         
            +
                  :latest=>"2.1.0",
         
     | 
| 
      
 31 
     | 
    
         
            +
                  :type=>:runtime},
         
     | 
| 
      
 32 
     | 
    
         
            +
                 {:name=>"sinatra",
         
     | 
| 
      
 33 
     | 
    
         
            +
                  :required=>"~> 1.4, >= 1.4.4",
         
     | 
| 
      
 34 
     | 
    
         
            +
                  :latest=>"2.0.8.1",
         
     | 
| 
      
 35 
     | 
    
         
            +
                  :type=>:runtime},
         
     | 
| 
      
 36 
     | 
    
         
            +
                 {:name=>"mustache",
         
     | 
| 
      
 37 
     | 
    
         
            +
                  :required=>">= 0.99.5, < 1.0.0",
         
     | 
| 
      
 38 
     | 
    
         
            +
                  :latest=>"1.1.1",
         
     | 
| 
      
 39 
     | 
    
         
            +
                  :type=>:runtime},
         
     | 
| 
      
 40 
     | 
    
         
            +
                 {:name=>"gemojione",
         
     | 
| 
      
 41 
     | 
    
         
            +
                  :required=>"~> 3.2",
         
     | 
| 
      
 42 
     | 
    
         
            +
                  :latest=>"4.3.2",
         
     | 
| 
      
 43 
     | 
    
         
            +
                  :type=>:runtime}],
         
     | 
| 
      
 44 
     | 
    
         
            +
               :outdated_minor=>[],
         
     | 
| 
      
 45 
     | 
    
         
            +
               :outdated_bump=>[],
         
     | 
| 
      
 46 
     | 
    
         
            +
               :ok=>
         
     | 
| 
      
 47 
     | 
    
         
            +
                [{:name=>"gollum-lib",
         
     | 
| 
      
 48 
     | 
    
         
            +
                  :required=>"~> 4.2, >= 4.2.10",
         
     | 
| 
      
 49 
     | 
    
         
            +
                  :latest=>"4.2.10",
         
     | 
| 
      
 50 
     | 
    
         
            +
                  :type=>:runtime},
         
     | 
| 
      
 51 
     | 
    
         
            +
                 {:name=>"useragent",
         
     | 
| 
      
 52 
     | 
    
         
            +
                  :required=>"~> 0.16.2",
         
     | 
| 
      
 53 
     | 
    
         
            +
                  :latest=>"0.16.10",
         
     | 
| 
      
 54 
     | 
    
         
            +
                  :type=>:runtime}],
         
     | 
| 
      
 55 
     | 
    
         
            +
               :unknown=>[]},
         
     | 
| 
      
 56 
     | 
    
         
            +
             :gemfile=>
         
     | 
| 
      
 57 
     | 
    
         
            +
              {:outdated_major=>
         
     | 
| 
      
 58 
     | 
    
         
            +
                [{:name=>"rake",
         
     | 
| 
      
 59 
     | 
    
         
            +
                  :required=>"~> 10.4",
         
     | 
| 
      
 60 
     | 
    
         
            +
                  :latest=>"13.0.1",
         
     | 
| 
      
 61 
     | 
    
         
            +
                  :type=>:runtime}],
         
     | 
| 
      
 62 
     | 
    
         
            +
               :outdated_minor=>[],
         
     | 
| 
      
 63 
     | 
    
         
            +
               :outdated_bump=>[],
         
     | 
| 
      
 64 
     | 
    
         
            +
               :ok=>[],
         
     | 
| 
      
 65 
     | 
    
         
            +
               :unknown=>[]}}
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            ```
         
     | 
| 
      
 68 
     | 
    
         
            +
            * These results are stored in a Moneta store under a key generated by `RepositoryGem#identifier` (for e.g. a `GithubGem`, the identifier will be of the form `'github/org/name'`).
         
     | 
| 
      
 69 
     | 
    
         
            +
            * The Moneta store used by the Worker is provided by the Sinatra app Class: `::CuttingEdge::App.store`.
         
     | 
| 
      
 70 
     | 
    
         
            +
              * So we must do e.g. `CuttingEdge::App.set(:store, Moneta.new(:Memory))` to set the `#store` method on the `CuttingEdge` Class.
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            ### Example use of the DependencyWorker and Gem API
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            See `test.rb` for a basic example (without Sinatra) of how the setup works. Run it with `bundle exec ruby test.rb`.
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 77 
     | 
    
         
            +
            require 'redis-objects'
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            gem = GithubGem.new('gollum', 'gollum')
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            Redis::Objects.redis = Redis.new
         
     | 
| 
      
 82 
     | 
    
         
            +
            gem_dependencies = Redis::Value.new(gem.identifier)
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            puts gem_dependencies.value # Currently nil
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            DependencyWorker.perform_async(gem.identifier, gem.gemspec_location, gem.gemfile_location) # Fire up a Sidekiq job
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            # Sleep 5
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            puts gem_dependencies.value # The JSON results hash
         
     | 
| 
      
 91 
     | 
    
         
            +
            ```
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            ## License
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            This work is licensed under the terms of the [GNU GPLv3.0](LICENSE).
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,159 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'date'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            task :default => :rspec
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            desc "Run specs."
         
     | 
| 
      
 8 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:rspec) do |spec|
         
     | 
| 
      
 9 
     | 
    
         
            +
              ruby_opts = "-w"
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.pattern = 'spec/**/*_spec.rb'
         
     | 
| 
      
 11 
     | 
    
         
            +
              spec.rspec_opts = ['--backtrace --color']
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            #############################################################################
         
     | 
| 
      
 15 
     | 
    
         
            +
            #
         
     | 
| 
      
 16 
     | 
    
         
            +
            # Helper functions
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            #############################################################################
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            def name
         
     | 
| 
      
 21 
     | 
    
         
            +
              @name ||= Dir['*.gemspec'].first.split('.').first
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            def version
         
     | 
| 
      
 25 
     | 
    
         
            +
              line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
         
     | 
| 
      
 26 
     | 
    
         
            +
              line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            # assumes x.y.z all digit version
         
     | 
| 
      
 30 
     | 
    
         
            +
            def next_version
         
     | 
| 
      
 31 
     | 
    
         
            +
              # x.y.z
         
     | 
| 
      
 32 
     | 
    
         
            +
              v = version.split '.'
         
     | 
| 
      
 33 
     | 
    
         
            +
              # bump z
         
     | 
| 
      
 34 
     | 
    
         
            +
              v[-1] = v[-1].to_i + 1
         
     | 
| 
      
 35 
     | 
    
         
            +
              v.join '.'
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            def bump_version
         
     | 
| 
      
 39 
     | 
    
         
            +
              old_file = File.read("lib/#{name}.rb")
         
     | 
| 
      
 40 
     | 
    
         
            +
              old_version_line = old_file[/^\s*VERSION\s*=\s*.*/]
         
     | 
| 
      
 41 
     | 
    
         
            +
              new_version = next_version
         
     | 
| 
      
 42 
     | 
    
         
            +
              # replace first match of old vesion with new version
         
     | 
| 
      
 43 
     | 
    
         
            +
              old_file.sub!(old_version_line, "  VERSION = '#{new_version}'")
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              File.write("lib/#{name}.rb", old_file)
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              new_version
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            def date
         
     | 
| 
      
 51 
     | 
    
         
            +
              Date.today.to_s
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            def gemspec_file
         
     | 
| 
      
 55 
     | 
    
         
            +
              "#{name}.gemspec"
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            desc "Build the gem file."
         
     | 
| 
      
 59 
     | 
    
         
            +
            task :build do
         
     | 
| 
      
 60 
     | 
    
         
            +
              system "gem build gollum_git_adapter_specs.gemspec"
         
     | 
| 
      
 61 
     | 
    
         
            +
            end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            def gem_file
         
     | 
| 
      
 64 
     | 
    
         
            +
              "#{name}-#{version}.gem"
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            def replace_header(head, header_name)
         
     | 
| 
      
 68 
     | 
    
         
            +
              head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
         
     | 
| 
      
 69 
     | 
    
         
            +
            end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            #############################################################################
         
     | 
| 
      
 72 
     | 
    
         
            +
            #
         
     | 
| 
      
 73 
     | 
    
         
            +
            # Custom tasks (add your own tasks here)
         
     | 
| 
      
 74 
     | 
    
         
            +
            #
         
     | 
| 
      
 75 
     | 
    
         
            +
            #############################################################################
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            desc "Update version number and gemspec"
         
     | 
| 
      
 78 
     | 
    
         
            +
            task :bump do
         
     | 
| 
      
 79 
     | 
    
         
            +
              puts "Updated version to #{bump_version}"
         
     | 
| 
      
 80 
     | 
    
         
            +
              # Execute does not invoke dependencies.
         
     | 
| 
      
 81 
     | 
    
         
            +
              # Manually invoke gemspec then validate.
         
     | 
| 
      
 82 
     | 
    
         
            +
              Rake::Task[:gemspec].execute
         
     | 
| 
      
 83 
     | 
    
         
            +
              Rake::Task[:validate].execute
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            #############################################################################
         
     | 
| 
      
 87 
     | 
    
         
            +
            #
         
     | 
| 
      
 88 
     | 
    
         
            +
            # Packaging tasks
         
     | 
| 
      
 89 
     | 
    
         
            +
            #
         
     | 
| 
      
 90 
     | 
    
         
            +
            #############################################################################
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            desc 'Create a release build and push to rubygems'
         
     | 
| 
      
 93 
     | 
    
         
            +
            task :release => :build do
         
     | 
| 
      
 94 
     | 
    
         
            +
              unless `git branch` =~ /^\* master$/
         
     | 
| 
      
 95 
     | 
    
         
            +
                puts "You must be on the master branch to release!"
         
     | 
| 
      
 96 
     | 
    
         
            +
                exit!
         
     | 
| 
      
 97 
     | 
    
         
            +
              end
         
     | 
| 
      
 98 
     | 
    
         
            +
              sh "git commit --allow-empty -a -m 'Release #{version}'"
         
     | 
| 
      
 99 
     | 
    
         
            +
              sh "git pull --rebase origin master"
         
     | 
| 
      
 100 
     | 
    
         
            +
              sh "git tag v#{version}"
         
     | 
| 
      
 101 
     | 
    
         
            +
              sh "git push origin master"
         
     | 
| 
      
 102 
     | 
    
         
            +
              sh "git push origin v#{version}"
         
     | 
| 
      
 103 
     | 
    
         
            +
              sh "gem push pkg/#{name}-#{version}.gem"
         
     | 
| 
      
 104 
     | 
    
         
            +
            end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            desc 'Publish to rubygems. Same as release'
         
     | 
| 
      
 107 
     | 
    
         
            +
            task :publish => :release
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            desc 'Build gem'
         
     | 
| 
      
 110 
     | 
    
         
            +
            task :build => :gemspec do
         
     | 
| 
      
 111 
     | 
    
         
            +
              sh "mkdir -p pkg"
         
     | 
| 
      
 112 
     | 
    
         
            +
              sh "gem build #{gemspec_file}"
         
     | 
| 
      
 113 
     | 
    
         
            +
              sh "mv #{gem_file} pkg"
         
     | 
| 
      
 114 
     | 
    
         
            +
            end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            desc "Build and install"
         
     | 
| 
      
 117 
     | 
    
         
            +
            task :install => :build do
         
     | 
| 
      
 118 
     | 
    
         
            +
              sh "gem install --local --no-document pkg/#{name}-#{version}.gem"
         
     | 
| 
      
 119 
     | 
    
         
            +
            end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            desc 'Update gemspec'
         
     | 
| 
      
 122 
     | 
    
         
            +
            task :gemspec => :validate do
         
     | 
| 
      
 123 
     | 
    
         
            +
              # read spec file and split out manifest section
         
     | 
| 
      
 124 
     | 
    
         
            +
              spec = File.read(gemspec_file)
         
     | 
| 
      
 125 
     | 
    
         
            +
              head, manifest, tail = spec.split("  # = MANIFEST =\n")
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              # replace name version and date
         
     | 
| 
      
 128 
     | 
    
         
            +
              replace_header(head, :name)
         
     | 
| 
      
 129 
     | 
    
         
            +
              replace_header(head, :version)
         
     | 
| 
      
 130 
     | 
    
         
            +
              replace_header(head, :date)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
              # determine file list from git ls-files
         
     | 
| 
      
 133 
     | 
    
         
            +
              files = `git ls-files`.
         
     | 
| 
      
 134 
     | 
    
         
            +
                split("\n").
         
     | 
| 
      
 135 
     | 
    
         
            +
                sort.
         
     | 
| 
      
 136 
     | 
    
         
            +
                reject { |file| file =~ /^\./ }.
         
     | 
| 
      
 137 
     | 
    
         
            +
                reject { |file| file =~ /^(rdoc|pkg|test|Home\.md|\.gitattributes)/ }.
         
     | 
| 
      
 138 
     | 
    
         
            +
                map { |file| "    #{file}" }.
         
     | 
| 
      
 139 
     | 
    
         
            +
                join("\n")
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              # piece file back together and write
         
     | 
| 
      
 142 
     | 
    
         
            +
              manifest = "  s.files = %w[\n#{files}\n  ]\n"
         
     | 
| 
      
 143 
     | 
    
         
            +
              spec = [head, manifest, tail].join("  # = MANIFEST =\n")
         
     | 
| 
      
 144 
     | 
    
         
            +
              File.open(gemspec_file, 'w') { |io| io.write(spec) }
         
     | 
| 
      
 145 
     | 
    
         
            +
              puts "Updated #{gemspec_file}"
         
     | 
| 
      
 146 
     | 
    
         
            +
            end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            desc 'Validate lib files and version file'
         
     | 
| 
      
 149 
     | 
    
         
            +
            task :validate do
         
     | 
| 
      
 150 
     | 
    
         
            +
              libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
         
     | 
| 
      
 151 
     | 
    
         
            +
              unless libfiles.empty?
         
     | 
| 
      
 152 
     | 
    
         
            +
                puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
         
     | 
| 
      
 153 
     | 
    
         
            +
                exit!
         
     | 
| 
      
 154 
     | 
    
         
            +
              end
         
     | 
| 
      
 155 
     | 
    
         
            +
              unless Dir['VERSION*'].empty?
         
     | 
| 
      
 156 
     | 
    
         
            +
                puts "A `VERSION` file at root level violates Gem best practices."
         
     | 
| 
      
 157 
     | 
    
         
            +
                exit!
         
     | 
| 
      
 158 
     | 
    
         
            +
              end
         
     | 
| 
      
 159 
     | 
    
         
            +
            end
         
     | 
    
        data/bin/cutting_edge
    ADDED
    
    | 
         @@ -0,0 +1,72 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require File.expand_path('../../lib/cutting_edge/app.rb', __FILE__)
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rufus-scheduler'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            config = <<YAML
         
     | 
| 
      
 8 
     | 
    
         
            +
            github:
         
     | 
| 
      
 9 
     | 
    
         
            +
              gollum:
         
     | 
| 
      
 10 
     | 
    
         
            +
                gollum:
         
     | 
| 
      
 11 
     | 
    
         
            +
                  api_token: secret
         
     | 
| 
      
 12 
     | 
    
         
            +
                gollum-lib:
         
     | 
| 
      
 13 
     | 
    
         
            +
                  api_token: secret
         
     | 
| 
      
 14 
     | 
    
         
            +
                  locations: [gemspec.rb]
         
     | 
| 
      
 15 
     | 
    
         
            +
                  dependency_types: [runtime, development]
         
     | 
| 
      
 16 
     | 
    
         
            +
              singingwolfboy:
         
     | 
| 
      
 17 
     | 
    
         
            +
                flask-dance:
         
     | 
| 
      
 18 
     | 
    
         
            +
                  language: python
         
     | 
| 
      
 19 
     | 
    
         
            +
              rust-lang:
         
     | 
| 
      
 20 
     | 
    
         
            +
                crates.io:
         
     | 
| 
      
 21 
     | 
    
         
            +
                  language: rust
         
     | 
| 
      
 22 
     | 
    
         
            +
                  api_token: secret
         
     | 
| 
      
 23 
     | 
    
         
            +
            gitlab:
         
     | 
| 
      
 24 
     | 
    
         
            +
              cthowl01:
         
     | 
| 
      
 25 
     | 
    
         
            +
                team-chess-ruby:
         
     | 
| 
      
 26 
     | 
    
         
            +
                  api_token: secret
         
     | 
| 
      
 27 
     | 
    
         
            +
            YAML
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            options = {
         
     | 
| 
      
 30 
     | 
    
         
            +
              :port => 4567,
         
     | 
| 
      
 31 
     | 
    
         
            +
              :bind => '0.0.0.0',
         
     | 
| 
      
 32 
     | 
    
         
            +
            }
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            store = Moneta.new(:Memory)
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            repositories = {}
         
     | 
| 
      
 37 
     | 
    
         
            +
            YAML.load(config).each do |source, orgs|
         
     | 
| 
      
 38 
     | 
    
         
            +
              orgs.each do |org, value|
         
     | 
| 
      
 39 
     | 
    
         
            +
                value.each do |name, settings|
         
     | 
| 
      
 40 
     | 
    
         
            +
                  cfg = settings.is_a?(Hash) ? settings : {}
         
     | 
| 
      
 41 
     | 
    
         
            +
                  repo = Object.const_get("CuttingEdge::#{source.capitalize}Repository").new(org, name, cfg.fetch('language', nil), cfg.fetch('locations', nil), cfg.fetch('branch', nil), cfg.fetch('api_token', nil))
         
     | 
| 
      
 42 
     | 
    
         
            +
                  repo.dependency_types = cfg['dependency_types'].map {|dep| dep.to_sym} if cfg['dependency_types'].is_a?(Array)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  repositories["#{source}/#{org}/#{name}"] = repo
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            # Need to initialize the log like this once, because otherwise it only becomes available after the Sinatra app has received a request...
         
     | 
| 
      
 49 
     | 
    
         
            +
            ::SemanticLogger.add_appender(file_name: "#{CuttingEdge::App.environment}.log")
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            CuttingEdge::App.set(:repositories, repositories)
         
     | 
| 
      
 52 
     | 
    
         
            +
            CuttingEdge::App.set(:store, store)
         
     | 
| 
      
 53 
     | 
    
         
            +
            CuttingEdge::App.set(:enable_logging, true)
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            puts "Scheduling Jobs..."
         
     | 
| 
      
 56 
     | 
    
         
            +
            scheduler = Rufus::Scheduler.new
         
     | 
| 
      
 57 
     | 
    
         
            +
            scheduler.every('1h') do
         
     | 
| 
      
 58 
     | 
    
         
            +
              worker_fetch_all(repositories.values)
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
      
 60 
     | 
    
         
            +
            scheduler.every('1h5m') do
         
     | 
| 
      
 61 
     | 
    
         
            +
              worker_all_badges(repositories.values)
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            puts "Running Workers a first time..."
         
     | 
| 
      
 65 
     | 
    
         
            +
            include CuttingEdgeHelpers
         
     | 
| 
      
 66 
     | 
    
         
            +
            worker_fetch_all(repositories.values)
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            sleep 5
         
     | 
| 
      
 69 
     | 
    
         
            +
            worker_all_badges(repositories.values)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            puts "Starting Sinatra..."
         
     | 
| 
      
 72 
     | 
    
         
            +
            CuttingEdge::App.run!(options)
         
     | 
| 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 2 
     | 
    
         
            +
              s.specification_version = 2 if s.respond_to? :specification_version=
         
     | 
| 
      
 3 
     | 
    
         
            +
              s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
         
     | 
| 
      
 4 
     | 
    
         
            +
              s.rubygems_version = '1.3.5'
         
     | 
| 
      
 5 
     | 
    
         
            +
              s.required_ruby_version = '>= 2.4'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              s.name              = 'cutting_edge'
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.version           = '0.0.1'
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.date              = '2020-02-19'
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.license           = 'GPL-3.0-only'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              s.summary     = 'Self-hosted dependency monitoring, including shiny badges.'
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.description = 'Self-hosted dependency monitoring, including shiny badges.'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              s.authors  = ['Dawa Ometto', 'Bart Kamphorst']
         
     | 
| 
      
 16 
     | 
    
         
            +
              s.email    = 'd.ometto@gmail.com'
         
     | 
| 
      
 17 
     | 
    
         
            +
              s.homepage = 'http://github.com/repotag/cutting_edge'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              s.require_paths = %w[lib]
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              s.executables = ['cutting_edge']
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_dependency 'gemnasium-parser', '~> 0.1.9'
         
     | 
| 
      
 24 
     | 
    
         
            +
              s.add_dependency 'http', '~> 4.3'
         
     | 
| 
      
 25 
     | 
    
         
            +
              s.add_dependency 'sucker_punch', '~> 2.1'
         
     | 
| 
      
 26 
     | 
    
         
            +
              s.add_dependency 'sinatra', '~> 2.0'
         
     | 
| 
      
 27 
     | 
    
         
            +
              s.add_dependency 'moneta', '~> 1.2'
         
     | 
| 
      
 28 
     | 
    
         
            +
              s.add_dependency 'victor', '~> 0.2.8'
         
     | 
| 
      
 29 
     | 
    
         
            +
              s.add_dependency 'rufus-scheduler', '~> 3.6'
         
     | 
| 
      
 30 
     | 
    
         
            +
              s.add_dependency 'sinatra-logger', '~> 0.3'
         
     | 
| 
      
 31 
     | 
    
         
            +
              s.add_dependency 'toml-rb', '~> 2.0'
         
     | 
| 
      
 32 
     | 
    
         
            +
              # = MANIFEST =
         
     | 
| 
      
 33 
     | 
    
         
            +
              s.files = %w[
         
     | 
| 
      
 34 
     | 
    
         
            +
                Gemfile
         
     | 
| 
      
 35 
     | 
    
         
            +
                LICENSE
         
     | 
| 
      
 36 
     | 
    
         
            +
                README.md
         
     | 
| 
      
 37 
     | 
    
         
            +
                Rakefile
         
     | 
| 
      
 38 
     | 
    
         
            +
                bin/cutting_edge
         
     | 
| 
      
 39 
     | 
    
         
            +
                cutting_edge.gemspec
         
     | 
| 
      
 40 
     | 
    
         
            +
                lib/cutting_edge.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
                lib/cutting_edge/app.rb
         
     | 
| 
      
 42 
     | 
    
         
            +
                lib/cutting_edge/badge.rb
         
     | 
| 
      
 43 
     | 
    
         
            +
                lib/cutting_edge/langs.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
                lib/cutting_edge/langs/python.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
                lib/cutting_edge/langs/ruby.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
                lib/cutting_edge/langs/rust.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
                lib/cutting_edge/repo.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
                lib/cutting_edge/versions.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
                lib/cutting_edge/workers/badge.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
                lib/cutting_edge/workers/dependency.rb
         
     | 
| 
      
 51 
     | 
    
         
            +
                lib/cutting_edge/workers/helpers.rb
         
     | 
| 
      
 52 
     | 
    
         
            +
                spec/langs/python_spec.rb
         
     | 
| 
      
 53 
     | 
    
         
            +
                spec/langs/rust_spec.rb
         
     | 
| 
      
 54 
     | 
    
         
            +
                spec/spec_helper.rb
         
     | 
| 
      
 55 
     | 
    
         
            +
              ]
         
     | 
| 
      
 56 
     | 
    
         
            +
              # = MANIFEST =
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/cutting_edge.rb
    ADDED
    
    
| 
         @@ -0,0 +1,77 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'sucker_punch'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'sinatra'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'sinatra/logger'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'moneta'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            require File.expand_path('../../cutting_edge.rb', __FILE__)
         
     | 
| 
      
 9 
     | 
    
         
            +
            require File.expand_path('../repo.rb', __FILE__)
         
     | 
| 
      
 10 
     | 
    
         
            +
            require File.expand_path('../workers/dependency.rb', __FILE__)
         
     | 
| 
      
 11 
     | 
    
         
            +
            require File.expand_path('../workers/badge.rb', __FILE__)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            module CuttingEdgeHelpers
         
     | 
| 
      
 14 
     | 
    
         
            +
              def worker_all_badges(repositories)
         
     | 
| 
      
 15 
     | 
    
         
            +
                repositories.each do |repo|
         
     | 
| 
      
 16 
     | 
    
         
            +
                  worker_generate_badge(repo)
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def worker_generate_badge(repo)
         
     | 
| 
      
 21 
     | 
    
         
            +
                BadgeWorker.perform_async(repo.identifier)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              def worker_fetch_all(repositories)
         
     | 
| 
      
 25 
     | 
    
         
            +
                repositories.each do |repo|
         
     | 
| 
      
 26 
     | 
    
         
            +
                  worker_fetch(repo)
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def worker_fetch(repo)
         
     | 
| 
      
 31 
     | 
    
         
            +
                DependencyWorker.perform_async(repo.identifier, repo.lang, repo.locations, repo.dependency_types)
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            module CuttingEdge
         
     | 
| 
      
 37 
     | 
    
         
            +
               LAST_VERSION_TIMEOUT = 5
         
     | 
| 
      
 38 
     | 
    
         
            +
              
         
     | 
| 
      
 39 
     | 
    
         
            +
              class App < Sinatra::Base
         
     | 
| 
      
 40 
     | 
    
         
            +
                include CuttingEdgeHelpers
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                logger filename: "#{settings.environment}.log", level: :trace
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                before do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @store = settings.store
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                get %r{/(.+)/(.+)/(.+)/info} do |source, org, name|
         
     | 
| 
      
 49 
     | 
    
         
            +
                  repo_defined?(source, org, name)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  content_type :json
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @store[@repo.identifier].merge({:language => @repo.lang}).to_json # Todo: check whether value exists yet? If not, call worker / wait / timeout?
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                get %r{/(.+)/(.+)/(.+)/svg} do |source, org, name|
         
     | 
| 
      
 55 
     | 
    
         
            +
                  repo_defined?(source, org, name)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  content_type 'image/svg+xml'
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @store["svg-#{@repo.identifier}"]
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                post %r{/(.+)/(.+)/(.+)/refresh} do |source, org, name|
         
     | 
| 
      
 61 
     | 
    
         
            +
                  repo_defined?(source, org, name)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  if @repo.token && params[:token] == @repo.token
         
     | 
| 
      
 63 
     | 
    
         
            +
                    worker_fetch(@repo)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    status 200
         
     | 
| 
      
 65 
     | 
    
         
            +
                  else
         
     | 
| 
      
 66 
     | 
    
         
            +
                    status 401
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                private
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def repo_defined?(source, org, name)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  halt 404, '404 Not Found' unless @repo = settings.repositories["#{source}/#{org}/#{name}"]
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     |