File indexing completed on 2024-10-13 13:02:02
0001 require 'json' 0002 require 'tmpdir' 0003 require 'yaml' 0004 0005 class Source 0006 attr_reader :upstream_name 0007 attr_reader :upstream_version 0008 0009 def initialize(upstream_name) 0010 @upstream_name = upstream_name 0011 end 0012 0013 def all_qml_depends 0014 @all_qml_depends ||= controls.collect do |control| 0015 control.binaries.collect do |binary| 0016 next nil unless runtime_binaries.include?(binary['package']) 0017 deps = binary.fetch('depends', []) + binary.fetch('recommends', []) 0018 deps.collect do |dep| 0019 dep = [dep[0]] if dep.size > 1 0020 next nil unless dep[0].name.start_with?('qml-module') 0021 dep = dep.each { |y| y.architectures = nil; y.version = nil; y.operator = nil } 0022 # puts "---> #{dep} ---> #{dep[0].substvar?}" 0023 dep = dep.reject(&:substvar?) 0024 dep.collect(&:to_s) 0025 end.compact 0026 end.flatten 0027 end.flatten 0028 end 0029 0030 def dev_binaries 0031 dev_only(all_packages) 0032 end 0033 0034 def runtime_binaries 0035 runtime_only(all_packages) 0036 end 0037 0038 def all_build_depends 0039 @all_build_depends ||= controls.collect do |control| 0040 bdeps = control.source.fetch('build-depends', []) + 0041 control.source.fetch('build-depends-indep', []) 0042 bdeps.collect do |x| 0043 # TODO: this makes a bunch of assumptions as we have no proper 0044 # resolver for dependencies. in alternates the first always wins 0045 # architecture restrictions are entirely ignored 0046 x = [x[0]] if x.size > 1 0047 x = x.each { |y| y.architectures = nil; y.version = nil; y.operator = nil } 0048 x.collect(&:to_s) 0049 end.compact 0050 end.flatten 0051 end 0052 0053 private 0054 0055 def read_upstream_version(dir) 0056 version = `dpkg-parsechangelog -S version -l #{dir}/debian/changelog`.strip 0057 unless $?.success? 0058 warn 'Got error during dpkg-parsechangelog!' 0059 warn version 0060 return nil 0061 end 0062 version = version.split(':', 2)[-1] # ditch epoch 0063 version.split('-', 2)[0] # ditch rev 0064 end 0065 0066 def parse_control(src) 0067 system("apt-get --download-only source #{src}") || raise 0068 FileUtils.mkpath('source/') 0069 files = 'debian/control debian/changelog' 0070 system("tar -xvf *debian.tar.* -C source #{files}") || raise 0071 @upstream_version = read_upstream_version('source') 0072 require_relative 'debian/control' 0073 control = Debian::Control.new('source') 0074 control.parse! 0075 control 0076 end 0077 0078 def controls 0079 @controls ||= sources.collect do |src| 0080 Dir.mktmpdir do |tmpdir| 0081 Dir.chdir(tmpdir) do 0082 parse_control(src) 0083 end 0084 end 0085 end 0086 end 0087 0088 0089 def all_packages 0090 @all_packages ||= controls.collect do |control| 0091 control.binaries.collect { |x| x.fetch('package') } 0092 end.flatten 0093 end 0094 0095 def dev_only(packages) 0096 packages.select do |pkg| 0097 pkg.include?('-dev') && !(pkg == 'qt5-qmake-arm-linux-gnueabihf') 0098 end 0099 end 0100 0101 def runtime_only(packages) 0102 packages.delete_if do |pkg| 0103 pkg.include?('-dev') || pkg.include?('-doc') || pkg.include?('-dbg') || 0104 pkg.include?('-examples') || pkg == 'qt5-qmake-arm-linux-gnueabihf' 0105 end 0106 end 0107 0108 MAP = { 0109 'qt5' => %w(qtbase-opensource-src 0110 qtscript-opensource-src 0111 qtdeclarative-opensource-src 0112 qttools-opensource-src 0113 qtsvg-opensource-src 0114 qtx11extras-opensource-src), 0115 'kwallet' => %w(kwallet-kf5), 0116 'kdnssd' => [], 0117 'baloo' => %w(baloo-kf5), 0118 'kdoctools' => %w(kdoctools5), 0119 'kfilemetadata' => %w(kfilemetadata-kf5), 0120 'attica' => %w(attica-kf5), 0121 'kactivities' => %w(kactivities-kf5) 0122 }.freeze 0123 0124 def sources 0125 MAP.fetch(@upstream_name, [@upstream_name]) 0126 end 0127 end 0128 0129 class SnapcraftConfig 0130 module AttrRecorder 0131 def attr_accessor(*args) 0132 record_readable(*args) 0133 super 0134 end 0135 0136 def attr_reader(*args) 0137 record_readable(*args) 0138 super 0139 end 0140 0141 def record_readable(*args) 0142 @readable_attrs ||= [] 0143 @readable_attrs += args 0144 end 0145 0146 def readable_attrs 0147 @readable_attrs 0148 end 0149 end 0150 0151 module YamlAttributer 0152 def encode_with(c) 0153 c.tag = nil # Unset the tag to prevent clutter 0154 self.class.readable_attrs.each do |readable_attrs| 0155 next unless data = method(readable_attrs).call 0156 c[readable_attrs.to_s.tr('_', '-')] = data 0157 end 0158 super(c) if defined?(super) 0159 end 0160 end 0161 0162 class Part 0163 extend AttrRecorder 0164 prepend YamlAttributer 0165 0166 # Array<String> 0167 attr_accessor :after 0168 # String 0169 attr_accessor :plugin 0170 # Array<String> 0171 attr_accessor :build_packages 0172 # Array<String> 0173 attr_accessor :stage_packages 0174 # Hash 0175 attr_accessor :filesets 0176 # Array<String> 0177 attr_accessor :snap 0178 # Array<String> 0179 attr_accessor :stage 0180 # Hash<String, String> 0181 attr_accessor :organize 0182 0183 attr_writer :source 0184 attr_writer :configflags 0185 0186 def initialize 0187 @after = [] 0188 @plugin = 'nil' 0189 @build_packages = [] 0190 @stage_packages = [] 0191 @filesets = { 0192 'exclusion' => %w( 0193 -usr/lib/*/cmake/* 0194 -usr/lib/*/qt5/bin/moc 0195 -usr/lib/*/qt5/bin/qmake 0196 -usr/lib/*/qt5/bin/rcc 0197 -usr/lib/*/qt5/bin/*cpp* 0198 -usr/lib/qt5/bin/assistant 0199 -usr/lib/qt5/bin/designer 0200 -usr/lib/qt5/bin/lconvert 0201 -usr/lib/qt5/bin/linguist 0202 -usr/lib/qt5/bin/lupdate 0203 -usr/lib/qt5/bin/lrelease 0204 -usr/lib/qt5/bin/moc 0205 -usr/lib/qt5/bin/pixeltool 0206 -usr/lib/qt5/bin/qcollectiongenerator 0207 -usr/lib/qt5/bin/qdbuscpp2xml 0208 -usr/lib/qt5/bin/qdbusxml2cpp 0209 -usr/lib/qt5/bin/qdoc 0210 -usr/lib/qt5/bin/qhelpconverter 0211 -usr/lib/qt5/bin/qlalr 0212 -usr/lib/qt5/bin/qmake 0213 -usr/lib/qt5/bin/rcc 0214 -usr/lib/qt5/bin/syncqt.pl 0215 -usr/lib/vlc/plugins/gui/libqt4_plugin.so 0216 -usr/include/* 0217 -usr/share/ECM/* 0218 -usr/share/xml/docbook/* 0219 -usr/share/doc/* 0220 -usr/share/locale/*/LC_MESSAGES/vlc.mo 0221 -usr/share/man/* 0222 -usr/share/icons/breeze/*.rcc 0223 -usr/share/icons/breeze-dark/*.rcc 0224 -usr/share/wallpapers/* 0225 -usr/share/fonts/* 0226 -usr/share/pkgconfig 0227 -usr/lib/*/pkgconfig 0228 -usr/share/QtCurve 0229 -usr/share/kde4 0230 -usr/share/bug 0231 -usr/share/debhelper 0232 -usr/share/lintian 0233 -usr/share/menu 0234 -usr/bin/*vlc 0235 -usr/bin/dh_* 0236 -usr/lib/*/*.a 0237 -usr/lib/*/*.pri 0238 ) 0239 } 0240 @stage = %w[ 0241 -usr/share/doc/* 0242 -usr/share/man/* 0243 -usr/share/icons/breeze/*.rcc 0244 -usr/share/wallpapers/* 0245 -usr/share/fonts/* 0246 ] 0247 @snap = %w($exclusion) 0248 # @organize = { 0249 # 'etc/*' => 'slash/etc/', 0250 # 'usr/*' => 'slash/usr/' 0251 # } 0252 end 0253 0254 def encode_with(c) 0255 if @plugin != 'nil' 0256 c['configflags'] = @configflags 0257 c['source'] = @source 0258 end 0259 super if defined?(super) 0260 end 0261 end 0262 0263 class Slot 0264 extend AttrRecorder 0265 prepend YamlAttributer 0266 0267 attr_accessor :content 0268 attr_accessor :interface 0269 attr_accessor :read 0270 end 0271 0272 extend AttrRecorder 0273 prepend YamlAttributer 0274 0275 attr_accessor :name 0276 attr_accessor :version 0277 attr_accessor :summary 0278 attr_accessor :description 0279 attr_accessor :confinement 0280 attr_accessor :grade 0281 attr_accessor :slots 0282 attr_accessor :parts 0283 0284 def initialize 0285 @parts = {} 0286 @slots = {} 0287 end 0288 end 0289 0290 config = SnapcraftConfig.new 0291 config.name = 'kde-frameworks-5' 0292 config.version = 'unknown' 0293 config.summary = 'KDE Frameworks 5' 0294 config.description = 'KDE Frameworks are addons and useful extensions to Qt' 0295 config.confinement = 'strict' 0296 config.grade = 'stable' 0297 0298 slot = SnapcraftConfig::Slot.new 0299 slot.content = 'kde-frameworks-5-all' 0300 slot.interface = 'content' 0301 slot.read = %w[.] 0302 config.slots['kde-frameworks-5-slot'] = slot 0303 0304 # These are only old versions! The new version is created later after we know 0305 # the current versions of the content. 0306 content_versions = JSON.parse(File.read('versions.json')).uniq 0307 content_versions.each do |content_version| 0308 slot = SnapcraftConfig::Slot.new 0309 slot.content = content_version 0310 slot.interface = 'content' 0311 slot.read = %w[.] 0312 config.slots[content_version] = slot 0313 end 0314 0315 # This list is generated by resolving and sorting the dep tree from 0316 # kde-build-metadata. Commented out bits we don't presently want to build. 0317 parts = %w(extra-cmake-modules kcoreaddons) + # kdesupport/polkit-qt-1 0318 %w(kauth kconfig kwidgetsaddons kcompletion 0319 kwindowsystem kcrash karchive ki18n kfilemetadata 0320 kjobwidgets kpty kunitconversion kcodecs) + # kdesupport/phonon/phonon 0321 %w(knotifications kpackage kguiaddons kconfigwidgets kitemviews 0322 kiconthemes attica kdbusaddons kservice kglobalaccel sonnet 0323 ktextwidgets breeze-icons kxmlgui kbookmarks solid kwallet kio 0324 kdeclarative kcmutils kplotting kparts kdewebkit 0325 kemoticons knewstuff kinit knotifyconfig kded 0326 kdesu ktexteditor kactivities kactivities-stats 0327 kdnssd kidletime kitemmodels threadweaver 0328 plasma-framework kxmlrpcclient kpeople frameworkintegration 0329 kdoctools 0330 kdesignerplugin 0331 krunner kwayland baloo) 0332 # plasma-integration) # extra integration pulls in breeze pulls in kde4/qt4 0333 parts += %w(qtwebkit qtbase qtdeclarative qtgraphicaleffects qtlocation 0334 qtmultimedia qtquickcontrols qtquickcontrols2 qtscript qtsensors qtserialport 0335 qtsvg qttools qttranslations qtvirtualkeyboard qtwayland qtwebchannel 0336 qtwebengine qtwebsockets qtx11extras qtxmlpatterns).collect { |x| x += '-opensource-src' } 0337 # 0338 # oxygen-icons5 only one icon set 0339 # Not Runtime Relevant! FIXME: need to seperate these out to only end up in -dev but not content! 0340 # extra-cmake-modules 0341 # kdesignerplugin 0342 # kdoctools 0343 # No Porting Aids! 0344 # kdelibs4support 0345 # khtml 0346 # kjs 0347 # kjsembed 0348 # kmediaplayer 0349 # kross 0350 0351 # padding 0352 parts = [nil] + parts 0353 # parts += [nil] 0354 0355 devs = [] 0356 # mesa-utils-extra - es2_info useful to debug GL problems. 0357 runs = %w[mesa-utils-extra] 0358 # GStreamer plugins 0359 runs += %w[gstreamer1.0-fluendo-mp3 gstreamer1.0-x gstreamer1.0-plugins-base 0360 gstreamer1.0-pulseaudio gstreamer1.0-plugins-good] 0361 # For on-demand locale generation we need the raw data to generate locales from. 0362 runs += %w[locales libc-bin] 0363 0364 kf5_version = nil 0365 qt5_version = nil 0366 0367 parts.each_cons(2) do |first_name, second_name| 0368 # puts "#{second_name} AFTER #{first_name}" 0369 next unless second_name # first item is nil 0370 source = Source.new(second_name) 0371 devs += source.dev_binaries 0372 runs += source.runtime_binaries 0373 if source.upstream_name == 'extra-cmake-modules' && config.version 0374 kf5_version = source.upstream_version 0375 config.version = source.upstream_version 0376 end 0377 if source.upstream_name == 'qtbase-opensource-src' 0378 qt5_version = source.upstream_version 0379 end 0380 end 0381 0382 # Construct a new interface name with up to date versions. 0383 # This is the only way we can version a content snap. 0384 kf5_version = 'kde-frameworks-' + kf5_version.split('.')[0..1].join('-') 0385 qt5_version = 'qt-' + qt5_version.split('.')[0..1].join('-') 0386 platform_version = 'ubuntu-1604' 0387 0388 latest_version = [kf5_version, qt5_version, platform_version].join('-') 0389 # Dump the latest interface. The application builds will pick this up and 0390 # set it as their content provider, this way we should be able to prevent 0391 # Qt version mismatches. 0392 File.write('content.json', 0393 JSON.generate(latest_version)) 0394 unless config.slots.include?(latest_version) 0395 slot = SnapcraftConfig::Slot.new 0396 slot.content = latest_version 0397 slot.interface = 'content' 0398 slot.read = %w[.] 0399 config.slots[latest_version] = slot 0400 0401 content_versions << latest_version 0402 File.write('versions.json', JSON.generate(content_versions.uniq)) 0403 end 0404 0405 # Do not pull in the GTK stack. 0406 runs.delete('qt5-gtk-platformtheme') 0407 devs.delete('qt5-gtk-platformtheme') 0408 0409 part = SnapcraftConfig::Part.new 0410 part.stage_packages = runs.flatten 0411 config.parts['kf5'] = part 0412 0413 dev = SnapcraftConfig::Part.new 0414 dev.stage_packages = devs.flatten 0415 dev.stage = (dev.stage + %w[ 0416 -usr/share/emoticons 0417 -usr/share/icons/* 0418 -usr/share/locale/*/LC_*/* 0419 -usr/share/qt5/translations/* 0420 -usr/lib/*/dri/* 0421 ]).uniq 0422 dev.snap = ['-*'] 0423 dev.after = %w(kf5) 0424 config.parts['kf5-dev'] = dev 0425 0426 breeze = SnapcraftConfig::Part.new 0427 breeze.after = %w(kf5-dev) 0428 breeze.build_packages = %w( 0429 pkg-config 0430 libx11-dev 0431 extra-cmake-modules 0432 qtbase5-dev 0433 libkf5config-dev 0434 libkf5configwidgets-dev 0435 libkf5windowsystem-dev 0436 libkf5i18n-dev 0437 libkf5coreaddons-dev 0438 libkf5guiaddons-dev 0439 libqt5x11extras5-dev 0440 libkf5style-dev 0441 libkf5kcmutils-dev 0442 kwayland-dev 0443 libkf5package-dev 0444 ) 0445 breeze.configflags = %w( 0446 -DKDE_INSTALL_USE_QT_SYS_PATHS=ON 0447 -DCMAKE_INSTALL_PREFIX=/usr 0448 -DCMAKE_BUILD_TYPE=Release 0449 -DENABLE_TESTING=OFF 0450 -DBUILD_TESTING=OFF 0451 -DKDE_SKIP_TEST_SETTINGS=ON 0452 -DWITH_DECORATIONS=OFF 0453 ) 0454 breeze.plugin = 'cmake' 0455 breeze.source = 'http://download.kde.org/stable/plasma/5.10.5/breeze-5.10.5.tar.xz' 0456 config.parts['breeze'] = breeze 0457 0458 integration = SnapcraftConfig::Part.new 0459 integration.after = %w(kf5-dev breeze) 0460 integration.build_packages = %w( 0461 extra-cmake-modules 0462 kio-dev 0463 kwayland-dev 0464 libkf5config-dev 0465 libkf5configwidgets-dev 0466 libkf5i18n-dev 0467 libkf5iconthemes-dev 0468 libkf5notifications-dev 0469 libkf5widgetsaddons-dev 0470 libqt5x11extras5-dev 0471 libxcursor-dev 0472 qtbase5-dev 0473 qtbase5-private-dev 0474 ) 0475 integration.configflags = %w( 0476 -DKDE_INSTALL_USE_QT_SYS_PATHS=ON 0477 -DCMAKE_INSTALL_PREFIX=/usr 0478 -DCMAKE_BUILD_TYPE=Release 0479 -DENABLE_TESTING=OFF 0480 -DBUILD_TESTING=OFF 0481 -DKDE_SKIP_TEST_SETTINGS=ON 0482 ) 0483 integration.plugin = 'cmake' 0484 integration.source = 'http://download.kde.org/stable/plasma/5.10.5/plasma-integration-5.10.5.tar.xz' 0485 config.parts['plasma-integration'] = integration 0486 0487 puts File.write('snapcraft.yaml', YAML.dump(config, indentation: 4)) 0488 puts File.write('stage-content.json', JSON.generate(runs)) 0489 puts File.write('stage-dev.json', JSON.generate(runs + devs))