Class: FPM::Package::Virtualenv

Inherits:
FPM::Package show all
Defined in:
lib/fpm/package/virtualenv.rb

Overview

Support for python virtualenv packages.

This supports input, but not output.

Instance Attribute Summary

Attributes inherited from FPM::Package

#architecture, #attributes, #attrs, #category, #config_files, #conflicts, #dependencies, #description, #directories, #epoch, #iteration, #license, #maintainer, #name, #provides, #replaces, #scripts, #url, #vendor, #version

Instance Method Summary collapse

Methods inherited from FPM::Package

apply_options, #build_path, #cleanup, #cleanup_build, #cleanup_staging, #convert, #converted_from, default_attributes, #edit_file, #files, inherited, #initialize, option, #output, #script, #staging_path, #to_s, #type, type, types

Methods included from Util

#copied_entries, #copy_entry, #copy_metadata, #default_shell, #execmd, #expand_pessimistic_constraints, #logger, #mknod_w, #program_exists?, #program_in_path?, #safesystem, #safesystemout, #tar_cmd

Constructor Details

This class inherits a constructor from FPM::Package

Instance Method Details

#input(package) ⇒ Object

Input a package.

`package` can look like `psutil==2.2.1` or `psutil`.


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
# File 'lib/fpm/package/virtualenv.rb', line 38

def input(package)
  installdir = attributes[:virtualenv_install_location]
  m = /^([^=]+)==([^=]+)$/.match(package)
  package_version = nil

  is_requirements_file = (File.basename(package) == "requirements.txt")

  if is_requirements_file
    if !File.file?(package)
      raise FPM::InvalidPackageConfiguration, "Path looks like a requirements.txt, but it doesn't exist: #{package}"
    end

    package = File.join(::Dir.pwd, package) if File.dirname(package) == "."
    package_name = File.basename(File.dirname(package))
    logger.info("No name given. Using the directory's name", :name => package_name)
    package_version = nil
  elsif m
    package_name = m[1]
    package_version = m[2]
    self.version ||= package_version
  else
    package_name = package
    package_version = nil
  end

  virtualenv_name = package_name

  self.name ||= package_name

  if self.attributes[:virtualenv_fix_name?]
    self.name = [self.attributes[:virtualenv_package_name_prefix],
                 self.name].join("-")
  end

  virtualenv_folder =
    File.join(installdir,
              virtualenv_name)

  virtualenv_build_folder = build_path(virtualenv_folder)

  ::FileUtils.mkdir_p(virtualenv_build_folder)

  safesystem("virtualenv", virtualenv_build_folder)
  pip_exe = File.join(virtualenv_build_folder, "bin", "pip")
  python_exe = File.join(virtualenv_build_folder, "bin", "python")

  # Why is this hack here? It looks important, so I'll keep it in.
  safesystem(pip_exe, "install", "-U", "-i",
             attributes[:virtualenv_pypi],
             "pip", "distribute")
  safesystem(pip_exe, "uninstall", "-y", "distribute")

  extra_index_url_args = []
  if attributes[:virtualenv_pypi_extra_index_urls]
    attributes[:virtualenv_pypi_extra_index_urls].each do |extra_url|
      extra_index_url_args << "--extra-index-url" << extra_url
    end
  end

  target_args = []
  if is_requirements_file
    target_args << "-r" << package
  else
    target_args << package
  end

  pip_args = [pip_exe, "install", "-i", attributes[:virtualenv_pypi]] << extra_index_url_args << target_args
  safesystem(*pip_args.flatten)

  if ! is_requirements_file && package_version.nil?
    frozen = safesystemout(pip_exe, "freeze")
    package_version = frozen[/#{package}==[^=]+$/].split("==")[1].chomp!
    self.version ||= package_version
  end

  ::Dir[build_path + "/**/*"].each do |f|
    if ! File.readable? f
      File.lchmod(File.stat(f).mode | 444)
    end
  end

  ::Dir.chdir(virtualenv_build_folder) do
    safesystem("virtualenv-tools", "--update-path", virtualenv_folder)
  end

  if !attributes[:virtualenv_other_files_dir].nil?
    # Copy all files from other dir to build_path
    Find.find(attributes[:virtualenv_other_files_dir]) do |path|
      src = path.gsub(/^#{attributes[:virtualenv_other_files_dir]}/, '')
      dst = File.join(build_path, src)
      copy_entry(path, dst, preserve=true, remove_destination=true)
      (path, dst)
    end
  end

  remove_python_compiled_files virtualenv_build_folder

  # use dir to set stuff up properly, mainly so I don't have to reimplement
  # the chdir/prefix stuff special for tar.
  dir = convert(FPM::Package::Dir)

  if attributes[:chdir]
    dir.attributes[:chdir] = File.join(build_path, attributes[:chdir])
  else
    dir.attributes[:chdir] = build_path
  end

  cleanup_staging
  # Tell 'dir' to input "." and chdir/prefix will help it figure out the
  # rest.
  dir.input(".")
  @staging_path = dir.staging_path
  dir.cleanup_build

end