File: box.rb

package info (click to toggle)
ruby-vagrant-cloud 3.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 408 kB
  • sloc: ruby: 4,343; makefile: 7
file content (146 lines) | stat: -rw-r--r-- 3,876 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
module VagrantCloud
  class Box < Data::Mutable
    autoload :Provider, "vagrant_cloud/box/provider"
    autoload :Version, "vagrant_cloud/box/version"

    attr_reader :organization
    attr_required :name
    attr_optional :created_at, :updated_at, :tag, :short_description,
      :description_html, :description_markdown, :private, :downloads,
      :current_version, :versions, :description, :username

    attr_mutable :short_description, :description, :private, :versions

    # Create a new instance
    #
    # @return [Box]
    def initialize(organization:, **opts)
      @organization = organization
      @versions_loaded = false
      opts[:username] = organization.username
      super(**opts)
      if opts[:versions] && !opts[:versions].empty?
        self.versions= Array(opts[:versions]).map do |version|
          Box::Version.load(box: self, **version)
        end
      end
      if opts[:current_version]
        clean(data: {current_version: Box::Version.
          load(box: self, **opts[:current_version])})
      end
      clean!
    end

    # Delete this box
    #
    # @return [nil]
    # @note This will delete the box, and all versions
    def delete
      if exist?
        organization.account.client.box_delete(
          username: username,
          name: name
        )
        b = organization.boxes.dup
        b.delete(self)
        organization.clean(data: {boxes: b})
      end
      nil
    end

    # Add a new version of this box
    #
    # @param [String] version Version number
    # @return [Version]
    def add_version(version)
      if versions.any? { |v| v.version == version }
        raise Error::BoxError::VersionExistsError,
          "Version #{version} already exists for box #{tag}"
      end
      v = Version.new(box: self, version: version)
      clean(data: {versions: versions + [v]})
      v
    end

    # Check if this instance is dirty
    #
    # @param [Boolean] deep Check nested instances
    # @return [Boolean] instance is dirty
    def dirty?(key=nil, deep: false)
      if key
        super(key)
      else
        d = super() || !exist?
        if deep && !d
          d = Array(plain_versions).any? { |v| v.dirty?(deep: true) }
        end
        d
      end
    end

    # @return [Boolean] box exists remotely
    def exist?
      !!created_at
    end

    # @return [Array<Version>]
    # @note This is used to allow versions information to be loaded
    # only when requested
    def versions_on_demand
      if !@versions_loaded
        if exist?
          r = self.organization.account.client.box_get(username: username, name: name)
          v = Array(r[:versions]).map do |version|
            Box::Version.load(box: self, **version)
          end
          clean(data: {versions: v + Array(plain_versions)})
        else
          clean(data: {versions: []})
        end
        @versions_loaded = true
      end
      plain_versions
    end
    alias_method :plain_versions, :versions
    alias_method :versions, :versions_on_demand

    # Save the box if any changes have been made
    #
    # @return [self]
    def save
      save_box if dirty?
      save_versions if dirty?(deep: true)
      self
    end

    protected

    # Save the box
    #
    # @return [self]
    def save_box
      req_args = {
        username: username,
        name: name,
        short_description: short_description,
        description: description,
        is_private: self.private
      }
      if exist?
        result = organization.account.client.box_update(**req_args)
      else
        result = organization.account.client.box_create(**req_args)
      end
      clean(data: result, ignores: [:current_version, :versions])
      self
    end

    # Save the versions if any require saving
    #
    # @return [self]
    def save_versions
      versions.map(&:save)
      self
    end
  end
end