package_cloud 0.0.3 → 0.1.0

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.
data/lib/package_cloud.rb CHANGED
@@ -8,4 +8,5 @@ module PackageCloud
8
8
  autoload :ConfigFile, "package_cloud/config_file"
9
9
  autoload :Object, "package_cloud/object"
10
10
  autoload :Repository, "package_cloud/repository"
11
+ autoload :Validator, "package_cloud/validator"
11
12
  end
@@ -3,20 +3,103 @@ require "thor"
3
3
 
4
4
  module PackageCloud
5
5
  class CLI < Thor
6
- option "config"
7
- option "url"
8
- desc "push user/repo /path/to/package",
9
- "push package to repository"
6
+ class_option "config"
7
+ class_option "url"
8
+
9
+ desc "list_distros package_type",
10
+ "list available distros and versions for package_type"
11
+ def list_distros(package_type)
12
+ distros = client.distributions[package_type]
13
+ if distros
14
+ puts "Listing distributions for #{package_type}:"
15
+ distros.each do |distro|
16
+ puts "\n #{distro["display_name"]} (#{distro["index_name"]}):\n\n"
17
+ distro["versions"].each do |ver|
18
+ puts " #{ver["display_name"]} (#{ver["index_name"]})"
19
+ end
20
+ end
21
+
22
+ puts "\nIf you don't see your distribution or version here, email us at support@packagecloud.io."
23
+ else
24
+ puts "No distributions exist for #{package_type}.".red
25
+ puts "That either means that we don't support #{package_type} or that it doesn't require a distribution/version."
26
+ exit(1)
27
+ end
28
+ end
29
+
30
+ desc "push user/repo[/distro/version] /path/to/package",
31
+ "push package to repository (in distro/version if required)"
10
32
  def push(repo, package_file)
11
- config = ConfigFile.new(options[:config] || "~/.packagecloud",
12
- options[:url] || "packagecloud.io")
33
+ ARGV.clear # otherwise gets explodes
34
+
35
+ validator = Validator.new(client)
36
+ dist_id = validator.distribution_id(repo, package_file)
37
+
38
+ # strip os/dist
39
+ repo = repo.split("/")[0..1].join("/")
40
+
41
+ print "Looking for repository at #{repo}... "
42
+ repo = client.repository(repo)
43
+ print "success!\n"
44
+ print "Pushing #{package_file}... "
45
+ repo.create_package(package_file, dist_id)
46
+ end
47
+
48
+ option :private
49
+ desc "create repo_name",
50
+ "create repository called repo_name"
51
+ def create(repo_name)
13
52
  config.read_or_create
14
53
  client = Client.new(config)
15
- print "Trying to find a repository at #{repo}... "
54
+
55
+ print "Looking for repository at #{repo_name}... "
56
+ repo = client.create_repo(repo_name, options[:private])
57
+ print "success!\n".green
58
+ puts "Your repository has been created at:"
59
+ puts " #{repo["url"]}"
60
+ end
61
+
62
+ desc "list",
63
+ "list your repositories"
64
+ def list
65
+ repos = client.repositories
66
+ if repos.length == 0
67
+ puts "You have no repositories at the moment. Create one!"
68
+ else
69
+ puts "Your repositories:"
70
+ puts ""
71
+ repos.each_with_index do |repo, i|
72
+ puts " #{repo.fqname} (#{repo.private_human})"
73
+ puts " last push: #{repo.last_push_human} | packages: #{repo.package_count_human}"
74
+ puts "" unless i == repos.length - 1
75
+ end
76
+ end
77
+ end
78
+
79
+ desc "install user/repo package_type",
80
+ "install user/repo for package_type"
81
+ def install(repo, package_type)
82
+ if Process.uid != 0 && package_type != "gem"
83
+ abort("You have to run install as root.".red)
84
+ end
85
+
86
+ print "Locating repository at #{repo}... "
16
87
  repo = client.repository(repo)
17
88
  print "success!\n"
18
- print "Pushing package #{package_file}... "
19
- repo.create_package(package_file)
89
+ pid = fork { exec(repo.install_script(package_type)) }
90
+ Process.waitpid(pid)
20
91
  end
92
+
93
+ private
94
+ def config
95
+ @config ||= begin
96
+ ConfigFile.new(options[:config] || "~/.packagecloud",
97
+ options[:url] || "packagecloud.io").tap(&:read_or_create)
98
+ end
99
+ end
100
+
101
+ def client
102
+ @client ||= Client.new(config)
103
+ end
21
104
  end
22
105
  end
@@ -7,6 +7,17 @@ module PackageCloud
7
7
  @config = config
8
8
  end
9
9
 
10
+ def repositories
11
+ base_url = @config.base_url
12
+ begin
13
+ attrs = JSON.parse(RestClient.get("#{base_url}/repositories.json"))
14
+ attrs.map { |a| Repository.new(a, @config) }
15
+ rescue RestClient::ResourceNotFound => e
16
+ print "failed!\n".red
17
+ exit(127)
18
+ end
19
+ end
20
+
10
21
  def repository(name)
11
22
  base_url = @config.base_url
12
23
  user, repo = name.split("/")
@@ -18,5 +29,30 @@ module PackageCloud
18
29
  exit(127)
19
30
  end
20
31
  end
32
+
33
+ def create_repo(name, priv)
34
+ base_url = @config.base_url
35
+ begin
36
+ JSON.parse(RestClient.post("#{base_url}/repositories.json", repository: {name: name, private: priv == "private" ? "1" : "0"}))
37
+ rescue RestClient::UnprocessableEntity => e
38
+ print "error!\n".red
39
+ json = JSON.parse(e.response)
40
+ json.each do |k,v|
41
+ puts "\n\t#{k}: #{v.join(", ")}\n"
42
+ end
43
+ puts ""
44
+ exit(1)
45
+ end
46
+ end
47
+
48
+ def distributions
49
+ base_url = @config.base_url
50
+ begin
51
+ JSON.parse(RestClient.get("#{base_url}/distributions.json"))
52
+ rescue RestClient::ResourceNotFound => e
53
+ print "failed!\n".red
54
+ exit(127)
55
+ end
56
+ end
21
57
  end
22
58
  end
@@ -28,7 +28,7 @@ module PackageCloud
28
28
  end
29
29
 
30
30
  def base_url(username = token, password = "")
31
- "https://#{CGI.escape(username)}:#{CGI.escape(password)}@#{url}"
31
+ "http://#{CGI.escape(username)}:#{CGI.escape(password)}@#{url}"
32
32
  end
33
33
 
34
34
  private
@@ -5,12 +5,13 @@ module PackageCloud
5
5
  @config = config
6
6
  end
7
7
 
8
- def create_package(file_path)
8
+ def create_package(file_path, dist_id)
9
9
  file_data = File.new(file_path, 'rb')
10
10
  base_url = @config.base_url
11
11
  url = base_url + paths["create_package"]
12
12
  begin
13
- RestClient.post(url, package: {package_file: file_data})
13
+ RestClient.post(url, package: {package_file: file_data,
14
+ distro_version_id: dist_id})
14
15
  print "success!\n".green
15
16
  rescue RestClient::UnprocessableEntity => e
16
17
  print "error:\n".red
@@ -22,5 +23,14 @@ module PackageCloud
22
23
  exit(1)
23
24
  end
24
25
  end
26
+
27
+ def install_script(type)
28
+ url = paths["install_script"].gsub(/:package_type/, type)
29
+ RestClient.get(url)
30
+ end
31
+
32
+ def private_human
33
+ send(:private) ? "private".red : "public".green
34
+ end
25
35
  end
26
36
  end
@@ -0,0 +1,96 @@
1
+ module PackageCloud
2
+ class Validator
3
+ def initialize(client)
4
+ @client = client
5
+ end
6
+
7
+ def distribution_id(repo, filename)
8
+ package_type = filename.split(".").last
9
+
10
+ if distributions[package_type]
11
+ _,_,dist_sel,ver_sel = repo.split("/")
12
+
13
+ if dist_sel && ver_sel
14
+ dist = distributions[package_type].detect { |d| d["index_name"] == dist_sel }
15
+
16
+ if dist
17
+ ver = dist["versions"].detect { |v| v["index_name"] == ver_sel }
18
+
19
+ if ver
20
+ ver["id"]
21
+ else
22
+ puts "#{ver_sel} isn't a valid version of #{dist["display_name"]}\n\n"
23
+ select_dist(repo, filename, package_type)
24
+ end
25
+ else
26
+ puts "#{dist_sel} isn't a valid operating system.\n\n"
27
+ select_dist(repo, filename, package_type)
28
+ end
29
+ else
30
+ puts "#{package_type} packages require an operating system and version to be selected.\n\n"
31
+ select_dist(repo, filename, package_type)
32
+ end
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ private
39
+ def distributions
40
+ @distributions ||= @client.distributions
41
+ end
42
+
43
+ def select_from(list)
44
+ selection = get_valid("0-#{list.length - 1}") do |s|
45
+ s =~ /^\d+$/ && list[s.to_i]
46
+ end
47
+
48
+ list[selection.to_i]
49
+ end
50
+
51
+ def get_valid(prompt)
52
+ selection = ""
53
+ times = 0
54
+ until yield(selection)
55
+ if times > 0
56
+ puts "#{selection} is not a valid selection."
57
+ end
58
+ print "\n #{prompt}: "
59
+ selection = ::Kernel.gets.chomp
60
+ times += 1
61
+ end
62
+
63
+ selection
64
+ end
65
+
66
+ def select_dist(repo, filename, package_type)
67
+ puts "If you don't see your OS or version here, send us an email at support@packagecloud.io:\n\n"
68
+ distros = distributions[package_type]
69
+ distros.each_with_index do |dist, index|
70
+ puts "\t#{index}. #{dist["display_name"]}"
71
+ end
72
+
73
+ distro = select_from(distros)
74
+
75
+ puts "\nYou selected #{distro["display_name"]}. Select a version:\n\n"
76
+ distro["versions"].each_with_index do |ver, index|
77
+ puts "\t#{index}. #{ver["display_name"]} (#{ver["index_name"]})"
78
+ end
79
+ version = select_from(distro["versions"])
80
+
81
+ repo = repo.split("/")[0..1].join("/")
82
+ os_shortcut = "#{distro["index_name"]}/#{version["index_name"]}"
83
+ shortcut = "#{repo}/#{os_shortcut}"
84
+ puts "\nPush #{filename} to #{shortcut}? "
85
+ answer = get_valid("(y/n)") { |sel| sel == "y" || sel == "n" }
86
+
87
+ if answer == "y"
88
+ print "\nContinuing...".green
89
+ puts " Note that next time you can push directly to #{os_shortcut} by specifying #{shortcut} on the commandline."
90
+ version["id"]
91
+ else
92
+ abort("Cancelled.")
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,3 +1,3 @@
1
1
  module PackageCloud
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: package_cloud
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.3
5
+ version: 0.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - James Golick
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2014-01-15 00:00:00 Z
13
+ date: 2014-02-24 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: thor
@@ -112,6 +112,7 @@ files:
112
112
  - lib/package_cloud/config_file.rb
113
113
  - lib/package_cloud/object.rb
114
114
  - lib/package_cloud/repository.rb
115
+ - lib/package_cloud/validator.rb
115
116
  - lib/package_cloud/version.rb
116
117
  - package_cloud.gemspec
117
118
  homepage: https://packagecloud.io
@@ -143,3 +144,4 @@ specification_version: 3
143
144
  summary: https://packagecloud.io
144
145
  test_files: []
145
146
 
147
+ has_rdoc: