<commit_before>module Statistrano
  module Deployment

    #
    # Manifest keeps track of the state of releases for a deployment
    # and handles updating the manifest file on the remote
    #
    class Manifest

      attr_reader :releases

      def initialize config, ssh_session
        @config = config
        @ssh = ssh_session
        @path = @config.remote_dir
        @releases = get.sort_by { |r| r.time }.reverse
      end

      # array of release names
      # @return [Array]
      def list
        get.map do |r|
          r.name
        end
      end

      # add a release to the manifest
      # @param release [Release]
      # @return [Void]
      def add_release release

        # remove releases with the same name
        @releases.keep_if do |r|
          r.name != release.name
        end

        @releases << release
        update
      end

      # remove a release to the manifest
      # @param name [String]
      # @return [Void]
      def remove_release name
        @releases.keep_if do |r|
          r.name != name
        end
        update
      end

      # update the manifest on the server
      # @return [Void]
      def update
        cmd = "touch #{manifest_path} && echo '#{releases_as_json}' > #{manifest_path}"
        @ssh.run_command(cmd)
      end

      class Release

        attr_reader :name
        attr_reader :time
        attr_reader :commit
        attr_reader :link

        # init a release
        # @param name [String] name of the release
        # @param hash [Hash] :time, :commit, & :link || :repo_url
        def initialize name, hash={}
          @name = name
          @time = (hash[:time]) ? hash[:time] : Time.now.to_i
          @commit = (hash[:commit]) ? hash[:commit] : Git.current_commit
          @link = (hash[:link]) ? hash[:link] : (hash[:repo_url]) ? hash[:repo_url] + '/tree/' + @commit : nil
        end

        # convert the release to a json object
        # @return [String]
        def to_json
          hash = {
            name: @name,
            time: @time,
            commit: @commit
          }

          if @link
            hash.merge({
              link: @link
            })
          end

          return hash.to_json
        end
      end

      private

        # get the manifest for this deployment
        # @return [Array]
        def get
          cmd = "touch #{manifest_path} && tail -n 1000 #{manifest_path}"
          manifest = []
          @ssh.run_command(cmd) do |ch, stream, data|
            manifest = JSON.parse(data).sort_by { |r| r["time"] }.reverse
          end
          releases = []
          if manifest.length > 0
            manifest.each do |r|

              options = {
                time: r["time"],
                commit: r["commit"]
              }

              if r["link"]
                options.merge({ link: r["link"] })
              elsif @config.repo_url
                options.merge({ repo_url: @config.repo_url })
              end

              releases << Release.new( r["name"], options )
            end
          end
          return releases
        end

        # path to the manifest
        # @return [String]
        def manifest_path
          File.join( @path, 'manifest.json' )
        end

        # json array of the releases
        # @return [String]
        def releases_as_json
          output = "["
          @releases.each_with_index do |r,idx|
            output << r.to_json
            unless idx == (@releases.length-1)
              output << ','<commit_msg>remove ambiguous variable names from manifest<commit_after>module Statistrano
  module Deployment

    #
    # Manifest keeps track of the state of releases for a deployment
    # and handles updating the manifest file on the remote
    #
    class Manifest

      attr_reader :releases

      def initialize config, ssh_session
        @config = config
        @ssh = ssh_session
        @path = @config.remote_dir
        @releases = get.sort_by { |release| release.time }.reverse
      end

      # array of release names
      # @return [Array]
      def list
        get.map do |release|
          release.name
        end
      end

      # add a release to the manifest
      # @param release [Release]
      # @return [Void]
      def add_release new_release

        # remove releases with the same name
        @releases.keep_if do |existing_release|
          existing_release.name != new_release.name
        end

        @releases << new_release
        update
      end

      # remove a release to the manifest
      # @param name [String]
      # @return [Void]
      def remove_release name
        @releases.keep_if do |existing_release|
          existing_release.name != name
        end
        update
      end

      # update the manifest on the server
      # @return [Void]
      def update
        cmd = "touch #{manifest_path} && echo '#{releases_as_json}' > #{manifest_path}"
        @ssh.run_command(cmd)
      end

      class Release

        attr_reader :name
        attr_reader :time
        attr_reader :commit
        attr_reader :link

        # init a release
        # @param name [String] name of the release
        # @param hash [Hash] :time, :commit, & :link || :repo_url
        def initialize name, hash={}
          @name = name
          @time = (hash[:time]) ? hash[:time] : Time.now.to_i
          @commit = (hash[:commit]) ? hash[:commit] : Git.current_commit
          @link = (hash[:link]) ? hash[:link] : (hash[:repo_url]) ? hash[:repo_url] + '/tree/' + @commit : nil
        end

        # convert the release to a json object
        # @return [String]
        def to_json
          hash = {
            name: @name,
            time: @time,
            commit: @commit
          }

          if @link
            hash.merge({
              link: @link
            })
          end

          return hash.to_json
        end
      end

      private

        # get the manifest for this deployment
        # @return [Array]
        def get
          cmd = "touch #{manifest_path} && tail -n 1000 #{manifest_path}"
          manifest = []
          @ssh.run_command(cmd) do |ch, stream, data|
            manifest = JSON.parse(data).sort_by { |release| release["time"] }.reverse
          end
          releases = []
          if manifest.length > 0
            manifest.each do |release|

              options = {
                time: release["time"],
                commit: release["commit"]
              }

              if release["link"]
                options.merge({ link: release["link"] })
              elsif @config.repo_url
                options.merge({ repo_url: @config.repo_url })
              end

              releases << Release.new( release["name"], options )
            end
          end
          return releases
        end

        # path to the manifest
        # @return [String]
        def manifest_path
          File.join( @path, 'manifest.json' )
        end

        # json array of the releases
        # @return [String]
        def releases_as_json
          output = "["
          @releases.each_with_index do |release,idx|
            output << release.to_json
            unless idx == (@releases.length-1)
              output << ','
{'fraction_non_alphanumeric': 0.09530348805273277, 'fraction_numerical': 0.0016478989288656962, 'mean_word_length': 1.5079201101928374, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '115564', 'n_tokens_mistral': 2043, 'n_tokens_neox': 1933, 'n_words': 603}